Compare commits

...
1203 Commits
Author SHA1 Message Date
Paul 64e0c91e73 Added category to Behaviours backend 2026-04-25 11:21:47 +10:00
Paul fd443785ad Added majority of functionality for premade NPCs 2026-04-20 09:43:00 +10:00
Paul 810ce8b759 Outline work for premade NPCs as a logical replacement for NPC presets 2026-04-18 11:35:40 +10:00
Paul aad115e43a Merge remote-tracking branch 'origin/main' into npc-upgrades
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/ai/OmniPathNavigation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2026-04-13 13:35:52 +10:00
Jackson Bowes 5e13da3e65 Merge branch 'graal-dev-runtime-fix' into 'main'
Graal dev runtime fix

See merge request cable-mc/cobblemon!2192
2026-04-04 16:12:04 -05:00
jackowes 03bc8a1b40 Add modRuntimeOnly for Graal in dev environment 2026-04-04 11:34:01 -05:00
Jackson Bowes 98eb43d13d Merge branch 'feature/flee-attempt' into 'main'
feature: add BattleFleeAttemptEvent and integrate flee attempt handling

See merge request cable-mc/cobblemon!2187
2026-04-02 16:49:57 -05:00
saul.tscandJackson Bowes ca839432aa feature: add BattleFleeAttemptEvent and integrate flee attempt handling 2026-04-02 16:49:57 -05:00
Hiroku 23f98f3a7d Merge branch 'gradle/JiJs' into 'main'
Move Graal and Mongo to JiJ

See merge request cable-mc/cobblemon!2181
2026-03-31 22:20:58 +00:00
Polymeta 5aeae2b350 Merge branch '1971-fix-recall-console-warning' into 'main'
Prevent calling `Entity.remove(DISCARDED)` if the entity is already being discarded

Closes #1971

See merge request cable-mc/cobblemon!2184
2026-03-25 21:24:58 +00:00
Charzard4261 b60fc26a97 Add change to CHANGELOG.md 2026-03-25 18:13:59 +00:00
Charzard4261 c1a95d0f3f Prevent calling Entity.remove(DISCARDED) if the entity is already being discarded 2026-03-25 17:21:12 +00:00
JazzMcNade 664c0c012c Converted PointToSpawn to BiggerBrains 2026-03-24 01:05:07 -05:00
Jackson Bowes 3fd04bcdb4 Merge branch 'feature/award-xp-to-fainted-pokemon' into 'main'
Add configurable XP distribution for fainted pokemon and battle losses

See merge request cable-mc/cobblemon!2183
2026-03-23 09:28:33 -05:00
JazzMcNade ed8c7569f9 Update FocusDuringBattle.kt 2026-03-21 18:55:36 -05:00
JazzMcNade e63a7c474f Migrate kick starting flight for flyers over water 2026-03-21 16:38:40 -05:00
Mr4Goosey a945bad5b5 Add changelog entry for fainted pokemon XP config options 2026-03-17 22:53:08 +01:00
Mr4Goosey edde3b16bf Add configurable XP distribution for fainted pokemon and battle losses
Currently, if a pokemon faints during battle, it receives no XP for any
opponents it helped defeat - that XP simply vanishes. This is especially
punishing in trainer battles where pokemon cycling is common.

This adds faint-order tracking so that pokemon who contributed to a kill
can still receive XP, as long as the opponent fainted before they did.
It also adds support for awarding XP on battle losses or forfeits for
opponents that were defeated during the battle.

Both behaviors are behind new config options (default off):
- awardExperienceToFaintedPokemon: fainted pokemon receive XP for
  opponents they helped defeat before fainting
- awardExperienceOnBattleLoss: pokemon receive XP for opponents
  defeated even if the battle is lost or forfeited
2026-03-17 22:31:58 +01:00
Nick ffaee877a7 Make sure we don't bundle everything + handle showdown init errors better 2026-03-14 19:54:10 -07:00
Nick 186f7dbbce Move Graal and Mongo to JiJ 2026-03-14 19:19:43 -07:00
Paul f5580fd83b Merge remote-tracking branch 'origin/bigger-brains' into bigger-brains 2026-03-14 11:40:10 +10:00
Paul a31b533b77 Rhyperior's grooving with better transitioning 2026-03-14 11:39:55 +10:00
Jackson Bowes 16165a2e68 Merge branch 'Fixes-#1977-and-#1959-gems-and-pokeballs' into 'main'
Fixes #1977 & #1959 gems and pokeballs

Closes #1977

See merge request cable-mc/cobblemon!2177
2026-03-13 20:34:07 -05:00
Cyrus cdec0e5640 small little # change 2026-03-13 17:47:02 -07:00
JazzMcNade 817ea0bff7 Added "canDance" species configuration option 2026-03-10 23:30:12 -05:00
Cyrus 87db8aadfe changed json for gems to be consumable and modifiers for the respectable pokeballs
edited changelog and added for json pvp battles
2026-03-10 13:25:45 -07:00
Cyrus 36921f439c changed json for gems to be consumable and modifiers for the respectable pokeballs 2026-03-10 13:12:43 -07:00
Paul 35977c0724 Rhyperior's grooving 2026-03-10 21:26:02 +10:00
JazzMcNade 7e08a46f28 Dancing Objective WIP 2026-03-10 01:41:32 -05:00
Polymeta f2d2ceb422 Merge branch 'patch-3' into 'main'
Fix incorrect spelling of "Pokémon" in some translation strings

See merge request cable-mc/cobblemon!2171
2026-03-08 21:35:45 +00:00
Micky 547ceae9ed Fix incorrect spelling of "Pokémon" in some places 2026-03-08 17:52:43 +00:00
JazzMcNade cc5d63fd11 Port JumpOutOfWaterTask to BiggerBrains 2026-03-08 01:56:47 -06:00
Polymeta a921d55812 fix campfirepot crash 2026-03-06 09:37:07 +00:00
Polymeta 79688ebdad Merge branch 'oh-hi-mark' into 'main'
Added `marks`, `has_mark`, & `remove_marks` as available Molang functions for pokemon

See merge request cable-mc/cobblemon!2173
2026-03-04 09:20:33 +00:00
Spicy 16d8c8bb19 Should be remove, not delete 2026-03-03 16:39:01 -06:00
Spicy e5738fecb0 Added marks, has_mark, & delete_marks as available Molang functions for pokemon 2026-03-03 16:33:44 -06:00
Jackson Bowes a46ac372a8 Merge branch 'showdown-species-name-fix' into 'main'
Fix to Showdown species names conflicting.

See merge request cable-mc/cobblemon!2170
2026-03-02 15:11:29 -06:00
Polymeta e6d2430405 Merge branch 'BWG-tag-updates' into 'main'
Fixes to BWG compat.

See merge request cable-mc/cobblemon!2172
2026-03-02 09:42:03 +00:00
JazzMcNade 065c5388a0 Fix Combee block jail break, more cleanup 2026-03-02 02:03:04 -06:00
JazzMcNade c20203a8e9 more clean up 2026-03-01 22:57:28 -06:00
JazzMcNade 932ebfa563 Clean up 2026-03-01 22:11:31 -06:00
JazzMcNade 0f57bd35de Comments 2026-03-01 22:05:45 -06:00
JazzMcNade d6974452fb Implemented Bee behavior with biggerbrain tech, allow fliers to wander 2026-03-01 22:02:59 -06:00
Veraxiel 6c425a43c6 Fixes to BWG compat. 2026-03-01 22:37:30 -05:00
Tyzillion 8b6c8d27b7 This fixes a bug that was causing species with one letter difference names to conflict in Showdown. 2026-02-27 17:13:06 -05:00
Polymeta a505bad554 [skip-ci] tidy up changelog 2026-02-27 10:56:57 +00:00
Polymeta e27e5a1d92 Merge branch 'ai-switch-fix' into 'main'
Stop the constant switching from AI NPC Trainers

See merge request cable-mc/cobblemon!2128
2026-02-27 10:55:00 +00:00
Hiroku 5e0357101d Merge branch 'feat/fishing-spawner-factory' into 'main'
PokeSnack and Fishing Spawner factories

See merge request cable-mc/cobblemon!2136
2026-02-27 02:11:53 +00:00
Andy 5420f7419f re-run licenseFormat 2026-02-26 19:14:03 -05:00
Andy 43ed2d3c7d local backmerge 2026-02-26 19:12:17 -05:00
Andy 93500f59ed Remove changelog lines from backmerge and run licenseFormat 2026-02-26 19:10:45 -05:00
Polymeta 08912fd53f Merge branch '#1945-brewing-stand-crash' into 'main'
#1945 Brewing Stand Shift Click Crash NeoForge 1.7.3 [1.21.1]

See merge request cable-mc/cobblemon!2163
2026-02-27 00:08:36 +00:00
CyrusandPolymeta 92c8fc0afc #1945 Brewing Stand Shift Click Crash NeoForge 1.7.3 [1.21.1] 2026-02-27 00:08:36 +00:00
Polymeta fae6bdb782 Merge branch 'main' into 'main'
Move BYG compat to Biomes We've Gone and Nether Descent

See merge request cable-mc/cobblemon!2149
2026-02-26 22:52:33 +00:00
J.T. McQuiggandPolymeta bba0100542 Move BYG compat to Biomes We've Gone and Nether Descent 2026-02-26 22:52:33 +00:00
Andy f9b66de742 Add fishing spawner factory to register influences to 2026-02-26 15:54:09 +00:00
Andy 3d0f1c826a Merge branch 'main' into feat/fishing-spawner-factory
update with cobblemon head
2026-02-26 10:52:48 -05:00
Andy 2a59add285 Merge branch cobblemon:main into main 2026-02-26 15:50:16 +00:00
Polymeta 0b83128aa0 Merge branch 'main' into 'main'
Fixes brushing for neoforge

Closes #1939

See merge request cable-mc/cobblemon!2154
2026-02-26 15:43:03 +00:00
Polymeta e2b04ff770 Merge branch 'ufo-fixes-and-improvements' into 'main'
UFO Fixes and Improvements

See merge request cable-mc/cobblemon!2156
2026-02-26 15:29:38 +00:00
Jackson BowesandPolymeta 4dabe50d43 UFO Fixes and Improvements 2026-02-26 15:29:37 +00:00
Hugin Juliansson Zachariasen 3dd0795b88 Merge branch cobblemon:main into main 2026-02-26 14:14:56 +00:00
Polymeta 70f1a8207f fix a apricorn bonemeal crash
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2026-02-26 12:17:32 +00:00
Polymeta 3ac18cce6e Merge branch 'main' into 'main'
Berry Growth Performance Optimization

See merge request cable-mc/cobblemon!2142
2026-02-26 12:15:32 +00:00
Polymeta aa0a0672d0 Merge branch 'show-my-pokemon-exp-gain' into 'main'
Party Overlay EXP display and evoltion unlocked Sound

See merge request cable-mc/cobblemon!2140
2026-02-26 11:59:48 +00:00
GertimoshkaandPolymeta ec2958400b Party Overlay EXP display and evoltion unlocked Sound 2026-02-26 11:59:48 +00:00
Polymeta fcb6bea78b Merge branch 'selecting-starters-in-style' into 'main'
The Cooler Starter Selection GUI

See merge request cable-mc/cobblemon!2164
2026-02-26 11:58:31 +00:00
GertimoshkaandPolymeta 5a76a39b77 The Cooler Starter Selection GUI 2026-02-26 11:58:31 +00:00
Jackson Bowes b5a4acfb7a Merge branch 'weight-influenced-collision' into 'main'
Weight influenced collision

See merge request cable-mc/cobblemon!2158
2026-02-26 01:49:56 -06:00
Jackson Bowes 1248230e67 Merge branch 'pasture-wander' into 'main'
No more pastured mons despawning

See merge request cable-mc/cobblemon!2155
2026-02-26 01:47:17 -06:00
Jackson Bowes 096db6cdcd No more pastured mons despawning 2026-02-26 01:47:16 -06:00
Jackson Bowes 72e416b9c7 Merge branch 'sub-drifting-fix' into 'main'
Submarine bug fixes

See merge request cable-mc/cobblemon!2157
2026-02-26 01:44:58 -06:00
Polymeta 9e8e80965b Merge branch 'fix/missing-botanypots-entries' into 'main'
Updated Botany Pots integration

See merge request cable-mc/cobblemon!2166
2026-02-26 07:41:03 +00:00
GitoidoandPolymeta 2325b436b1 Updated Botany Pots integration 2026-02-26 07:41:02 +00:00
Jackson Bowes 57421a2884 Merge branch 'scrolling_textures' into 'main'
Scrolling Texture Layer

See merge request cable-mc/cobblemon!2168
2026-02-25 21:54:47 -06:00
jackowes 4fdd3eba8e - changelog entry 2026-02-25 20:24:29 -06:00
jackowes e6efe800c0 - Clean up mixin
- add changelog entry
2026-02-25 19:45:52 -06:00
Polymeta 95aa99e18c Merge branch 'fix/particle-disapearing' into 'main'
fix: adapting the boundingBox to the visual if it's a beam it should have a...

See merge request cable-mc/cobblemon!2167
2026-02-26 01:16:09 +00:00
TerrainwaxandPolymeta 270484e745 fix: adapting the boundingBox to the visual if it's a beam it should have a... 2026-02-26 01:16:09 +00:00
Polymeta 719addf633 Merge branch 'molang-or-dishonor' into 'main'
Added `has_chosen_starter` & `get_starter_uuid` as available Molang functions

See merge request cable-mc/cobblemon!2159
2026-02-25 23:05:54 +00:00
Polymeta 31e386871f Merge branch 'little-dose-of-molang' into 'main'
Enchanting Molang

See merge request cable-mc/cobblemon!2162
2026-02-25 23:00:15 +00:00
Tyzillion bfd7e596d0 changelog 2026-02-25 17:52:39 -05:00
Tyzillion 643545d54c Added the ability to set a layer in the resolver as a scrolling texture. 2026-02-25 16:41:50 -05:00
Tyzillion fcb017f980 New Molang functions to check if an item is enchanted or has a certain enchantment. 2026-02-23 08:48:51 -05:00
JazzMcNade 937393b93d Remove old tasks 2026-02-22 20:37:45 -06:00
JazzMcNade 59fceeefc3 Smarter usage of looktracker 2026-02-22 16:06:26 -06:00
JazzMcNade ec7e106efb Item pickup for items too close to path to 2026-02-22 13:33:14 -06:00
Spicy dd52da7c42 oops 2026-02-18 20:57:23 -06:00
Spicy ff45def0e8 Added has_chosen_starter & get_starter_uuid as available Molang functions 2026-02-18 20:42:40 -06:00
jackowes f078584e56 - Add weight influenced collision 2026-02-18 15:24:43 -06:00
JazzMcNade d95c5687b1 Added eatHeldItem Objective, corrections to PickupItem 2026-02-18 01:35:05 -06:00
jackowes a11382b5a1 - Braking now works on Submarine (whoops).
- Strafing now has the same friction as forward movement (funny whoops).
- Submarine's surfacewater animations now play.
- Submarine camera no longer freaks out when looking up or down on the surface.
2026-02-17 20:28:55 -06:00
JazzMcNade 39ef558b9b Pickup item logic 2026-02-15 23:11:03 -06:00
Paul d1b8094539 Validate party positions of traded Pokémon upon trading 2026-02-16 11:23:24 +10:00
Paul b8d79af911 Migrate to a more unique tag name for data and config on scriptable entities, closes #1869 2026-02-16 10:57:11 +10:00
Hugin Juliansson Zachariasen 155b4b2182 Added changelog doc 2026-02-13 17:50:46 +00:00
Faering666 690ed845b2 Fixes brushing for neoforge 2026-02-13 15:55:51 +01:00
JazzMcNade 11452de369 class name typo 2026-02-09 01:35:25 -06:00
JazzMcNade fb4e5002a3 Migrate sweet berry bush harvesting 2026-02-08 21:44:28 -06:00
JazzMcNade 6dd7a7bc9a respect distraction rules 2026-02-08 13:30:52 -06:00
JazzMcNade ba718561aa MoveToRestingPlace Correction 2026-02-08 02:43:35 -06:00
Hiroku a7198fd324 Merge branch 'fossil_crash' into 'main'
Adjust fossil creation

Closes #1801

See merge request cable-mc/cobblemon!2150
2026-02-08 01:16:45 +00:00
aeroeng15 bc69ce91f3 Changelog 2026-02-07 16:00:00 -07:00
aeroeng15 1de1d8cdc3 Adjust ordering of party modification 2026-02-07 15:26:36 -07:00
Konoha 1f8171dd94 Experimental Hanging fix 2026-02-03 13:51:41 -05:00
JazzMcNade 21411d26ac More clean up, added moveToRestingPlace Objective 2026-02-03 00:49:14 -06:00
Hiroku 087bf75500 Merge branch 'party-selection-toast' into 'main'
Party Selection Tutorial Toasts

See merge request cable-mc/cobblemon!2148
2026-02-02 05:58:58 +00:00
CeejayandHiroku bac435ba7b Party Selection Tutorial Toasts 2026-02-02 05:58:58 +00:00
Hiroku 74a6106eb6 Merge branch 'snack-stack-fix' into 'main'
Fixes odd stacking behavior with the poke_bait item.

See merge request cable-mc/cobblemon!2143
2026-02-01 03:29:20 +00:00
Neovitalism 5ec993ad3c Update CHANGELOG.md 2026-01-31 21:13:10 -06:00
Paul 73a03d90da Resnapshot 2026-01-31 13:22:11 +10:00
Paul e6fda6137e Teeny tiny changelog [skip-ci] 2026-01-31 10:47:13 +10:00
Paul afae39acc8 Missed a bit of changelog [skip-ci] 2026-01-31 09:21:40 +10:00
Paul 37264aff0f Changelog stuff and no snapshot 2026-01-31 09:17:43 +10:00
Paul 2b60e6de77 Merge remote-tracking branch 'origin/lang-updates' 2026-01-31 09:12:27 +10:00
Hiroku 4f29e7457c Merge branch 'feature/riding-scrape' into 'main'
scrape riding data and fix script

See merge request cable-mc/cobblemon!2141
2026-01-30 09:43:44 +00:00
Polymeta 04a6ab31f4 rescrape data
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2026-01-30 09:26:22 +00:00
JazzMcNade 3f6c5ebc96 Sleep blocks movement, Added comfort distractions, Removed null check from StayAfloat 2026-01-29 23:25:12 -06:00
Hiroku a2cdc847dd Merge branch 'packet-sync-error-fix' into 'main'
Fixed packet sync issue with pokemon interactions, added "chance" requirement type

Closes #1933 and #1938

See merge request cable-mc/cobblemon!2147
2026-01-30 03:04:14 +00:00
阿鱼andWeblate 0bca678f56 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2026-01-30 02:59:44 +00:00
Paul 067c3607aa Tweak /pctake to check the PC's box count and use that for constraints 2026-01-30 12:20:17 +10:00
Hiroku 823c1f6444 Merge branch 'main' into 'main'
Fixes PcTake not respecting defaultBoxCount

See merge request cable-mc/cobblemon!2146
2026-01-30 02:18:38 +00:00
Paul bfc00635cd Fixed packet sync issue with pokemon interactions, added "chance" requirement type 2026-01-30 12:16:01 +10:00
Hiroku b2e5b85ac5 Merge branch 'Custom-Ball-Resources-updated' into 'main'
updated ball texture locations missing from last update

See merge request cable-mc/cobblemon!2145
2026-01-30 00:24:49 +00:00
阿鱼andWeblate 2c27476954 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.7% (9034 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2026-01-29 13:40:10 +00:00
Auristite aab78d84fc Fixes PcTake not respecting defaultBoxCount
Command is also missing lang option for "cobblemon.command.pctake.removed" (Removing Pokémon from self)
2026-01-29 04:46:25 +00:00
Zack the GhastandWeblate cb632c2a65 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.9% (6154 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2026-01-29 01:28:38 +00:00
Dragonwhisper92 8d219f1338 updated ball texture locations 2026-01-28 23:45:08 +00:00
Zack the GhastandWeblate 1e6a4ed984 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.7% (6143 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2026-01-28 21:10:25 +00:00
geumuandWeblate 64240c31fc Translated using Weblate (Korean)
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ko/
2026-01-28 17:35:35 +00:00
Zack the GhastandWeblate d2222c3858 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.6% (6129 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2026-01-28 14:44:02 +00:00
geumuandWeblate c7f31c3e14 Translated using Weblate (Korean)
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ko/
2026-01-28 14:44:01 +00:00
Zack the GhastandWeblate 740e846b2d Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.5% (6125 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2026-01-28 08:26:35 +00:00
Neovitalism 246d00aa3f Fixes odd stacking behavior with the poke_bait item. 2026-01-27 21:45:05 -06:00
Zack the GhastandWeblate 06f9d60595 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.5% (6123 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2026-01-27 04:12:54 +00:00
Konoha b3ed47fbca Adjust thresholds and scoring 2026-01-26 15:00:50 -05:00
Loopiwc 3a6ad70b76 fix: Use scheduleTick in randomTick to avoid tick scheduler NPE
- Schedule growth to next tick instead of direct setBlock in randomTick
- Add hasScheduledTick check to prevent duplicate scheduling
- Add IS_ROOTED guard in tick() handler
2026-01-27 03:35:11 +08:00
Loopiwc 8120270bf8 perf: Replace BlockEntityTicker with Random Tick + time compensation for Berry growth
- Remove per-tick BlockEntityTicker to reduce server load
- Add processTick() method with gameTime-based compensation
- Track lastTickTime in NBT for accurate growth calculation
- Berry growth timing remains accurate via elapsed time batching
2026-01-26 16:30:43 +08:00
JazzMcNade 0bbdfd2c5e Added Sleeping 2026-01-26 02:28:20 -06:00
JazzMcNade f43b7d3dd7 Cleanup 2026-01-25 20:35:28 -06:00
Zack the GhastandWeblate d54439ce14 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.3% (6103 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2026-01-26 02:31:37 +00:00
TeggyandWeblate 32ee4bb72a Translated using Weblate (Spanish)
Currently translated at 84.3% (7644 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/es/
2026-01-25 13:02:37 +00:00
JazzMcNade 6291ac0e23 Added MoveIntoWaterObjective 2026-01-25 02:50:46 -06:00
Polymeta e7d2a46cc0 Bumping snapshot version 2026-01-25 06:57:31 +00:00
JazzMcNade 4f528c855b Created MoveOutOfWater Objective 2026-01-24 23:08:21 -06:00
YasitoandWeblate 3ee94ec076 Translated using Weblate (French)
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-25 03:06:53 +00:00
YasitoandWeblate 589293abc4 Translated using Weblate (French (Canada))
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-25 03:06:49 +00:00
Paul 279865cc7c Resnaps your shot 2026-01-25 11:53:29 +10:00
Paul b597b149c3 Snapnot 2026-01-25 10:18:32 +10:00
Paul b7f592f2a8 Relocate mongodb packages 2026-01-25 10:18:02 +10:00
Paul 70e17c22e7 Merge remote-tracking branch 'origin/lang-updates' 2026-01-25 10:17:49 +10:00
YasitoandWeblate 51b18ca0f6 Translated using Weblate (French)
Currently translated at 99.6% (9027 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-25 00:16:58 +00:00
YasitoandWeblate a83f243a3b Translated using Weblate (French (Canada))
Currently translated at 99.9% (9059 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-25 00:16:55 +00:00
Weblate f5b088c708 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/
2026-01-25 00:14:04 +00:00
YasitoandWeblate dc454cbb68 Translated using Weblate (French)
Currently translated at 99.5% (9022 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-25 00:13:56 +00:00
YasitoandWeblate 3b99e38da2 Translated using Weblate (French (Canada))
Currently translated at 99.9% (9057 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-25 00:13:54 +00:00
Paul 483af57964 Merge remote-tracking branch 'origin/lang-updates' 2026-01-25 10:12:48 +10:00
Dmytro BunnuaandWeblate a941bdddf3 Translated using Weblate (Ukrainian)
Currently translated at 76.9% (6971 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/uk/
2026-01-24 18:24:12 +00:00
TeggyandWeblate 246ba4a93b Translated using Weblate (Spanish)
Currently translated at 83.9% (7611 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/es/
2026-01-24 18:24:09 +00:00
Paul 3347c084ed More changelog [skip-ci] 2026-01-24 22:42:58 +10:00
Paul 8175cee454 More translations 2026-01-24 22:11:15 +10:00
Paul 37d54053a5 Merge remote-tracking branch 'origin/lang-updates' 2026-01-24 22:10:10 +10:00
Dmytro BunnuaandWeblate b8846bd74c Translated using Weblate (Ukrainian)
Currently translated at 76.8% (6966 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/uk/
2026-01-24 11:47:21 +00:00
Paul 1716e135c4 Changelog [skip-ci] 2026-01-24 21:45:14 +10:00
Paul 0ac804cfcb Cleanup 2026-01-24 21:20:50 +10:00
Hiroku aecc132814 Merge branch 'pokeballUIResourcePathChange' into 'main'
ball_icon resource location changes

See merge request cable-mc/cobblemon!2113
2026-01-24 11:13:26 +00:00
Hiroku 8b47876dff Merge branch 'Add-Plaques-to-Village-Pokecenters' into 'main'
Adding Plaques to Village Pokecenters

See merge request cable-mc/cobblemon!2139
2026-01-24 09:27:56 +00:00
Slippy ffc108953a Adding Plaques to Village Pokecenters 2026-01-24 01:51:33 -06:00
Paul 0a106174fe Changelog cleanup [skip-ci] 2026-01-24 15:59:27 +10:00
Paul 90210bee3c Fixed cottonee cries being inconsistent due to not having appropriate pose type coverage 2026-01-24 15:13:08 +10:00
Paul 8603cd4ad0 Merge remote-tracking branch 'origin/main' into Expression-stuffs 2026-01-24 13:56:14 +10:00
Hiroku 7b2c6827c2 Merge branch 'Expression-stuffs' into 'main'
Expression stuffs

See merge request cable-mc/cobblemon!2138
2026-01-24 03:55:02 +00:00
Paul 902b4a6d21 Fixed croagunk and toxicroak playing cry animations without the sound 2026-01-24 13:54:41 +10:00
Hiroku a847cb5926 Merge branch 'fix-plain-aprijuice-prefix' into 'main'
Fix Aprijuice 'Plain' prefix

See merge request cable-mc/cobblemon!2137
2026-01-24 03:46:05 +00:00
Paul 050c6f5adc Merge remote-tracking branch 'origin/Expression-stuffs' into Expression-stuffs 2026-01-24 13:41:23 +10:00
Paul fb95fb3cf7 Various cry corrections from implementation 2026-01-24 13:41:11 +10:00
Carmendar d507367411 Bird stamina changes. 2026-01-23 21:30:43 -06:00
Paul faa19cebcb Fixed perma zero stamina on horses when landing from bird 2026-01-24 13:16:38 +10:00
Paul aced374367 Fixed birds falling out of the sky and not gliding all chill like 2026-01-24 12:40:04 +10:00
Paul d424a6f1d3 Fixed stamina stat flowing to crazy negative from bird sometimes 2026-01-24 11:58:25 +10:00
Carmendar 71bb1c32de stamina expression changes for Bird and Hover. Changes to Mantine riding. 2026-01-23 18:56:17 -06:00
Carmendar f726fcedb9 Merge branch 'main' into implement_pokemon 2026-01-23 18:09:48 -06:00
Weblate 77344ccc2f Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/
2026-01-23 17:29:44 +00:00
Dmytro BunnuaandWeblate 90bc16be90 Translated using Weblate (Ukrainian)
Currently translated at 76.8% (6960 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/uk/
2026-01-23 17:29:37 +00:00
Gustavo PuerariandWeblate d1b743a01f Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.3% (8908 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2026-01-23 17:29:33 +00:00
TeggyandWeblate aed651c0a0 Translated using Weblate (Spanish)
Currently translated at 83.9% (7608 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/es/
2026-01-23 17:29:28 +00:00
Faintful 4c477e1675 Add changelog 2026-01-23 17:36:05 +01:00
Faintful d1cdc6789c Handle case for LOW quality Aprijuice in getName() for proper 'Plain' prefix 2026-01-23 17:33:04 +01:00
Andy 70fe1682b0 remove whitespace in pokesnack block entity 2026-01-23 10:49:24 -05:00
Andy 9058bde326 remove whitespace from changelog 2026-01-23 10:41:52 -05:00
Andy bf425efd40 Merge branch 'feat/snack-spawner-factory' into 'main'
Added PokeSnackSpawnerFactory so influences can be registered to pokesnacks

See merge request ppVon/cobblemon!1
2026-01-23 15:39:21 +00:00
geumuandWeblate cd3127b983 Translated using Weblate (Korean)
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ko/
2026-01-23 13:22:11 +00:00
Watuneni iteiteandWeblate 68f5eff048 Translated using Weblate (Japanese)
Currently translated at 100.0% (9061 of 9061 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ja/
2026-01-23 13:22:06 +00:00
Andy cebff87656 update changelog 2026-01-23 03:49:09 -05:00
Andy d24fb13877 Add fishing spawner factory to register influences to 2026-01-23 03:47:34 -05:00
Paul c3d2918a2b Fixed a crash when joining a server and a player is riding nearby 2026-01-23 17:49:57 +10:00
Andy 1d82df464a Added PokeSnackSpawnerFactory so influences can be registered to pokesnacks 2026-01-23 02:19:02 -05:00
Paul 0432525c06 Throh resize 2026-01-23 17:04:45 +10:00
Paul a60f27e282 Fixed implemented flag missing from the new 1.7.2 pokemon, subtle size changes 2026-01-23 17:04:14 +10:00
Test 5f0182cb7e fix type asset 2026-01-23 01:48:49 -05:00
Paul 4a3ae9407b Translation changelog [skip-ci] 2026-01-23 16:44:32 +10:00
Paul 766c2838d2 Merge remote-tracking branch 'origin/lang-updates' 2026-01-23 14:34:19 +10:00
Hiroku 4cb95589b4 Merge branch 'more-fixes' into 'main'
More fixes

See merge request cable-mc/cobblemon!2134
2026-01-23 04:30:49 +00:00
Hiroku a8d3c2dd52 Merge branch '1.7.2-spawns' into 'main'
Added spawns. Fixed spawns. Updated tags.

Closes #1896

See merge request cable-mc/cobblemon!2131
2026-01-23 04:13:07 +00:00
Test cb5d7b6ad7 rm unused 2026-01-22 23:05:38 -05:00
Test c7dcc64595 sync repo assets 2026-01-22 23:00:10 -05:00
Paul 6573e08da7 Fix for packet handling to ensure all packets are handled on main and without extra delays on Fabric, closes #1903 2026-01-23 13:37:36 +10:00
Paul cd695ade4a Apparently I put more changelog in than was meant to be there 2026-01-23 13:22:37 +10:00
Paul 55cb413cfc Merge remote-tracking branch 'origin/main' into 1.7.2-spawns 2026-01-23 13:11:50 +10:00
Paul 4f1bf7fcbb Changelog for spawns [skip-ci] 2026-01-23 13:11:42 +10:00
Test 154ee80ead fix some block issues 2026-01-22 21:32:51 -05:00
Test 1c9f9bb198 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2026-01-22 20:38:08 -05:00
Test 6836343f11 ride summary 2026-01-22 20:37:46 -05:00
RedGenesectNinja aa0d1cd943 Updated changelog 2026-01-22 14:44:46 -06:00
Hiroku 798f1da8b3 Merge branch 'main' into 'main'
Issue 1926: Make SpawnBaitInfluence apply all effects correctly

See merge request cable-mc/cobblemon!2130
2026-01-22 13:44:44 +00:00
Andy d98efb52b6 Add changelog line and extend author tag 2026-01-22 08:38:13 -05:00
Kenji_64 2f27a03f08 Alolan Raichu can look around in the menu now (yay) 2026-01-22 13:36:19 +01:00
Kenji_64 e33025b1fa Fixed the weird eye clipping on Dragapult (fr this time) 2026-01-22 13:36:00 +01:00
Kenji_64 ade2481f42 Treecko line has their cries back 2026-01-22 13:35:39 +01:00
Hiroku 576e2301ce Merge branch 'open-actor-classes' into 'main'
Mark the actor classes as open so they can be extended.

See merge request cable-mc/cobblemon!2129
2026-01-22 12:19:06 +00:00
Polymeta a568d45d75 [skip-ci] tidy up changelog take two 2026-01-22 09:58:38 +00:00
Hiroku bc19a7e4c1 Merge branch 'decor-split' into 'main'
Decor split

See merge request cable-mc/cobblemon!2127
2026-01-22 09:42:35 +00:00
Polymeta 616e438f17 [skip-ci] tidy up changelog 2026-01-22 09:40:47 +00:00
Polymeta 9bb11c46d5 Merge branch 'implement_pokemon' into 'main'
Implement pokemon

Closes #1921 and #1800

See merge request cable-mc/cobblemon!2063
2026-01-22 09:28:25 +00:00
Carmendar 5f470bb703 Honchkrow and Mantine camera fixes. 2026-01-21 23:25:53 -06:00
Andy 276f13cea5 1926: Re-add affectWeight comment 2026-01-22 00:08:34 -05:00
Andy ac069687f1 1926: Changed SpawnBaitInfluence to apply all bait effects properly in affectWeight 2026-01-22 00:07:14 -05:00
Deltric f248c22eed Fix initialPos being able to change and changelog 2026-01-21 22:54:53 -06:00
RedGenesectNinja 65a5687f92 Fixed Dusknoir's stomach mouth lips glowing while it sleeps 2026-01-21 22:27:11 -06:00
Deltric ea50fa534b Mark the actor classes as open so they can be extended. 2026-01-21 21:35:03 -06:00
RedGenesectNinja 4bd3c4af58 Updated changelog 2026-01-21 21:20:16 -06:00
RedGenesectNinja 283d80f7ed Implemented Croagunk and Toxicroak's animations 2026-01-21 21:19:22 -06:00
Veraxiel 0238ca80f0 Added spawns. Fixed spawns. Updated tags. 2026-01-21 18:53:40 -05:00
RedGenesectNinja d24c5fe874 Fixed a mistake I made with file placement 2026-01-21 15:32:14 -06:00
RedGenesectNinja e65e21f2ff Fixed Chimecho's cry not playing a sound 2026-01-21 15:21:02 -06:00
Carmendar e1d417718f Added Flygon jump and Mantine ride anims with temp ride stats. 2026-01-21 02:25:05 -06:00
Polymeta d4308b0a4f Merge branch 'fix-battle-memory-leak' into 'main'
Fixed memory leak from battles not being cleaned up after ending.

See merge request cable-mc/cobblemon!2075
2026-01-21 08:09:44 +00:00
Konoha 2a1d1e4474 fix: AI constant switching 2026-01-20 21:09:30 -05:00
Test bc0d530484 loisence 2026-01-20 19:19:53 -05:00
Jerzykv 56650418d2 Implemented Throh and Sawk 2026-01-20 20:32:21 +01:00
Jerzykv 0543b84d34 The battle idle should probably play the battle idle animation 2026-01-20 19:57:45 +01:00
Jerzykv 1f50687a59 Re-added Honchkrow's driving license 2026-01-20 19:53:25 +01:00
Polymeta ed04faf0d8 Merge branch 'dispenser-fix' into 'main'
Resolved Dispenser Behaviors not working

See merge request cable-mc/cobblemon!2118
2026-01-20 14:46:55 +00:00
AramandPolymeta 1ed020f3e0 Resolved Dispenser Behaviors not working 2026-01-20 14:46:54 +00:00
Polymeta 7e385d8c94 Merge branch 'default-offest' into 'main'
[FEAT] Add `default_seat` option to seat offset posers

See merge request cable-mc/cobblemon!1999
2026-01-20 14:46:44 +00:00
Polymeta ee509b5438 Merge branch 'molang-inventory-and-move-utility' into 'main'
molang additions: Move struct accessor and player inventory utils

See merge request cable-mc/cobblemon!2103
2026-01-20 14:46:34 +00:00
Jerzykv ac9394131c Implemented Litleo and Pyroar - Changelog 2026-01-20 12:01:09 +01:00
Jerzykv d058a306a7 Implemented Litleo and Pyroar 2026-01-20 11:58:48 +01:00
Jerzykv b9be0c3fcb Swirlix and Slurpuff cry fixes 2026-01-20 10:14:16 +01:00
Jerzykv b59b46568a Swirlix and Slurpuff poser changes 2026-01-20 10:14:11 +01:00
Jerzykv 408cbc8c49 Slurpuff and Aromatisse scale changes 2026-01-20 10:13:55 +01:00
Test 1537816132 log of change 2026-01-20 00:56:36 -05:00
Test 1705639950 loot 2026-01-20 00:50:04 -05:00
Test ce32541dd6 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into decor-split 2026-01-19 23:45:28 -05:00
Test 3ffea4f4dd split items 2026-01-19 23:44:20 -05:00
Hiroku f942d7c34a Merge branch 'misc-additions-fixes' into 'main'
Couple of misc API additions and bug fixes.

See merge request cable-mc/cobblemon!2125
2026-01-19 02:16:09 +00:00
Deltric 0f1ada4624 Pass in pnx to the event 2026-01-18 18:52:27 -06:00
Deltric b4ee4629bf Couple of misc API additions and bug fixes. 2026-01-18 17:57:28 -06:00
Paul d0b64e2d82 Respect the BYPASSES_INVULNERABILITY damage tag 2026-01-18 22:12:25 +10:00
Jerzykv a8ce3c2175 Fixed Wishiwashi's School Form, Fixes #1921 2026-01-18 12:39:16 +01:00
Jerzykv 80ae127379 Implemented Spritzee and Aromatisse. Smells good. 2026-01-18 12:36:48 +01:00
Jerzykv bd3a9fb3af Implemented Swirlix and Slurpuff. How sweet! 2026-01-18 11:28:15 +01:00
Paul 29c291fd7a Minor doc change [skip-ci] 2026-01-18 13:28:13 +10:00
Paul 493f71302e Some brain clarification stuff and some docs for adding to the brains 2026-01-18 13:20:03 +10:00
Instrafe d0eaccb81b Fixed Ferroseed and Ferrothorn's posers not identifying a root bone (woops) 2026-01-17 12:12:08 -05:00
Paul 1ed2042283 Fixed /calculateseatpositions expecting no underscore when actually we always use an underscore 2026-01-17 22:32:57 +10:00
Deltric 0b531d967e Merge remote-tracking branch 'origin/fix-battle-memory-leak' into fix-battle-memory-leak
# Conflicts:
#	common/src/main/resources/data/cobblemon/showdown.zip
2026-01-17 03:42:38 -06:00
Deltric b0d1aec9ab Update showdown 2026-01-17 03:42:21 -06:00
Deltric f4d47098b5 Fixed memory leak from battles not being cleaned up after ending. 2026-01-17 03:42:08 -06:00
Paul ab5a54f21e Fixed excessive wander chances 2026-01-17 18:25:59 +10:00
Paul 440e2855c0 Swimmers can tread water when not pathing on new brain 2026-01-17 16:43:44 +10:00
Paul 8ebecc4928 Migrated stay afloat task to new brain 2026-01-17 11:24:13 +10:00
Instrafe 1989b8aa92 Implemented remodels for Ferroseed and Ferrothorn 2026-01-16 17:06:45 -05:00
Paul 4f0108c8a2 Replaced busy locks with fixations that implement LockFixation 2026-01-16 22:16:54 +10:00
Hiroku 948ca61ef3 Merge branch 'fix-super-potion-ingredients-tag' into 'main'
Fix super potion ingredients tag

See merge request cable-mc/cobblemon!2121
2026-01-16 08:27:19 +00:00
Hiroku e60aca30ba Merge branch 'patch-2' into 'main'
Fix Syrupy Apple missing from evolution items tag

See merge request cable-mc/cobblemon!2120
2026-01-16 08:26:22 +00:00
Hiroku fb5055c39e Merge branch 'form_crash' into 'main'
Initialize FormData when updating

Closes #1916

See merge request cable-mc/cobblemon!2122
2026-01-16 08:20:23 +00:00
Paul dfb5650121 Merge remote-tracking branch 'origin/main' 2026-01-16 18:17:01 +10:00
Paul 8a0cbf28fe Fixed battles not ending fully when a switch is in progress, closes #1917 2026-01-16 18:16:11 +10:00
aeroeng15 a6b9060d57 Changelog 2026-01-15 20:54:54 -07:00
aeroeng15 8e57995e44 Make It Proper 2026-01-15 20:51:59 -07:00
aeroeng15 1d8257808c Initialize rather than set; seems to fix the issue 2026-01-15 20:42:14 -07:00
Carmendar e290fe9c75 Modified Hover expressions and buffs/nerfs for hover mounts. 2026-01-15 21:23:34 -06:00
Paul 32cd79baec Improved wandering so they can look around and (rarely) wander while in a herd, fixed look targeting for wandering 2026-01-15 22:25:19 +10:00
Jerzykv 06a50cfeeb Changelog for the cottons 2026-01-15 11:12:17 +01:00
Jerzykv 00888c8ad5 Implemented Cottonee and Whimsicott remodels 2026-01-15 11:11:44 +01:00
Faintful e3582ccfb4 Add changelog 2026-01-14 19:49:11 +01:00
Faintful 4c6822b1c6 Merge remote-tracking branch 'upstream/main' into fix-super-potion-ingredients-tag 2026-01-14 19:46:54 +01:00
Faintful 2e6a4c7341 Change Hondew for Aguav 2026-01-14 19:28:49 +01:00
Micky 8edb5e1013 Fix Syrupy Apple missing from evolution items tag 2026-01-14 18:25:06 +00:00
Paul a8ac858918 Migrated herding to bigger brain 2026-01-14 21:48:20 +10:00
Polymeta 6fb139cbb9 Merge branch 'pokemon-interactions-fixes' into 'main'
Pokémon Interaction fixes

See merge request cable-mc/cobblemon!2117
2026-01-14 00:03:33 +00:00
lionandPolymeta c81c95142b Pokémon Interaction fixes 2026-01-14 00:03:32 +00:00
Hiroku afde822860 Edit CHANGELOG.md [skip-ci] 2026-01-12 10:50:47 +00:00
Hiroku 474c386535 Merge branch 'main' into 'main'
Fix Fresh Start Mochi EV Reset

See merge request cable-mc/cobblemon!2115
2026-01-12 10:48:40 +00:00
RedGenesectNinja 3963e83717 Implemented Ducklett and Swanna's cries with placeholder animations 2026-01-12 01:04:46 -06:00
Konoha 7893e365da yolo: drop item on give_item if inventory is full & sneak in a fix for active_dialogue 2026-01-11 18:50:52 -05:00
ToothCollector 71b9ae8dee add fix to CHANGELOG.md 2026-01-11 21:31:22 +02:00
ToothCollector b87b47d62a Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2026-01-11 21:28:04 +02:00
Hiroku 2bb85718d7 Merge branch 'main' into 'main'
Fix Adorn compatibility

See merge request cable-mc/cobblemon!2112
2026-01-11 12:21:25 +00:00
Tate Frost ee187d7b89 Delete file + update Adorn resource pack metadata
- Delete config file that was committed in error
- Update Adorn resource pack metadata to reflect new wood type
2026-01-10 22:30:27 -06:00
Hiroku b6a7051b2c Fixed galarian weezing blink crash, closes #1800 2026-01-11 04:28:37 +00:00
Tate Frost 3532cac278 Update CHANGELOG.md 2026-01-10 22:18:01 -06:00
Hiroku 1447ab25b4 Merge branch 'CombeeWorldGenFix' into 'main'
CombeeWorldGenFix

See merge request cable-mc/cobblemon!2071
2026-01-11 02:55:56 +00:00
Hiroku 9a06ca78c6 Merge branch 'fix-mongo-driver' into 'main'
Fix MongoDB ClassNotFoundException by including drivers at runtime

See merge request cable-mc/cobblemon!2098
2026-01-11 02:47:10 +00:00
Hiroku f6ba70634b Merge branch 'double-battle-gimmicks' into 'main'
Fix double battle gimmicks not being processed

See merge request cable-mc/cobblemon!2094
2026-01-11 02:46:36 +00:00
Hiroku 148fd04a93 Merge branch 'molang-evaluate_expression' into 'main'
molang addition: exception handling for run_molang

See merge request cable-mc/cobblemon!2102
2026-01-11 02:12:07 +00:00
Hiroku 17f60623ee Merge branch 'effect-id-regex-update' into 'main'
Custom messages for datapack moves and abilities

See merge request cable-mc/cobblemon!2106
2026-01-11 02:08:42 +00:00
Hiroku c5ece27c11 Merge branch '1861-galarien_mrmime_mount' into 'main'
Fix Galarian Mr. Mime incorrectly being rideable.

Closes #1861

See merge request cable-mc/cobblemon!2107
2026-01-11 02:02:14 +00:00
Hiroku 296ccd1a76 Merge branch 'main' into 'main'
Fix pasture block incorrect hit-box when facing north and south.

See merge request cable-mc/cobblemon!2109
2026-01-11 02:01:44 +00:00
ToothCollector 82a4f71f24 fix(FreshStartMochiItem.kt): Set all Pokemon's EVs to zero with the appropriate method. 2026-01-10 17:10:15 +02:00
Jerzykv 2cb1cf2f83 tiny fix on Togekiss 2026-01-10 13:36:40 +01:00
Paul d46394cb1d Migrated sheep grass eating to bigger brains 2026-01-09 22:44:45 +10:00
阿鱼andWeblate f13a4e0e24 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2026-01-08 18:45:37 +00:00
Dragonwhisper92 17e1bbd6a1 oops changelog extra '-' removed 2026-01-07 20:00:26 +00:00
Dragonwhisper92 c36ff0a0fe ball_icon resource location changes
Changed the resource location of pokeball icons in the gui to use the balls namespace instead of cobblemon, allowing mods to properly use their own name space for these textures
2026-01-07 19:57:36 +00:00
Tate Frost 08b58e2f78 Fix Adorn compatibility
- Fixed Apricorn block model rotation for counters/sinks/cupboards/drawers to match that of most recent version of Adorn
- Added Saccharine wood + Adorn compatibility
2026-01-07 02:04:52 -06:00
Merv 62d2b8db2d Edit CHANGELOG.md 2026-01-06 18:47:45 +00:00
Merv 3869f7ed93 Merge branch cobblemon:main into main 2026-01-05 23:09:08 +00:00
Jerzykv 8dbb350230 minor fix to apricorn textures 2026-01-05 21:56:02 +01:00
Dragonwhisper92 c9c44872d6 Updated Changelog. 2026-01-05 19:35:05 +00:00
Dragonwhisper92 cae53efedc Updated ActivateInstruction.kt to have an optional message parameter. 2026-01-05 19:14:40 +00:00
Jerzykv 52f9ffb1f6 fixed Politoed's drop again. thanks scraper 2026-01-05 12:23:07 +01:00
Polymeta 5fac24cee8 Merge branch 'Molang-SimpleDateFormat-Fix' into 'main'
Fixed Molang functions:

See merge request cable-mc/cobblemon!2105
2026-01-05 11:22:45 +00:00
Polymeta 1954dfec80 Merge branch '1784-riding_stats_order' into 'main'
Fix riding stat boosts to always render in the same order

Closes #1784

See merge request cable-mc/cobblemon!2108
2026-01-05 11:20:29 +00:00
Landon 2eea2b64c2 Merge branch 'bag-clause' into 'main'
Bag Clause (Preventing Item use in Battles)

See merge request cable-mc/cobblemon!1849
2026-01-05 08:12:36 +00:00
GDWR a127a93be8 Sort boosts when rendering to remove the jumping of stats between items
The sort uses the key. As `RidingStat` it sorts them by the enum value.
2026-01-04 20:27:42 +00:00
GDWR 9b32f85817 Set an empty riding definition for Galarian Mr. Mime to avoid inheriting the default definition 2026-01-04 17:28:02 +00:00
Dragonwhisper92 ec139d2677 Updated Effect.kt to use a custom REGEX entry 2026-01-04 16:46:44 +00:00
Landon Wills 4327be0cf9 Omit bag clause from getting sent to showdown 2026-01-04 02:22:32 -05:00
Landon Wills c25c832b31 Remove import 2026-01-04 01:21:20 -05:00
Landon Wills eabaabc535 Move bag clause check to bag items instead of pokemon entity 2026-01-04 01:19:26 -05:00
Dragonwhisper92 9acf97f5a0 Updated CHANGELOG.md 2026-01-04 00:18:24 +00:00
Dragonwhisper92 24fc212c76 Updated CHANGELOG.md 2026-01-04 00:15:32 +00:00
Hiroku 04f88bdd63 Merge branch 'form-change-move-sanitization-fix' into 'main'
Fix the improper sanitization of moves on mons with compounding properties

Closes #1853 and #1846

See merge request cable-mc/cobblemon!2085
2026-01-04 00:05:26 +00:00
Dragonwhisper92 a4eb58aa57 Fixed molang functions:
- date_local_time
- date_of
- date_is_after
too use the correct SimpleDateFormat of "dd/MM/yyyy"
2026-01-03 23:40:12 +00:00
LucasandWeblate 030195e3ff Translated using Weblate (French)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-03 08:52:44 +00:00
YasitoandWeblate d21a52ae68 Translated using Weblate (French)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-03 08:52:43 +00:00
YasitoandWeblate 3c1f1dbacb Translated using Weblate (French (Canada))
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-03 08:52:42 +00:00
Paul d5cc2de7e5 I want a license to kill this pipeline error 2026-01-03 17:03:01 +10:00
Paul a5088cf264 Migrated objective configs into the objective classes, moved OT type class out of the Pokemon file 2026-01-03 16:18:20 +10:00
Merv 6704d4e5ee Maybe fix pasture block incorrect hitbox 2026-01-03 02:05:03 +00:00
LucasandWeblate 787c4851ff Translated using Weblate (French)
Currently translated at 99.9% (9021 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:02:21 +00:00
YasitoandWeblate bf6e7fafd3 Translated using Weblate (French)
Currently translated at 99.9% (9021 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:02:20 +00:00
LucasandWeblate ea6df764c0 Translated using Weblate (French)
Currently translated at 99.9% (9020 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:01:41 +00:00
YasitoandWeblate f242de272d Translated using Weblate (French)
Currently translated at 99.9% (9020 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:01:41 +00:00
LucasandWeblate 5232e2e9bc Translated using Weblate (French)
Currently translated at 99.9% (9019 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:01:09 +00:00
YasitoandWeblate ca35898243 Translated using Weblate (French)
Currently translated at 99.9% (9019 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:01:08 +00:00
LucasandWeblate 869457d235 Translated using Weblate (French)
Currently translated at 99.9% (9018 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:00:52 +00:00
YasitoandWeblate 6736c8160b Translated using Weblate (French)
Currently translated at 99.9% (9018 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:00:51 +00:00
LucasandWeblate 243c50550d Translated using Weblate (French)
Currently translated at 99.9% (9017 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:00:37 +00:00
YasitoandWeblate fe7d3ef23a Translated using Weblate (French)
Currently translated at 99.9% (9017 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:00:36 +00:00
LucasandWeblate 57ad77fc39 Translated using Weblate (French)
Currently translated at 99.9% (9016 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 21:00:10 +00:00
LucasandWeblate d70e7bd1b3 Translated using Weblate (French)
Currently translated at 99.9% (9015 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:59:34 +00:00
YasitoandWeblate 254cc931ea Translated using Weblate (French)
Currently translated at 99.9% (9015 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:59:34 +00:00
LucasandWeblate 01fe5cffe8 Translated using Weblate (French)
Currently translated at 99.9% (9014 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:59:19 +00:00
YasitoandWeblate 3e18995a37 Translated using Weblate (French)
Currently translated at 99.9% (9014 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:59:18 +00:00
YasitoandWeblate ff161c9c9b Translated using Weblate (French)
Currently translated at 99.9% (9013 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:58:36 +00:00
LucasandWeblate 6b7b4f326d Translated using Weblate (French)
Currently translated at 99.9% (9013 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:58:35 +00:00
LucasandWeblate f50f7dec29 Translated using Weblate (French)
Currently translated at 99.8% (9012 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:58:17 +00:00
YasitoandWeblate a5def20c58 Translated using Weblate (French)
Currently translated at 99.8% (9012 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:58:16 +00:00
YasitoandWeblate b23204f9c9 Translated using Weblate (French)
Currently translated at 99.8% (9011 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:57:51 +00:00
LucasandWeblate 4972de0aaa Translated using Weblate (French)
Currently translated at 99.8% (9011 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:57:50 +00:00
LucasandWeblate 58a1f3d7b4 Translated using Weblate (French)
Currently translated at 99.8% (9010 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:57:33 +00:00
YasitoandWeblate f516edb858 Translated using Weblate (French)
Currently translated at 99.8% (9010 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:57:32 +00:00
LucasandWeblate 161aa952fa Translated using Weblate (French)
Currently translated at 99.8% (9008 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:55:43 +00:00
YasitoandWeblate 3b26a13ad6 Translated using Weblate (French)
Currently translated at 99.8% (9008 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:55:43 +00:00
LucasandWeblate 014189217a Translated using Weblate (French)
Currently translated at 99.8% (9007 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:55:29 +00:00
YasitoandWeblate 978debb40c Translated using Weblate (French)
Currently translated at 99.8% (9007 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:55:28 +00:00
LucasandWeblate 5be707811e Translated using Weblate (French)
Currently translated at 99.8% (9006 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:55:13 +00:00
YasitoandWeblate ac44a98f8a Translated using Weblate (French)
Currently translated at 99.8% (9006 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:55:12 +00:00
LucasandWeblate 03ecc2ae8d Translated using Weblate (French)
Currently translated at 99.8% (9005 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:54:13 +00:00
YasitoandWeblate 1518379107 Translated using Weblate (French)
Currently translated at 99.8% (9005 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:54:12 +00:00
YasitoandWeblate a58c8c59e1 Translated using Weblate (French)
Currently translated at 99.8% (9004 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:53:58 +00:00
LucasandWeblate 37959b5048 Translated using Weblate (French)
Currently translated at 99.8% (9004 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:53:58 +00:00
YasitoandWeblate cbcc9fc6f1 Translated using Weblate (French (Canada))
Currently translated at 99.7% (9002 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-02 20:53:57 +00:00
YasitoandWeblate d236aaa7da Translated using Weblate (French)
Currently translated at 99.7% (9000 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:50:35 +00:00
LucasandWeblate a2cd5a671c Translated using Weblate (French)
Currently translated at 99.7% (9000 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:50:35 +00:00
LucasandWeblate 1d6a45bf4d Translated using Weblate (French)
Currently translated at 99.7% (8998 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:49:59 +00:00
YasitoandWeblate 5bfe703ed7 Translated using Weblate (French)
Currently translated at 99.7% (8998 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:49:58 +00:00
YasitoandWeblate fc8485388e Translated using Weblate (French)
Currently translated at 99.7% (8997 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:45:38 +00:00
LucasandWeblate a5593b3131 Translated using Weblate (French)
Currently translated at 99.7% (8997 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:45:38 +00:00
YasitoandWeblate 9541bf3267 Translated using Weblate (French (Canada))
Currently translated at 99.6% (8991 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-02 20:45:37 +00:00
LucasandWeblate 1037fe0a0e Translated using Weblate (French)
Currently translated at 99.6% (8989 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:38:19 +00:00
YasitoandWeblate a6eea3198a Translated using Weblate (French)
Currently translated at 99.6% (8989 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:38:19 +00:00
YasitoandWeblate b28e2313a8 Translated using Weblate (French (Canada))
Currently translated at 99.6% (8988 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-02 20:38:19 +00:00
LucasandWeblate 0f0b4e6c86 Translated using Weblate (French)
Currently translated at 99.6% (8988 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:37:45 +00:00
YasitoandWeblate e033467054 Translated using Weblate (French)
Currently translated at 99.6% (8988 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:37:45 +00:00
YasitoandWeblate 0f092bf6bf Translated using Weblate (French (Canada))
Currently translated at 99.6% (8987 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-02 20:37:44 +00:00
LucasandWeblate 66ba762360 Translated using Weblate (French)
Currently translated at 99.6% (8987 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:37:01 +00:00
YasitoandWeblate c7c11838a0 Translated using Weblate (French)
Currently translated at 99.6% (8987 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2026-01-02 20:37:01 +00:00
YasitoandWeblate 301d80fabe Translated using Weblate (French (Canada))
Currently translated at 99.6% (8986 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2026-01-02 20:37:00 +00:00
Hiroku c88087de29 Merge branch 'main' into 'main'
Small improvements to the Battle AI

See merge request cable-mc/cobblemon!2101
2026-01-02 00:38:26 +00:00
Konoha fade5502d9 molang additions: Move struct accessor and player inventory utils 2026-01-01 15:31:40 -05:00
Konoha 86bb802140 adjustment: exception handling to run_molang 2026-01-01 11:44:29 -05:00
GGavino1 6b644b384d Updated CHANGELOG.md to include AI changes 2026-01-01 15:00:15 +00:00
Konoha c370af8914 feature: molang function for safe evaluation of booleans 2025-12-31 22:23:50 -05:00
GGavino1 1cd6d2bfc7 Edit StrongBattleAI.kt 2025-12-31 23:15:52 +00:00
Paul 6c5fd6ea1c Added draft of new AI system 2025-12-31 23:00:10 +10:00
Test fc720916fb wall block properties 2025-12-31 00:24:39 -05:00
Jerzykv ce55035408 changelog 2025-12-30 14:46:38 +01:00
Jerzykv d4665ddaeb implemented Falinks remodel 2025-12-30 14:44:46 +01:00
Jerzykv 4375c6f667 fixed Revavroom's hitbox. Who implemented this guy (it was me) 2025-12-30 14:43:24 +01:00
Konoha 1edeae2a60 fix: let's actually fix 2025-12-27 09:48:49 -05:00
mkh 409f1056b9 fix: Add MongoDB driver dependency to Fabric/NeoForge build configuration and shade it into the mod jar to resolve ClassNotFoundException. 2025-12-26 17:31:46 +08:00
Landon Wills d8c470db3d Oops, forgot a file 2025-12-23 01:28:50 -05:00
Landon Wills c642c4b84b Update changelog 2025-12-23 01:22:01 -05:00
Landon Wills 0b80f7e547 Make the gimmick buttons work with the back button 2025-12-23 01:18:35 -05:00
Landon Wills d543f45607 Fix double battle gimmicks not being processed, prevent people from trying to use the same gimmick multiple times on the same turn 2025-12-23 00:43:31 -05:00
Test e5699c1cdc plaques, policies 2025-12-22 01:34:10 -05:00
RedGenesectNinja f4a7c6e873 Implemented the remodels for Chingling and Chimecho 2025-12-21 22:40:17 -06:00
Konoha 2b4fdfd219 changelog: sanitization fix 2025-12-21 15:40:17 -05:00
geumuandWeblate 3bef1dad4a Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-20 19:34:20 +00:00
geumuandWeblate da50ee59cf Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-20 14:40:56 +00:00
Hiroku 1a3b655d3f Merge branch 'the-tiniest-of-tiny-changes' into 'main'
Edit pokemon_model.json

See merge request cable-mc/cobblemon!2091
2025-12-20 12:41:36 +00:00
dhi_holo 1f5f278970 Edit pokemon_model.json 2025-12-20 21:25:12 +10:00
Hiroku 0b4eb5239a Merge branch 'in-flight-dismounting-config' into 'main'
Add enable in-flight dismounting config

See merge request cable-mc/cobblemon!2079
2025-12-20 06:01:12 +00:00
lionandHiroku 118e8f6205 Add enable in-flight dismounting config 2025-12-20 06:01:12 +00:00
Hiroku cf126c5906 Merge branch 'molang-is-love-molang-is-life' into 'main'
Fixed the `run_script` Molang function to not fail if the environment's context is null.

See merge request cable-mc/cobblemon!2090
2025-12-20 01:59:22 +00:00
Spicy 645cf61911 Fixed the run_script Molang function to not fail if the environment's context is null. 2025-12-19 19:48:27 -06:00
arvid6andWeblate 6e8985d97e Translated using Weblate (Spanish)
Currently translated at 84.2% (7599 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-12-19 08:15:16 +00:00
geumuandWeblate 19c4c0d50d Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-19 08:15:15 +00:00
阿鱼andWeblate b23110950e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-12-19 08:15:14 +00:00
Watuneni iteiteandWeblate 60c213c44b Translated using Weblate (Japanese)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-12-19 08:15:13 +00:00
Hiroku 87d5ede3dd Merge branch 'RestoreCombeeLeavesPathing' into 'main'
RestoreCombeeLeavesPathing

See merge request cable-mc/cobblemon!2046
2025-12-19 07:36:50 +00:00
Hiroku 203e5d89cd Merge branch 'label-consistency' into 'main'
Who are we if not consistent?

See merge request cable-mc/cobblemon!1985
2025-12-19 07:36:21 +00:00
Konoha ce611cc61c cleanup: fix redundancies in form change sanitization 2025-12-18 21:17:48 -05:00
geumuandWeblate 3df8dea71b Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-18 17:09:19 +00:00
geumuandWeblate 3cca50b7cc Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-18 07:49:53 +00:00
geumuandWeblate 1ff5622694 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-18 06:01:40 +00:00
JazzMcNade f6ad7ff865 Fix changelog 2025-12-17 21:08:46 -06:00
JazzMcNade d69627a9c8 Merge branch 'main' into CombeeWorldGenFix 2025-12-17 20:05:09 -06:00
Alexis SalgueiroandWeblate 411f388bd3 Translated using Weblate (French)
Currently translated at 99.5% (8984 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-12-18 00:21:32 +00:00
geumuandWeblate 5b8d35604a Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-18 00:21:30 +00:00
geumuandWeblate 619d002bc4 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-17 07:19:25 +00:00
geumuandWeblate 7049656f64 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-16 06:33:05 +00:00
geumuandWeblate e6e7c2982d Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-15 12:47:01 +00:00
JazzMcNade 54e8763470 Fixed a bug in which Combees could become stuck inside of leaves 2025-12-13 21:17:59 -06:00
JazzMcNade db34687df0 Merge branch 'main' into RestoreCombeeLeavesPathing 2025-12-13 21:11:57 -06:00
Konoha 7f008d85ff fix: form_change move updates no longer sanitize the sets of compounding property mons 2025-12-13 18:37:37 -05:00
Polymeta 06ebf51078 Merge branch 'Wii-Break-It-Wii-Fix-It' into 'main'
Boat Tags and Mint Leaves

Closes #1855

See merge request cable-mc/cobblemon!2082
2025-12-13 22:14:32 +00:00
Polymeta 39c5bcd73c Merge branch 'even-more-seasonings' into 'main'
Adding Missing Effects for Seasonings

See merge request cable-mc/cobblemon!1991
2025-12-13 22:13:24 +00:00
CeejayandPolymeta 8f5f158b60 Adding Missing Effects for Seasonings 2025-12-13 22:13:24 +00:00
dhi_holo 3bc1e35125 Update CHANGELOG.md 2025-12-13 18:42:50 +10:00
dhi_holo 460bedddae Boat Tags
Resolves #1855
2025-12-13 18:12:24 +10:00
dhi_holo 8b64c315f3 Merge branch 'main' into Wii-Break-It-Wii-Fix-It 2025-12-13 17:51:15 +10:00
dhi_holo 7c824a2b72 OVERSIGHTS 2025-12-13 17:50:57 +10:00
Paul f197ac5077 Removed a bunch of duplicates from is_held_item because it looks whack. 2025-12-12 16:24:30 +10:00
Hiroku e0be669482 Merge branch 'patch-1' into 'main'
Fix Soothe Bell not tagged as `cobblemon:held/is_held_item`

See merge request cable-mc/cobblemon!2081
2025-12-12 06:17:17 +00:00
Watuneni iteiteandWeblate 82686b0511 Translated using Weblate (Japanese)
Currently translated at 99.4% (8976 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-12-12 03:20:38 +00:00
JPAKx4 f4eca30163 Fix merge issues 2025-12-11 10:40:53 -06:00
arvid6andWeblate 2814183012 Translated using Weblate (Spanish)
Currently translated at 84.2% (7597 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-12-11 16:38:11 +00:00
JPAKx4 bbc3c2a8d6 Merge branch 'main' into default-offest
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/camera/MountedCameraRenderer.kt
2025-12-11 10:27:50 -06:00
geumuandWeblate 7eeb7feeae Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-11 06:27:41 +00:00
geumuandWeblate b2f850c1c8 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-10 15:57:39 +00:00
Micky 08ea21fff4 Fix Soothe Bell not tagged as cobblemon:held/is_held_item 2025-12-10 13:27:23 +00:00
JazzMcNade 9dac604a93 Merge branch 'main' into RestoreCombeeLeavesPathing 2025-12-10 00:20:49 -06:00
Nico MerenqandWeblate 23db346070 Translated using Weblate (Russian)
Currently translated at 77.7% (7012 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-12-09 19:49:13 +00:00
geumuandWeblate d3b7d739bb Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-09 19:49:11 +00:00
Polymeta 28c0f8ab7d Merge branch 'item-interactions-sync' into 'main'
Item interactions sync

See merge request cable-mc/cobblemon!2068
2025-12-08 16:08:48 +00:00
lionandPolymeta fcbe0db568 Item interactions sync 2025-12-08 16:08:48 +00:00
Polymeta 83cefe476e Merge branch 'partner-mark' into 'main'
Add Partner Mark

See merge request cable-mc/cobblemon!2034
2025-12-08 15:57:21 +00:00
Guilherme Pereira 690ccbd260 refactor check riding statistics method for server player mixin 2025-12-08 12:06:20 -03:00
Polymeta 63846d53fb Merge branch 'main' into 'main'
Fixed shiny Pokémon not respecting the silent flag on spawn.

See merge request cable-mc/cobblemon!2064
2025-12-08 13:07:25 +00:00
Polymeta 86cb865742 fixed mochi items being consumed twice
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-12-08 13:01:14 +00:00
Polymeta 1a0c9b6a82 Merge branch 'malformed-jsons-no-more' into 'main'
Fixes a crash caused by malformed riding prespectives json file when trying to ride a pokemon

See merge request cable-mc/cobblemon!2077
2025-12-08 12:59:22 +00:00
Polymeta 985eb103fe Merge branch 'sterr/ride-sound-changes' into 'main'
New ride sound stuff

See merge request cable-mc/cobblemon!2065
2025-12-08 11:44:22 +00:00
Polymeta aec76a78da Merge branch 'restore_adorn_texturing' into 'main'
Restore adorn texturing

Closes #1833

See merge request cable-mc/cobblemon!2078
2025-12-08 11:36:41 +00:00
geumuandWeblate eb6c134f4b Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-08 10:48:16 +00:00
Jacob Hartmann 17f3edf2be Changelog 2025-12-07 20:35:11 -07:00
Jacob Hartmann 9c5bfda20f Updating texture paths 2025-12-07 20:34:09 -07:00
geumuandWeblate aa0b8d88e8 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-07 12:09:09 +00:00
Gertimoshka 6d545fc1ca Fixes a crash caused by malformed riding prespectives json file when trying to ride a pokemon 2025-12-07 11:47:04 +02:00
Polymeta 9a8ad27122 Merge branch 'fix-spectator-crash' into 'main'
fix spectator crash

Closes #1847

See merge request cable-mc/cobblemon!2076
2025-12-07 08:39:18 +00:00
500-internal-server-error 9f1dbc9ff0 add notes to changelog 2025-12-07 07:58:55 +07:00
Polymeta 99942748b0 Merge branch 'entropydragon--spawn-bait-regional-forms' into 'main'
fix: use regional form data for spawn bait influence

See merge request cable-mc/cobblemon!2074
2025-12-07 00:49:48 +00:00
jasoncramer 64c34230bf chore: add to changelog 2025-12-06 19:28:41 -05:00
500-internal-server-error 36881b70be fix spectator crash 2025-12-06 20:51:48 +07:00
Deltric 3cf9425247 Fixed memory leak from battles not being cleaned up after ending. 2025-12-06 01:35:53 -06:00
jasoncramer 9b052478f6 fix: use regional form data for spawn bait influence 2025-12-05 14:23:05 -05:00
Hiroku 339f8339f0 Merge branch 'RestorePokemonItemPickup' into 'main'
Restore Pokemon item pickup

See merge request cable-mc/cobblemon!2073
2025-12-05 08:19:41 +00:00
Hiroku db9a802c3f Merge branch 'fix-spawner-crash' into 'main'
Prevents outside spawn influences from crashing the logical server.

See merge request cable-mc/cobblemon!2072
2025-12-05 07:45:29 +00:00
Carmendar b5578e72bd Merge branch 'main' into implement_pokemon 2025-12-05 01:30:51 -06:00
JazzMcNade e5666e7a82 Restore Pokemon item pickup. Remove unnecessary check in shouldBeSaved() 2025-12-05 01:30:20 -06:00
Carmendar 3aea0909a4 Merge branch 'main' into implement_pokemon 2025-12-05 01:27:25 -06:00
TeggyandWeblate 5adef3336e Translated using Weblate (Spanish)
Currently translated at 84.2% (7597 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-12-05 06:23:53 +00:00
geumuandWeblate 1a96b418bc Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-05 06:23:51 +00:00
geumuandWeblate e373e86b60 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-04 15:33:38 +00:00
geumuandWeblate 6f3035184c Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-04 09:30:13 +00:00
Jerzykv 7ae8b1957c fixed Arcanine's texture having a line 2025-12-04 10:27:42 +01:00
Neovitalism a588213323 Update CHANGELOG.md 2025-12-04 03:05:03 -06:00
Neovitalism 56b2ba08ad Prevents outside influences from crashing the logical server.
Before when it was completed exceptionally w/ the pokesnack spawner, it would crash the server.
2025-12-04 03:03:57 -06:00
geumuandWeblate 824b9718ee Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-04 08:07:32 +00:00
JazzMcNade 8540a73885 Fix for error occurring while populating bee nests with pokemon on world gen 2025-12-04 01:38:56 -06:00
Khvrram 7e6ca7be5e Merge branch cobblemon:main into main 2025-12-04 01:59:17 +00:00
geumuandWeblate ef43f6c087 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-03 21:23:55 +00:00
geumuandWeblate c8a70caf79 Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-03 16:30:22 +00:00
Neovitalism 25ce784a60 Hopefully fixes changelog
Idk why gitlab didn't detect that when merging main
2025-12-03 10:17:48 -06:00
Neovitalism 5358cccb62 Merge branch 'main' into label-consistency 2025-12-03 10:09:41 -06:00
geumuandWeblate ba11758e1f Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-03 12:53:16 +00:00
geumuandWeblate f0412d6b1d Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-03 10:05:08 +00:00
Polymeta c43b3bbb4d Merge branch 'fix-can-drop-held-item' into 'main'
Fix can drop held item function

See merge request cable-mc/cobblemon!2069
2025-12-03 08:17:38 +00:00
lionandPolymeta d826aeeb07 Fix can drop held item function 2025-12-03 08:17:35 +00:00
Polymeta f90c6967ce Merge branch 'FixHoneyedLeavesInteraction' into 'main'
FixHoneyedLeavesInteraction

Closes #1832

See merge request cable-mc/cobblemon!2067
2025-12-03 08:15:26 +00:00
Jerzykv f5f87ce1a3 fixed Dewgong swimming in battle 2025-12-03 06:57:40 +01:00
Jerzykv f28b269734 fixed Camerupt jumping in battle 2025-12-03 06:57:31 +01:00
Jerzykv d545efd843 adjusted Tinkaton & Tinkatuff profile scaling 2025-12-03 06:57:07 +01:00
JazzMcNade b9cf18adbd Changelog 2025-12-02 20:16:56 -06:00
JazzMcNade 30650e1f9f Code simplication 2025-12-02 20:12:37 -06:00
JazzMcNade eaa558a7c8 Check for creative on using empty bottle 2025-12-02 00:36:53 -06:00
JazzMcNade 0dc725e513 Can only receive honey at max age. Adds result to hand if possible. Checks for creative and server/client 2025-12-02 00:28:23 -06:00
Zack the GhastandWeblate f8682c2123 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.2% (8866 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-12-02 05:47:12 +00:00
geumuandWeblate f62e31a1eb Translated using Weblate (Korean)
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-02 05:46:50 +00:00
Watuneni iteiteandWeblate ea623b08a6 Translated using Weblate (Japanese)
Currently translated at 99.4% (8971 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-12-02 05:46:48 +00:00
Sterrezo a575c6bc3d Update CHANGELOG.md 2025-12-01 15:47:34 +01:00
Sterrezo 9c102a7850 Merge branch 'main' into sterr/ride-sound-changes 2025-12-01 15:45:40 +01:00
Sterrezo 22a1eaab19 Volume balancing 2025-12-01 15:35:22 +01:00
Sterrezo 0118ace5fc Implemented stereo flight loops 2025-12-01 15:09:37 +01:00
Sterrezo d4a93abbf7 Added support for submerged ride sounds 2025-12-01 14:27:55 +01:00
geumuandWeblate ce3d5a413c Translated using Weblate (Korean)
Currently translated at 95.8% (8650 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-01 13:03:30 +00:00
Sterrezo d0ee3f3e9d Added an option for ride sounds to not play for the passengers 2025-12-01 13:56:56 +01:00
JazzMcNade 698fa9dff9 Merge branch 'main' into RestoreCombeeLeavesPathing 2025-12-01 00:46:50 -06:00
geumuandWeblate d23fd6e23c Translated using Weblate (Korean)
Currently translated at 84.1% (7595 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-12-01 05:33:07 +00:00
Khvrram 46ae53f565 Merge branch cobblemon:main into main 2025-12-01 04:25:52 +00:00
Hiroku 7d4e5892ba Merge branch 'main' into 'main'
Orientation after crash fix

See merge request cable-mc/cobblemon!2061
2025-12-01 00:23:40 +00:00
KhvrramandHiroku f9de415020 Orientation after crash fix 2025-12-01 00:23:39 +00:00
geumuandWeblate 59395a254d Translated using Weblate (Korean)
Currently translated at 81.2% (7328 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-30 20:59:27 +00:00
geumuandWeblate 5d7c6c8d6f Translated using Weblate (Korean)
Currently translated at 80.6% (7276 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-30 08:10:30 +00:00
Khurram Valiyev 4d123b6e4b Fixed shiny Pokémon not respecting the silent flag on spawn. 2025-11-29 22:50:52 -05:00
Polymeta 54dc2e7f6f tidy up changelog [skip-ci] 2025-11-29 12:57:24 +00:00
Polymeta 1d60ba093f Merge branch 'convention-tags-not-being-consistent-grrrrrrrr' into 'main'
Why

See merge request cable-mc/cobblemon!2060
2025-11-29 11:53:50 +00:00
Hiroku 0fef74dce7 Edit OneToOneFileStoreAdapter.kt 2025-11-29 09:46:27 +00:00
violet 6529293d21 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-29 02:44:47 -05:00
violet a1fce624ea something was forgotten in the changelog... 2025-11-29 02:44:34 -05:00
Hiroku b08647bb32 Revert "Merge branch 'main' into 'main'"
This reverts merge request !2062
2025-11-29 04:26:57 +00:00
Hiroku de9e89f040 Merge branch 'main' into 'main'
Editar en_us.json

See merge request cable-mc/cobblemon!2062
2025-11-29 04:25:10 +00:00
Ezequiel Neri Ferreira 84a29ebc2a Editar en_us.json 2025-11-29 04:22:49 +00:00
Paul 37b13ae959 Unsnaps your shot 2025-11-29 12:44:40 +10:00
dhi_holo 1cacbe8306 Why
It's called Shears, that's the item name, why does NeoForge use a Shear tag instead
Atleast Fabric has that tag as well so it's not a hard fix
2025-11-29 12:30:45 +10:00
Paul 12d224d15a Reinforce switchForm for crashes 2025-11-29 11:25:58 +10:00
Paul a57eee3afc Changelog updates [skip-ci] 2025-11-29 10:46:19 +10:00
geumuandWeblate b7773f7471 Translated using Weblate (Korean)
Currently translated at 79.1% (7144 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-28 23:27:54 +00:00
Hiroku 57595c999c Merge branch 'remove-snapshot' into 'main'
Remove snapshot for release

See merge request cable-mc/cobblemon!2059
2025-11-28 23:24:59 +00:00
Landon Wills 83615b7eb3 Prepare release 2025-11-28 17:54:24 -05:00
Polymeta c53c544a8b Merge branch 'implement_pokemon' into 'main'
Last minute changes

See merge request cable-mc/cobblemon!2058
2025-11-28 22:23:03 +00:00
Kenji_64 c7c272c79c Had to fix Dragapult (again) 2025-11-28 21:04:50 +01:00
Kenji_64 c759161367 Added cries to Eelektrik and Eelektross 2025-11-28 21:01:27 +01:00
Landon 19b7b4804f Merge branch 'add-defend-owner-task' into 'main'
Make Pokémon only attack mobs targeting the player

See merge request cable-mc/cobblemon!2051
2025-11-28 18:30:05 +00:00
Landon 3a005cc813 Merge branch '1.7.1-spawns' into 'main'
Updated Dratini line spawns.

See merge request cable-mc/cobblemon!2055
2025-11-28 18:28:24 +00:00
Landon a8e16efa48 Merge branch 'jet-handling' into 'main'
Increase pitch rotation of Jet

See merge request cable-mc/cobblemon!2054
2025-11-28 18:08:20 +00:00
Veraxiel c3ddfce0a7 Updated Dratini spawn. 2025-11-28 12:38:53 -05:00
Landon Wills 9500f7a1f3 adjust wording 2025-11-28 12:21:44 -05:00
Landon Wills 83a8d92e3f Add changelog 2025-11-28 12:21:08 -05:00
Landon Wills e105c5d4d7 Remove multipliers, adjust expression 2025-11-28 12:17:42 -05:00
Landon Wills 3d816f57e2 Increase pitch rotation of Jet 2025-11-28 12:13:55 -05:00
Landon 1e6dcfba9b Merge branch 'change-freelook-default' into 'main'
Change free look binding default to Left Alt

See merge request cable-mc/cobblemon!2053
2025-11-28 16:30:35 +00:00
Polymeta e59d755d32 Merge branch 'implement_pokemon' into 'main'
Various implementation fixes

See merge request cable-mc/cobblemon!2050
2025-11-28 15:38:40 +00:00
geumuandWeblate f927e47bfe Translated using Weblate (Korean)
Currently translated at 77.9% (7030 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-28 15:25:08 +00:00
Watuneni iteiteandWeblate 48a37b2018 Translated using Weblate (Japanese)
Currently translated at 99.2% (8953 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-28 15:25:07 +00:00
Guilherme Pereira c155b5575d change free look binding default to left alt 2025-11-28 09:35:13 -03:00
Jerzykv 9c6b8b231a oops 2 2025-11-28 13:30:16 +01:00
Jerzykv 92b404dac4 oops 2025-11-28 13:27:19 +01:00
Jerzykv 8a1c536d68 Fixed Furfrou's pink and magenta trims being swapped 2025-11-28 12:56:07 +01:00
Jerzykv 04719d22a5 Fixed a tiny issue with Ceruledge's poser 2025-11-28 12:55:54 +01:00
Jerzykv dacc312756 Implemented Tinkatink line remodels 2025-11-28 12:55:26 +01:00
Polymeta ee4a3d46ba Merge branch '1.7.1-spawns' into 'main'
Updated some spawns.

See merge request cable-mc/cobblemon!2052
2025-11-28 09:31:16 +00:00
violet 80b11f1c3d Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-28 01:20:00 -05:00
Carmendar ddcf4eea7b Heracross and Mudsdale jump fix. 2025-11-28 00:16:50 -06:00
violet 6a0681e4c6 fixed cyclizar's textures 2025-11-27 23:37:39 -05:00
Veraxiel 8ebb378da7 Updated some spawns. 2025-11-27 23:31:32 -05:00
violet e92a878074 fixed boltund's model 2025-11-27 23:30:22 -05:00
Paul 0b97b41c08 Merge remote-tracking branch 'origin/main' 2025-11-28 12:27:10 +10:00
Paul 20fe732cfc Potentially minor perf improvement on following walk targets that are unreachable 2025-11-28 12:26:26 +10:00
Carmendar 0575aa29d9 Doubled high end land mount stamina. 2025-11-27 18:43:20 -06:00
Guilherme Pereira 29b560d244 Merge branch 'main' of gitlab.com:cable-mc/cobblemon into partner-mark 2025-11-27 18:21:19 -03:00
Guilherme Pereira dcc98b4a54 rename mob to living entity 2025-11-27 18:19:49 -03:00
Guilherme Pereira d3ce455391 prevents defend owner task from targeting players 2025-11-27 18:10:59 -03:00
Kenji_64 85c6b633d8 Fixed Dragapult's eyes clippings 2025-11-27 22:03:48 +01:00
Guilherme Pereira 956b599060 update CHANGELOG.md 2025-11-27 17:51:11 -03:00
Jerzykv f88552f99b Gholdengo no longer dances in air. what a shame (fixed flying battle pose issue) 2025-11-27 21:46:35 +01:00
Carmendar e2b559f3eb Merge branch 'main' into implement_pokemon 2025-11-27 14:42:31 -06:00
Carmendar 39816d33b6 Rufflet eepy cry and battle pose fix 2025-11-27 14:38:39 -06:00
Landon 0cf2a23fd4 Merge branch 'cobble-land-fixes' into 'main'
Land adjustments for a smoother riding experience. And bug fixes to land rides

See merge request cable-mc/cobblemon!2039
2025-11-27 19:31:24 +00:00
Guilherme Pereira c4d8eae47e add defend owner task once again 2025-11-27 12:16:54 -03:00
Polymeta 2a5a292386 fix saccharine hanging signs sometimes dropping oak wood signs
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-27 11:27:58 +00:00
阿鱼andWeblate f6b2da6ed6 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (9022 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-27 11:09:47 +00:00
Polymeta e8a09f5c48 Merge branch 'json-fixing' into 'main'
JSON Fixes

Closes #1819

See merge request cable-mc/cobblemon!2048
2025-11-27 10:42:07 +00:00
dhi_holo e82193cdfd Update interact_with_pokemon.json
Removed accidental flag
2025-11-27 19:56:33 +10:00
dhi_holo 87e7cdebf6 Fabric Tags that aren't true c tags are the bane of my existence
Fixed the concrete tags to behave properly, changelog
2025-11-27 15:25:53 +10:00
dhi_holo 9ca84d852f Update interact_with_pokemon.json
Should close #1819
2025-11-27 14:22:06 +10:00
Carmendar 8194f93d13 Merge branch 'main' into implement_pokemon 2025-11-26 20:54:41 -06:00
Carmendar c158ec33fa Braviary sleep cry fix 2025-11-26 20:53:46 -06:00
Carmendar 1e27c7494e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-26 20:52:27 -06:00
Carmendar 54a1f8d932 Braviary battle pose fix 2025-11-26 20:51:45 -06:00
Watuneni iteiteandWeblate 275779b20e Translated using Weblate (Japanese)
Currently translated at 99.2% (8953 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-26 22:24:14 +00:00
Polymeta 635f29e1ac fix glass bottle not being returned when using honey on saccharine leaves
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-26 22:08:12 +00:00
Polymeta db2001b60a Merge branch 'attempted-jvm-fix' into 'main'
Fixed JVM crash from campfire pot

Closes #1795

See merge request cable-mc/cobblemon!2040
2025-11-26 21:40:30 +00:00
HirokuandPolymeta b5098a2ad0 Fixed JVM crash from campfire pot 2025-11-26 21:40:29 +00:00
阿鱼andWeblate 2102f8ff88 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.6% (8991 of 9022 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-26 15:42:52 +00:00
Kenji_64 d2af0c9332 Fixed Swampert line's missing recoils crashing the game 2025-11-26 15:40:40 +01:00
Polymeta 8c939ee276 Merge branch 'lets-wind-down' into 'main'
Fixes wind charges recalling pastured pokémon

Closes #1805

See merge request cable-mc/cobblemon!2042
2025-11-26 13:27:12 +00:00
NeovitalismandPolymeta 645b8993c8 Fixes wind charges recalling pastured pokémon 2025-11-26 13:27:12 +00:00
Polymeta d96799cac7 Merge branch 'feature/neoforge-recipe-book' into 'main'
split recipebooktype and category across fabric and neoforge so we can leverage neoforge APIs

Closes #1789 and #1787

See merge request cable-mc/cobblemon!2044
2025-11-26 12:44:06 +00:00
Polymeta b822b626c4 split recipebooktype and category across fabric and neoforge so we can leverage neoforge APIs 2025-11-26 12:44:05 +00:00
Polymeta 4d9b182fb3 fix hearty grains crashing if a block is in the way
Closes #1818

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-26 11:59:25 +00:00
Polymeta 88d155eaf4 [skip-ci] more changelog
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-26 11:33:57 +00:00
Paul af96469b7a changelog [skip-ci] 2025-11-26 21:17:15 +10:00
Paul 65f1e7a3be Merge remote-tracking branch 'weblate/lang-updates' 2025-11-26 21:14:31 +10:00
Kenji_64 379a566d71 Fixed Ditto being silent 2025-11-26 11:52:43 +01:00
Kenji_64 f30ff739ed Fixed Metagross' ground_idle not looping properly (again) >:( 2025-11-26 11:36:23 +01:00
阿鱼andWeblate 16cd2de02f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.4% (8973 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-26 10:03:51 +00:00
Polymeta 22a44bd7e9 Merge branch 'ImprovedPastureBees' into 'main'
Improved Pasture Combees and More

See merge request cable-mc/cobblemon!2043
2025-11-26 09:36:28 +00:00
Polymeta d37bd4ef03 Merge branch 'OmnipathNavigationCrashFix' into 'main'
OmnipathNavigationCrashFix

See merge request cable-mc/cobblemon!2045
2025-11-26 09:34:03 +00:00
Hiroku a3d9a10f2e Merge branch 'wallpaper' into 'main'
Remove auto generated screen glow due to rendering issues

See merge request cable-mc/cobblemon!2047
2025-11-26 08:48:00 +00:00
Test 7801e3feee changelog clarification [skip-ci] 2025-11-26 04:56:10 +00:00
Test 4a54cb4674 remove auto generated screen glow 2025-11-26 04:38:14 +00:00
JazzMcNade a8949cf1f9 changelog 2025-11-25 21:49:38 -06:00
JazzMcNade 24fe1c125c changelog 2025-11-25 21:47:45 -06:00
JazzMcNade 61db6334f9 Restores Combee pathing through leaves 2025-11-25 21:37:57 -06:00
JazzMcNade 023160f87a Removed a really silly cast 2025-11-25 21:32:17 -06:00
RedGenesectNinja c45e34648c Fixed Toedscool and Toedscruel's hitboxes being too small 2025-11-25 18:53:12 -06:00
Polymeta 17fbf7c6f0 defensive pokemon casts as NPCs use this too
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-25 16:53:26 +00:00
Polymeta ec86b7d4bf fix tag reference
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-25 15:18:09 +00:00
阿鱼andWeblate 7561eb116f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.3% (8960 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-25 14:20:09 +00:00
Polymeta 6467b97a23 Merge branch 'implement_pokemon' into 'main'
marked furfrou as implemented

See merge request cable-mc/cobblemon!2041
2025-11-25 12:16:02 +00:00
JazzMcNade 6d5909a1e3 Added rain clause, do not attempt to enter a full hive, changelog 2025-11-25 02:17:28 -06:00
JazzMcNade 2bb0d43ca8 Fix wandering for pastured bees, fix hoverpos not being cleared 2025-11-25 00:51:04 -06:00
Watuneni iteiteandWeblate 1fb3f0ebdc Translated using Weblate (Japanese)
Currently translated at 99.2% (8954 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-25 06:46:07 +00:00
jackowes d56586ecac - Fix walking animation issues 2025-11-24 21:39:36 -06:00
violet fb2154e2c3 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-24 22:06:34 -05:00
violet 3b14d19fdb marked furfrou as implemented 2025-11-24 22:06:22 -05:00
Carmendar 6840c2fdef Merge branch 'main' into implement_pokemon 2025-11-24 17:28:35 -06:00
阿鱼andWeblate 8fc2031806 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.2% (8954 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-24 21:23:59 +00:00
jackowes 9df8be33e9 - revert a bad change 2025-11-24 14:51:33 -06:00
Alexis SalgueiroandWeblate 4795e2e1bc Translated using Weblate (French)
Currently translated at 99.6% (8984 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-11-24 11:22:45 +00:00
Carmendar c563627b05 Shiny female Combee is now actually shiny. 2025-11-24 02:31:25 -06:00
violet 73ebf7a789 tiny typo fix 2025-11-24 03:18:38 -05:00
Landon a1b3d3d2ca Merge branch 'lets-be-friends-again' into 'main'
Move friendship logic to spawn action

See merge request cable-mc/cobblemon!2037
2025-11-24 06:50:24 +00:00
lionandLandon 8baacbcf90 Move friendship logic to spawn action 2025-11-24 06:50:23 +00:00
Hiroku f2e357b749 Merge branch 'pc-crash-fix' into 'main'
Fix PC crash with VulkanMod

Closes #1793

See merge request cable-mc/cobblemon!2038
2025-11-24 04:28:32 +00:00
jackowes ff2afd546e changelog 2025-11-23 21:50:30 -06:00
Test b95900b29a Fix PC crash with VulkanMod 2025-11-23 22:39:28 -05:00
jackowes b8b7756a45 - Add double tap to sprint on land mounts
- Adjust step up in air and on ground to reflect vanilla behaviour
- Fix inAir check so pose does not change back to walking or running while in air
2025-11-23 21:29:30 -06:00
jackowes 3d6146f551 - Add double tap to sprint on land mounts.
- Adjust step up in air and on ground to reflect vanilla behaviour
2025-11-23 21:15:41 -06:00
Hiroku 03585fafb0 Merge branch 'HoneyIForgotTheNectar' into 'main'
Don't Forget the Nectar

See merge request cable-mc/cobblemon!2031
2025-11-24 01:38:14 +00:00
jackowes 31d81db243 Merge branch 'main' into cobble-land-fixes 2025-11-23 18:19:51 -06:00
jackowes 4c36db8685 - Fix ridden pokemon land collision and weird step up issues. Horse is smoother overall now.
- Change the turnrate debuff to be squareroot instead of linear.
- Accel stat does not affect land ridden mounts walks.
- Add vanilla sprinting fov to pokemon land mounts
2025-11-23 18:19:13 -06:00
washashu0905andWeblate e3d0252d75 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 94.4% (8519 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-11-24 00:10:57 +00:00
阿鱼andWeblate dbe8e57341 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.2% (8950 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-24 00:10:56 +00:00
Zack the GhastandWeblate 6f37fd69cd Translated using Weblate (Portuguese (Brazil))
Currently translated at 97.4% (8791 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-11-24 00:10:55 +00:00
JazzMcNade b191f4e9fb Check hivecooldown memory registration 2025-11-23 15:42:56 -06:00
Hiroku a5a7cc20ba Merge branch 'eating-cough-drops' into 'main'
Throat Spray Recipe

See merge request cable-mc/cobblemon!2036
2025-11-23 11:48:00 +00:00
Polymeta 02b6c46082 [skip-ci] 1.7 tag doc files
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-23 11:39:39 +00:00
dhi_holo 881a30cca4 Merge branch 'main' into eating-cough-drops 2025-11-23 20:33:20 +10:00
dhi_holo d01011f4d0 Throat Spray Recipe
This either was lost at some point or never existed in the mod, I'm not sure which. It's here now!
2025-11-23 20:32:21 +10:00
Landon 309ed379c7 Merge branch 'AAAAAAAAAAAAAAAAAAAAA' into 'main'
unfudge camera maybe please

See merge request cable-mc/cobblemon!2030
2025-11-23 10:30:50 +00:00
Landon Wills edbf667f45 Add changelog 2025-11-23 04:44:02 -05:00
Landon Wills b6bc766adf Merge branch 'main' into AAAAAAAAAAAAAAAAAAAAA 2025-11-23 04:42:52 -05:00
Test 1ecf556cf2 Merge branch 'nom' into 'main'
Small Fixes

See merge request cable-mc/cobblemon!2035
2025-11-23 03:46:33 +00:00
dhi_holo 6d32073604 Small Fixes
- Ponigiri can no longer be eaten at full hunger
- Medicinal Brew's Campfire Pot recipe now correctly displays that it can be made using an empty glass bottle or a filled bottle
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader
- Reduced cost of the Vivichoke Seed trade with the Wandering Trader
2025-11-23 12:45:18 +10:00
Guilherme Pereira 7cedfb9047 update CHANGELOG.md 2025-11-22 22:02:14 -03:00
Guilherme Pereira a7ab2e37c2 Merge branch 'main' of gitlab.com:cable-mc/cobblemon into partner-mark 2025-11-22 21:57:49 -03:00
Guilherme Pereira 4723f91500 add riding stats 2025-11-22 21:57:25 -03:00
Hiroku aa0f5d8a05 Merge branch 'vanilla-ride-fix-and-misc-ride-fixes' into 'main'
Fix vanilla rides suffocating players and misc cobble riding fixes

See merge request cable-mc/cobblemon!2033
2025-11-22 23:50:31 +00:00
jackowes 6202c14215 - changelog update 2025-11-22 16:42:20 -06:00
Guilherme Pereira e23aa6b066 add partner mark molang callback 2025-11-22 19:39:21 -03:00
Hiroku b0790341c7 Merge branch 'some-fixes' into 'main'
Some fixes

See merge request cable-mc/cobblemon!2032
2025-11-22 22:36:17 +00:00
jackowes 4f0fa6af4a - Fix horse player suffocation on vanilla mounts
- stop passengers from hearing the shiny noise of a ridden shiny pokemon.
- Convert the riding freelook button to a configurable keybinding

(cherry picked from commit 6432db9f7d)
2025-11-22 16:24:25 -06:00
JazzMcNade 4e24e09924 Safer memory reading in hive occupant mixins 2025-11-22 16:19:30 -06:00
jackowes 48676067b7 Revert "- Fix horse player suffocation on vanilla mounts"
This reverts commit 6432db9f7d.
2025-11-22 16:16:17 -06:00
jackowes 6432db9f7d - Fix horse player suffocation on vanilla mounts
- stop passengers from hearing the shiny noise of a ridden shiny pokemon.
- Convert the riding freelook button to a configurable keybinding
2025-11-22 16:13:47 -06:00
Test 2cb28fb384 rm unused imports 2025-11-22 12:57:59 -05:00
JazzMcNade 3b59148151 changelog again 2025-11-22 11:43:44 -06:00
JazzMcNade d6198631ba New Changelog 2025-11-22 11:40:03 -06:00
geumuandWeblate 47daea6195 Translated using Weblate (Korean)
Currently translated at 75.6% (6826 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-22 17:37:36 +00:00
Watuneni iteiteandWeblate aca66a4bb0 Translated using Weblate (Japanese)
Currently translated at 99.2% (8954 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-22 17:37:35 +00:00
Test e9fe1774c0 fix poke snack sound issue, prevent ride controls from showing to passengers 2025-11-22 12:36:31 -05:00
JazzMcNade bb8b8a77c9 Fixed bees forgetting that they had nectar upon entering a hive 2025-11-22 11:07:37 -06:00
Paul c692b6b5c1 Reset changelog [skip-ci] 2025-11-22 23:09:37 +10:00
geumuandWeblate 68c6d5d9b2 Translated using Weblate (Korean)
Currently translated at 75.6% (6825 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-22 07:33:14 +00:00
Landon Wills 221547aabf unfuck camera maybe please 2025-11-21 22:39:19 -05:00
Watuneni iteiteandWeblate f6b3591d80 Translated using Weblate (Japanese)
Currently translated at 99.2% (8954 of 9019 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-22 03:06:51 +00:00
geumuandWeblate f9878d6137 Translated using Weblate (Korean)
Currently translated at 75.2% (6740 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-22 01:45:14 +00:00
Watuneni iteiteandWeblate 94da3b8d21 Translated using Weblate (Japanese)
Currently translated at 100.0% (8962 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-22 01:45:14 +00:00
Nick 3a2ff9de75 1.7.1 SNAPSHOT in prep for next development cycle 2025-11-21 17:06:08 -08:00
Paul b249896316 more changelog [skip-ci] 2025-11-22 09:37:51 +10:00
Test 1cb6979b90 More changelog cleanup [skip-ci] 2025-11-21 20:56:30 +00:00
Polymeta e983d2c1db Merge branch 'implement_pokemon' into 'main'
marked togedemaru as implemented

See merge request cable-mc/cobblemon!2029
2025-11-21 20:16:07 +00:00
violet 9ee0cf941b Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-21 14:29:35 -05:00
violet 8436c93317 marked togedemaru as implemented 2025-11-21 14:29:19 -05:00
Paul 7f0329acb7 Loads of changelog restructuring, separated old versions out into their own files [skip-ci] 2025-11-21 23:49:00 +10:00
Polymeta 83489b7230 nothing to see here
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-21 13:09:27 +00:00
Landon 081a25f04b Merge branch 'does-anyone-even-read-these' into 'main'
Fix mutation of vector after changing from Vector3f to Vec3

See merge request cable-mc/cobblemon!2028
2025-11-21 12:42:41 +00:00
Landon Wills 38bdfae0db Fix mutation of vector after changing from Vector3f to Vec3 2025-11-21 06:57:06 -05:00
Landon bd3a9e30f1 Merge branch 'fix-npc-behavior-json' into 'main'
Fix NPC Behavior Json key

See merge request cable-mc/cobblemon!2026
2025-11-21 11:02:11 +00:00
Hiroku 7ce968f467 Merge branch 'implement_pokemon' into 'main'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...

See merge request cable-mc/cobblemon!2027
2025-11-21 10:33:34 +00:00
Hiroku 9ac8cc56f0 Merge branch 'main' into 'implement_pokemon'
# Conflicts:
#   common/src/main/resources/data/cobblemon/species/generation5/patrat.json
#   common/src/main/resources/data/cobblemon/species/generation9/tadbulb.json
2025-11-21 09:45:22 +00:00
Polymeta 98159e1e0e Merge branch 'smeargle-tail-reset' into 'main'
Fixed smeargle tail changing colour between relogs

See merge request cable-mc/cobblemon!2024
2025-11-21 09:44:00 +00:00
violet 025b5aae74 edited treecko line, braixen, and delphox's files 2025-11-21 04:27:03 -05:00
Deltric 2fddb21585 Fixed NPC behavior key fix, yes that's right behavior not behaviour @Hiroku. 2025-11-21 01:32:54 -06:00
violet 6b75976236 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2025-11-21 02:17:36 -05:00
Paul fdf419ec8f Rescraped for willFlee scraper bug, restoring flee behaviour for hundreds of pokes 2025-11-21 17:12:20 +10:00
Paul d2ceb2d58a Fixed wooper and whiscash forms being fished by all rods 2025-11-21 17:11:11 +10:00
Hiroku 6d8311a66c Merge branch '1.7-spawns-update' into 'main'
Updated spawns for 1/100 chance form Pokémon.

See merge request cable-mc/cobblemon!2025
2025-11-21 07:07:00 +00:00
Veraxiel 18a3d1c22c Updated spawns for 1/100 chance form Pokémon. 2025-11-21 01:54:50 -05:00
Hiroku b382a1b2db Merge branch '1.7-tag-cleanup' into 'main'
1.7 tag cleanup

See merge request cable-mc/cobblemon!2017
2025-11-21 06:29:22 +00:00
Paul dd17fa138e Fixed smeargle tail changing colour between relogs 2025-11-21 16:27:56 +10:00
Test 09dd623ea7 Amend dolphin controls overlay 2025-11-21 06:24:56 +00:00
Landon 8c01bb831f Merge branch 'path-faster-and-less-and-faster' into 'main'
Following the owner should not be so aggressive. Path cooldown, and consider...

See merge request cable-mc/cobblemon!2019
2025-11-21 06:09:10 +00:00
Paul 2cb4372496 Removed cry from slowpoke tail'ing 2025-11-21 15:04:43 +10:00
Hiroku 7597b2d98e Merge branch 'fated-faint' into 'main'
Crafting Fix

See merge request cable-mc/cobblemon!2023
2025-11-21 04:54:05 +00:00
dhi_holo 5ac2729a77 Crafting Fix
EV Feathers now unlock in recipe book, and Mochi cannot be crafted in a table, now requires campfire pot cooking
2025-11-21 14:46:13 +10:00
Hiroku bec1fca7a5 Merge branch 'brewer-only' into 'main'
Quick Brewing Only-ification

See merge request cable-mc/cobblemon!2022
2025-11-21 04:19:04 +00:00
dhi_holo 32d145f3cc Quick Brewing Only-ification
Removed 8 recipes that were meant to be removed, added translation for a newer tag that was missed over
2025-11-21 13:34:52 +10:00
Paul a5f1a14e21 Merge remote-tracking branch 'weblate/lang-updates'
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/pt_br.json
2025-11-21 11:43:28 +10:00
Landon 57784b8620 Merge branch 'camera-farlands' into 'main'
Switch to using Doubles when positioning camera.

See merge request cable-mc/cobblemon!2021
2025-11-20 23:28:26 +00:00
JPAKx4 a29b3342a1 Switch to using Doubles when positioning camera. 2025-11-20 16:41:13 -06:00
Polymeta 64d6560caf Merge branch 'cobble-jail-here-i-come' into 'main'
Small fixes

See merge request cable-mc/cobblemon!2018
2025-11-20 22:10:32 +00:00
Polymeta 2e314e48fb Merge branch 'Car-fixes' into 'main'
Car fixes

See merge request cable-mc/cobblemon!2016
2025-11-20 21:19:50 +00:00
Nick e8d1e3766b Merge branch 'fix-pc-deserialisation' into 'main'
Fix PC JSON loading

See merge request cable-mc/cobblemon!2020
2025-11-20 12:09:54 -08:00
Landon Wills 012682268e Add safe check for nbt 2025-11-20 14:22:32 -05:00
Landon Wills 38428e4ea9 Fix PC JSON loading 2025-11-20 14:19:17 -05:00
Paul 567132bc0c Even more aggressive optimizations for the nodemaker 2025-11-20 23:07:59 +10:00
Paul e7209e4000 More aggressive optimizations for the nodemaker 2025-11-20 22:40:19 +10:00
Landon Wills 273b520c0b Shave iterations off of node type checks 2025-11-20 02:13:27 -05:00
Guilherme Pereira 0f02313a14 prevent pokemon from being busy when capturing player gets killed 2025-11-20 03:13:55 -03:00
Guilherme Pereira 3249e4bbb1 prevent pokemon from doing damage when being captured 2025-11-20 03:13:15 -03:00
geumuandWeblate 36aca65003 Translated using Weblate (Korean)
Currently translated at 67.0% (6010 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-20 05:48:24 +00:00
Watuneni iteiteandWeblate c6635213a2 Translated using Weblate (Japanese)
Currently translated at 99.2% (8897 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-20 05:48:23 +00:00
JazzMcNade bf6fab3936 Only check for nearby danger nodes if the hitbox is small 2025-11-19 23:18:11 -06:00
Watuneni iteiteandWeblate b76158d1d7 Translated using Weblate (Japanese)
Currently translated at 99.2% (8896 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-20 02:32:39 +00:00
geumuandWeblate 916ec97fce Translated using Weblate (Korean)
Currently translated at 66.6% (5972 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-20 02:32:36 +00:00
Veraxiel 36b38d36cb Updated biome tags. 2025-11-19 21:00:27 -05:00
Veraxiel f1163977e1 Updated biome and seasoning tags. Updated Sinister Tea recipe filter. 2025-11-19 20:59:42 -05:00
Carmendar a7dd6d52c8 Charizard and Mudsdale Look tweaks. 2025-11-19 19:29:19 -06:00
Watuneni iteiteandWeblate 6898804e83 Translated using Weblate (Japanese)
Currently translated at 96.9% (8686 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-20 00:40:19 +00:00
Carmendar 2331603b27 Tyrantrum sleep t-pose fix. 2025-11-19 18:30:38 -06:00
Carmendar c8e9cbbe59 Furfrou cry fix 2025-11-19 18:30:11 -06:00
Carmendar d374635648 Aerodactyl Battle Cry and Texture fix 2025-11-19 18:29:39 -06:00
Polymeta 803d3be325 recipe and tag tweak
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-19 23:59:55 +00:00
Polymeta 50bacbe25e Merge branch 'fix_medicinal_brew_from_cooking_pot_recipe' into 'main'
Revert Medicinal Brew recipe back to water bottle as opposed to empty bottle.

See merge request cable-mc/cobblemon!2015
2025-11-19 23:55:28 +00:00
Faintful 94ef9830b7 Revert Medicinal Brew recipe back to water bottle as opposed to empty bottle. 2025-11-19 21:17:22 +01:00
Weblate 87502f36c4 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-11-19 16:43:18 +00:00
Nico MerenqandWeblate bed511d403 Translated using Weblate (Russian)
Currently translated at 78.3% (7019 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-19 16:43:14 +00:00
阿鱼andWeblate 4170b00e31 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (8962 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-19 16:43:13 +00:00
geumuandWeblate 3cc90daaf0 Translated using Weblate (Korean)
Currently translated at 66.2% (5937 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-19 16:43:12 +00:00
Polymeta b0ecd24f42 Merge branch 'aprijuice-advancement-fix' into 'main'
Fixed max ride boosts advancement not working properly

See merge request cable-mc/cobblemon!2014
2025-11-19 14:10:10 +00:00
Polymeta ade5603331 Edit max_ride_stats.json 2025-11-19 13:25:03 +00:00
Paul 34bcefb09f Fixed max ride boosts advancement not working properly 2025-11-19 21:41:14 +10:00
Hiroku dccc9dfbcb Merge branch 'sterr/sound-fixes' into 'main'
Audio fixes stuff

See merge request cable-mc/cobblemon!2013
2025-11-19 11:29:40 +00:00
Weblate 9a1d6461d9 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-11-19 11:12:29 +00:00
Watuneni iteiteandWeblate 2dc76ffe3e Translated using Weblate (Japanese)
Currently translated at 96.4% (8646 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-19 11:12:25 +00:00
geumuandWeblate 87225d8981 Translated using Weblate (Korean)
Currently translated at 65.6% (5886 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-19 11:12:24 +00:00
Sterrezo 4bf4101fd1 Audio fixes stuff 2025-11-19 11:39:24 +01:00
Paul 58c6ea0269 Following the owner should not be so aggressive. Path cooldown, and consider hitbox when deciding if it needs to start walking closer 2025-11-19 19:16:42 +10:00
Paul 034bd2eec6 Only use strict walking pathing when the hitbox is small 2025-11-19 19:16:02 +10:00
Polymeta a24be04d68 Merge branch 'ihatebugtypes1.7' into 'main'
sacrificing Bugsy for the sake of the release

Closes #1771 and #1768

See merge request cable-mc/cobblemon!2000
2025-11-19 07:32:27 +00:00
Segfault Guy 0d878d57b7 Merge remote-tracking branch 'origin/main' into ihatebugtypes1.7 2025-11-19 00:55:42 -05:00
Paul 08880e2294 Fixed instance of check for diagonal validation on non pokemon 2025-11-19 12:52:20 +10:00
Paul 1c45654930 Update the changed-default root variables on 1.7 installation 2025-11-19 12:33:36 +10:00
Hiroku dae3acb5a0 Merge branch 'i-dont-know-what-to-call-this-branch' into 'main'
Small fixes

See merge request cable-mc/cobblemon!2007
2025-11-19 02:30:20 +00:00
Hiroku 7bb6f8a12e Merge branch 'damage-formula' into 'main'
Add attack to damage formula

See merge request cable-mc/cobblemon!2011
2025-11-19 02:18:25 +00:00
lionandHiroku b25f3ca3f6 Add attack to damage formula 2025-11-19 02:18:25 +00:00
Hiroku 610b762188 Merge branch 'nut-rition' into 'main'
Food Tweaks

See merge request cable-mc/cobblemon!2010
2025-11-19 02:00:41 +00:00
Hiroku c4c954c898 Merge branch 'Meta&Jet-fixes' into 'main'
Metagross fix and Jet handling tweak.

See merge request cable-mc/cobblemon!2009
2025-11-19 01:49:19 +00:00
Segfault Guy 10b70a0e3f Merge remote-tracking branch 'origin/main' into ihatebugtypes1.7 2025-11-18 20:20:46 -05:00
Segfault Guy af437f9d3e Merge branch 'ihatebugtypes1.7' of https://gitlab.com/cable-mc/cobblemon into ihatebugtypes1.7 2025-11-18 20:14:21 -05:00
Segfault Guy ca5a96e979 Fix berry chomp sfx not playing for unrestricted berries when full. 2025-11-18 20:11:02 -05:00
dhi_holo a2936ebcff Berry Reorganisation
Reordered berries as Vera requested
2025-11-19 11:10:15 +10:00
geumuandWeblate c3d7537b3e Translated using Weblate (Korean)
Currently translated at 65.0% (5832 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-19 00:43:57 +00:00
Carmendar 81e5d830c6 Metagross walks once more & Jet handling expression tweak. 2025-11-18 18:38:02 -06:00
dhi_holo 4b09714ed5 Merge branch 'main' into nut-rition 2025-11-19 10:27:33 +10:00
Polymeta fa4a4c7e51 Merge branch 'farming-simulator-2025' into 'main'
Allow villagers to plant hearty rice

See merge request cable-mc/cobblemon!2008
2025-11-19 00:25:29 +00:00
dhi_holo 493b8bbecf Seasoning Tweaks
values are now what they should be, hopefully
2025-11-19 10:23:56 +10:00
Guilherme Pereira 9b519daff1 allow villagers to plant hearty rice 2025-11-18 21:02:10 -03:00
Guilherme Pereira a5ba3e7084 buff roots 2025-11-18 19:23:38 -03:00
Guilherme Pereira 6d2d146543 sync combat behaviour 2025-11-18 19:17:13 -03:00
Landon 22d93cb92c Merge branch 'navigator-performance' into 'main'
Performance optimizations for pathfinding

See merge request cable-mc/cobblemon!2006
2025-11-18 18:41:03 +00:00
geumuandWeblate 31c55a9b6f Translated using Weblate (Korean)
Currently translated at 65.0% (5832 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-18 17:39:25 +00:00
Paul 5281dbd81c Performance optimizations for pathfinding 2025-11-19 03:02:52 +10:00
Segfault Guy 8b863070fe addressing MR comments 2025-11-18 11:20:07 -05:00
Paul da1064772d Fixed rattata cry crash 2025-11-19 01:59:00 +10:00
Landon 8ca1957a60 Merge branch 'ai-scrape' into 'main'
Scraped AI and Behaviors

See merge request cable-mc/cobblemon!1994
2025-11-18 12:51:11 +00:00
lionandLandon cbab2b7e5c Scraped AI and Behaviors 2025-11-18 12:51:10 +00:00
Landon c47bd604d5 Merge branch 'wrong-land-shark' into 'main'
Prevent sharpedo from trying to swim on land

See merge request cable-mc/cobblemon!2003
2025-11-18 12:21:59 +00:00
Polymeta 63776ca7a0 added missing food colours and remove debug annotation
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-18 11:56:32 +00:00
Polymeta c66c7170f6 Merge branch 'juice-tweaks' into 'main'
Fixed apricorn stat changes only applying when points are already assigned to that stat, adjusted flavour floor

See merge request cable-mc/cobblemon!2004
2025-11-18 10:00:03 +00:00
Weblate e9e4158666 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-11-18 09:44:12 +00:00
Watuneni iteiteandWeblate b15917898f Translated using Weblate (Japanese)
Currently translated at 95.7% (8582 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-18 09:44:07 +00:00
TeggyandWeblate ef3179bfa2 Translated using Weblate (Spanish)
Currently translated at 84.8% (7602 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-11-18 09:44:06 +00:00
阿鱼andWeblate f0afb8b3d9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (8959 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-18 09:44:05 +00:00
geumuandWeblate 17e58b0ce5 Translated using Weblate (Korean)
Currently translated at 63.7% (5714 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-18 09:44:04 +00:00
Paul fb0bfb2d19 Merge remote-tracking branch 'origin/main' 2025-11-18 19:42:15 +10:00
Landon 0d87de157a Merge branch 'implement_pokemon' into 'main'
Implemplemenation

See merge request cable-mc/cobblemon!2002
2025-11-18 09:35:33 +00:00
Paul 4189da0cc7 Merge remote-tracking branch 'origin/main' 2025-11-18 19:33:17 +10:00
Paul 662ccdc268 Removed unrefined sinister tea seasonings 2025-11-18 19:29:54 +10:00
Hiroku 6779995680 Merge branch 'evo_particles_fix' into 'main'
Claire Obscure Particles: Expedition 33

See merge request cable-mc/cobblemon!1997
2025-11-18 09:26:28 +00:00
Landon c4b6cc7c00 Merge branch 'slowpoke-dex-fix' into 'main'
Fixed some dex display issues and fixed slowpoke appearance in dex

See merge request cable-mc/cobblemon!2001
2025-11-18 09:24:09 +00:00
Paul 07ef404518 Fixed apricorn stat changes only applying when points are already assigned to that stat, adjusted flavour floor 2025-11-18 19:13:04 +10:00
Landon Wills 4c8a8351ac Prevent sharpedo from trying to swim on land 2025-11-18 04:06:57 -05:00
Carmendar 17f5ed03d0 poser/species tweaks. 2025-11-18 02:46:11 -06:00
Paul a3d3c987bc Fixed some dex display issues and fixed slowpoke appearance in dex 2025-11-18 18:34:46 +10:00
Carmendar 6db0567f03 Merge branch 'main' into implement_pokemon 2025-11-18 02:02:32 -06:00
Segfault Guy 3e89499588 Fix SocketShowdownService and custom showdown data registration. 2025-11-18 02:09:39 -05:00
Segfault Guy 7982034964 Fix missing optional ability activation langs. 2025-11-18 02:02:19 -05:00
JPAKx4 8f462aab40 Add default_seat option to seat offset posers, and remove shouldRotate as it's not needed for positioning the camera. 2025-11-18 00:56:40 -06:00
Jackson Bowes ac3628d907 Merge branch 'ufo-turning-and-head-rot-fix' into 'main'
Fix various bugs with riding.

See merge request cable-mc/cobblemon!1998
2025-11-18 00:32:11 -06:00
Segfault Guy 4a1e0020f7 remove redundant bag item 2025-11-18 01:10:12 -05:00
Segfault Guy 3c1486e45b Implement volatile status curing berries and patch fullness conflict with restoration berries. 2025-11-18 00:36:11 -05:00
jackowes 4563770835 - fix nonJumping horses from falling through to Tpose when trying to jump. The in_air flag checks for the player.jumping flag so its true for a moment. Block this from being true when horse has no jump. 2025-11-17 23:00:13 -06:00
dhi_holo c49eed3aaf Initial value tweaks 2025-11-18 14:59:28 +10:00
jackowes cc80f69c47 - Fix jet bug/mishap
- Fixed ride sounds not working in multiplayer
- Made the velocity threshold lower for ridesounds so that they can be heard in more 'normal' situations.
- Revert player head rotation changes for rollables.
2025-11-17 22:56:30 -06:00
Landon 128366f9c2 Merge branch '1.7-spawns-update' into 'main'
Updated spawns for Marill, Bidoof, Rufflet, and Tadbulb lines.

See merge request cable-mc/cobblemon!1996
2025-11-18 04:43:51 +00:00
Tyzillion 1d158ae12c Evolution obscure particles fixed. 2025-11-17 23:10:58 -05:00
Landon ddd63ac841 Merge branch 'Aprijuice-Recipe-Change' into 'main'
Energy Root added to Aprijuice recipes & slight update to compost values.

See merge request cable-mc/cobblemon!1995
2025-11-18 03:57:18 +00:00
Veraxiel 118a682451 Updated spawns for Marill, Bidoof, Rufflet, and Tadbulb lines. 2025-11-17 22:26:13 -05:00
Landon d202efc0a9 Merge branch 'validate-op-permissions-riding' into 'main'
Add is OP player check to riding stats debug GUI

See merge request cable-mc/cobblemon!1988
2025-11-18 03:16:00 +00:00
Carmendar 81a1314493 Energy Root added to Aprijuice recipes & slight update to compost values. 2025-11-17 21:08:16 -06:00
Guilherme Pereira d20673d9bf fix pokemon not being able to enter boats 2025-11-17 21:32:30 -03:00
FrankTheFarmer 4634dc7539 Fixed both stunfisks using portrait pose when in water 2025-11-18 09:56:52 +10:00
FrankTheFarmer c2db648d25 Tweaked Rayqwayqway's poser 2025-11-18 08:59:33 +10:00
FrankTheFarmer 76f1ace6b7 Fixed scovillain's cry interpolation 2025-11-18 08:51:15 +10:00
Jackson Bowes a316329359 Merge branch 'very-minor-molang-change' into 'main'
Fix boats and truthy values

See merge request cable-mc/cobblemon!1993
2025-11-17 16:29:54 -06:00
violet 4aa1b804bc Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-17 17:25:32 -05:00
violet 233d27413d poser tweaks to tynamo, ribombee, and cutiefly 2025-11-17 17:25:24 -05:00
FrankTheFarmer 05621ccb51 Merge branch 'main' into implement_pokemon 2025-11-18 08:13:24 +10:00
jackowes ea59981b58 - fix ufo momentum by rotating the rideVelocity vector by the induced ride yaw. 2025-11-17 15:22:41 -06:00
JPAKx4 960460ec08 Fix Boats being 'in_air' in water and vice versa. 2025-11-17 13:58:06 -06:00
JPAKx4 8d587c5287 Fix unintendid behaviour, shouldn't actually change anything currently though. 2025-11-17 13:35:19 -06:00
Guilherme Pereira e0b79c9bab change is op check to use cobblemon permissions validator 2025-11-17 09:36:56 -03:00
Polymeta 6206330b76 Merge branch 'getting-statistical' into 'main'
Getting statistical and minor Advancement fixes

See merge request cable-mc/cobblemon!1760
2025-11-17 09:30:28 +00:00
FrankTheFarmer 8e7a2a0356 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-17 19:29:51 +10:00
FrankTheFarmer 7657cf4f73 Fixed Dragapult spinning rapidly after every physical attack 2025-11-17 19:28:59 +10:00
Polymeta 7b137fbe14 Merge branch 'Saccharine-Tree-Biome-List-Update' into 'main'
Saccharine tree biome list update

See merge request cable-mc/cobblemon!1990
2025-11-17 09:21:35 +00:00
Neovitalism 46d278ca55 key \:) 2025-11-17 03:18:02 -06:00
Landon 4d472d0b36 Merge branch 'molang-json-interaction' into 'main'
Molang json interaction

See merge request cable-mc/cobblemon!1934
2025-11-17 09:10:40 +00:00
Neovitalism 339038956d Support for deserialization from any key
...I think.
2025-11-17 03:09:21 -06:00
Slippy fd442211d3 Change Saccharine Tree Rarity 2025-11-17 03:07:58 -06:00
Landon 144f857a3b Merge branch 'fix-blocks-traveled-requirement' into 'main'
Fix Blocks Traveled requirement

See merge request cable-mc/cobblemon!1979
2025-11-17 08:20:35 +00:00
lionandLandon 80131e57f8 Fix Blocks Traveled requirement 2025-11-17 08:20:35 +00:00
Slippy 30d89a2704 Make Saccharine Trees a little less common 2025-11-17 02:04:51 -06:00
Landon 5e147545b7 Merge branch 'advancing-advancements' into 'main'
Advancing Advancements for Cobblemon 1.7.0

See merge request cable-mc/cobblemon!1974
2025-11-17 07:59:41 +00:00
Landon e962079cda Merge branch 'remove-poke-puff' into 'main'
Disable Poké Puffs temporarily

See merge request cable-mc/cobblemon!1989
2025-11-17 07:30:41 +00:00
lionandLandon 6f934cfbd4 Disable Poké Puffs temporarily 2025-11-17 07:30:41 +00:00
MoeBoy76 47ecef81a6 fix changelog errors 2025-11-17 18:02:04 +11:00
MoeBoy76 16762ae933 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-11-17 17:56:53 +11:00
MoeBoy76 ba47f6a833 remove species check from catch trigger 2025-11-17 17:56:26 +11:00
dhi_holo 522ffefd0a Stone fix and Z-fix
All Evolution Stone blocks (besides Nether Fire Stone Ore) now need Iron to mine, and Display Cases now look better in more contexts
2025-11-17 16:04:15 +10:00
dhi_holo e17ca360df Merge branch 'main' into advancing-advancements 2025-11-17 15:46:04 +10:00
Carmendar a559737106 Merge branch 'main' into implement_pokemon 2025-11-16 23:27:00 -06:00
Landon e18d5837af Merge branch 'riding-molang-electric-bogaloo' into 'main'
Switch asMoLangValue from the states to the behaviour to allow for more dynamic options.

See merge request cable-mc/cobblemon!1986
2025-11-17 05:15:10 +00:00
Landon 65ae67d9ac Merge branch 'disable-nvb' into 'main'
Disable third_person_view_bobbing Config.

See merge request cable-mc/cobblemon!1987
2025-11-17 05:15:08 +00:00
Paul 05c77a6156 Hitbox improvements for melee attack, also don't randomly attack piglins or slimes or creepers 2025-11-17 15:11:50 +10:00
Paul 8ae6792785 Fixed fossil substitutes not working, fixed aspects not working in fossil tank rendering, fixed slowpoke tail aspects being added to everything 2025-11-17 11:21:23 +10:00
Guilherme Pereira 5f67fc167a add is op player check to riding stats debug gui 2025-11-16 20:16:08 -03:00
FrankTheFarmer 8dd62269ed Updated delphox animations 2025-11-17 08:03:29 +10:00
JPAKx4 0eee6e8634 Merge remote-tracking branch 'origin/riding-molang-electric-bogaloo' into riding-molang-electric-bogaloo
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/air/BirdBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/air/HoverBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/air/JetBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/air/RocketBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/land/HorseBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/land/MinekartBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/land/VehicleBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/liquid/BoatBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/liquid/BurstBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/liquid/DolphinBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/liquid/SubmarineBehaviour.kt
2025-11-16 15:10:45 -06:00
JPAKx4 a16a7c31fe Switch asMoLangValue from the states to the behaviour to allow for more dynamic options. 2025-11-16 15:10:07 -06:00
JPAKx4 a4254df0ca Disable third_person_view_bobbing Config. 2025-11-16 12:02:25 -06:00
JPAKx4 21df52daf7 Switch asMoLangValue from the states to the behaviour to allow for more dynamic options. 2025-11-16 11:49:08 -06:00
Landon 5e81e26c69 Merge branch 'molang-riding' into 'main'
Updates to riding to work better in Molang

See merge request cable-mc/cobblemon!1984
2025-11-16 15:33:38 +00:00
Neovitalism 116a93d8cc Update CHANGELOG.md 2025-11-16 04:19:32 -06:00
Neovitalism acebc35d3f Who are we if not consistent?
Before, this property was called `PokemonFlagProperty`, had the key `tag`, and checked pokémon's labels. It was also in a package by itself.

Now, it's moved down into the properties package, renamed to LabelProperty, and the key "label" was added, keeping "tag" as a secondary for those that are using it currently.
2025-11-16 04:10:45 -06:00
Hiroku d103629fd2 Merge branch '1.7-spawns-update' into 'main'
1.7 spawns update

See merge request cable-mc/cobblemon!1983
2025-11-16 09:27:54 +00:00
JPAKx4andJordan 6e2a0cd3b9 Switch to using ObjectValues for states to support riding styles with multiple properties. Added a few useful properties that can now be accessed through get_riding_state(name). 2025-11-16 07:12:59 +00:00
FrankTheFarmer 77490783e4 Swampert model tweak to fix its look animation 2025-11-16 15:51:10 +10:00
FrankTheFarmer ed28c70c5a Tweaked Meganium's profile data to look better in the dex 2025-11-16 15:50:40 +10:00
FrankTheFarmer 3f71584a6e Clamped Shelmet's look range to stop clipping with the shell. 2025-11-16 14:55:31 +10:00
FrankTheFarmer 4f09e56510 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-16 14:54:36 +10:00
FrankTheFarmer b534183a50 Clamped Sandaconda's look range and stopped it from using the donut to look 2025-11-16 14:54:27 +10:00
Carmendar 56ea6c7161 Merge branch 'main' into implement_pokemon 2025-11-15 22:48:16 -06:00
Veraxiel 37f6010381 Edit to Popplio line spawns. 2025-11-15 23:44:38 -05:00
Hiroku 798dd64f84 Merge branch 'RestoreSheepShearing' into 'main'
Restore Sheep Shearing

See merge request cable-mc/cobblemon!1982
2025-11-16 03:43:58 +00:00
Paul c1acf8494c Slowpoke tails are snipped a bit less short 2025-11-16 13:15:44 +10:00
Veraxiel d4601326a7 Removed Water and Lava block tags. Updated spawns using those tags to use the blocks directly. 2025-11-15 22:09:50 -05:00
JazzMcNade a037af6948 Allow herding sheep to eat grass, fix typo 2025-11-15 20:55:58 -06:00
FrankTheFarmer 976c94cb6b Puppy and Icecream changelog 2025-11-16 12:48:28 +10:00
FrankTheFarmer 422154e4c7 Tweaked Eevee's shoulder positioning 2025-11-16 12:46:38 +10:00
JazzMcNade 517ac94b8d Restore sheep shearing and eating grass to restore wool 2025-11-15 20:26:31 -06:00
Paul b5ec2b28fd Merge remote-tracking branch 'origin/main' 2025-11-16 12:14:50 +10:00
Paul f45a4b784b Fixed percentSum being exceeded during multi-pass spawns, closes #1778 2025-11-16 12:14:35 +10:00
Hiroku 91dda046d8 Merge branch 'revert-transition-logic' into 'main'
Revert transition logic so land mounts can be consistently mounted

See merge request cable-mc/cobblemon!1981
2025-11-16 01:47:59 +00:00
FrankTheFarmer 71fabbd245 Added placeholder shoulder animations to Alcremie 2025-11-16 11:45:07 +10:00
Carmendar fa0f29b085 Merge branch 'main' into implement_pokemon 2025-11-15 18:57:34 -06:00
Landon Wills 49577d2518 Revert transition logic so land mounts can be consistently mounted 2025-11-15 19:29:36 -05:00
FrankTheFarmer 12de6750de Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-16 10:19:01 +10:00
FrankTheFarmer 4e1b9785a0 Stupid fish assets updated 🔵🔴⚪ 2025-11-16 10:18:53 +10:00
RedGenesectNinja 2f2de32493 Implemented the updated textures for Slowpoke and Galarian Slowpoke 2025-11-15 18:09:39 -06:00
FrankTheFarmer a38b68ce23 Added translucent culling to flygon's resolver to fix goggle z fighting 2025-11-16 09:49:09 +10:00
FrankTheFarmer 7d605f8bf9 Updated flygon's animation to fix the static legs in the ground idle 2025-11-16 09:48:46 +10:00
FrankTheFarmer 75134f41e3 Fixed flygon's look animation to use the proper head_ai bone 2025-11-16 09:48:20 +10:00
Landon 2bad8ec673 Merge branch 'implement_pokemon' into 'main'
Implement pokemon

See merge request cable-mc/cobblemon!1945
2025-11-15 22:44:48 +00:00
Carmendar 1524e9c476 smol species fixes. 2025-11-15 15:55:14 -06:00
Carmendar c8ad0cd7e7 Merge branch 'main' into implement_pokemon
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation1/aerodactyl.json
#	common/src/main/resources/data/cobblemon/species/generation1/arcanine.json
#	common/src/main/resources/data/cobblemon/species/generation1/blastoise.json
#	common/src/main/resources/data/cobblemon/species/generation1/charizard.json
#	common/src/main/resources/data/cobblemon/species/generation1/dewgong.json
#	common/src/main/resources/data/cobblemon/species/generation1/dragonite.json
#	common/src/main/resources/data/cobblemon/species/generation1/gyarados.json
#	common/src/main/resources/data/cobblemon/species/generation1/lapras.json
#	common/src/main/resources/data/cobblemon/species/generation1/mrmime.json
#	common/src/main/resources/data/cobblemon/species/generation1/nidoking.json
#	common/src/main/resources/data/cobblemon/species/generation1/parasect.json
#	common/src/main/resources/data/cobblemon/species/generation1/rhydon.json
#	common/src/main/resources/data/cobblemon/species/generation1/rhyhorn.json
#	common/src/main/resources/data/cobblemon/species/generation1/seaking.json
#	common/src/main/resources/data/cobblemon/species/generation1/tauros.json
#	common/src/main/resources/data/cobblemon/species/generation1/venusaur.json
#	common/src/main/resources/data/cobblemon/species/generation2/ariados.json
#	common/src/main/resources/data/cobblemon/species/generation2/forretress.json
#	common/src/main/resources/data/cobblemon/species/generation2/girafarig.json
#	common/src/main/resources/data/cobblemon/species/generation2/heracross.json
#	common/src/main/resources/data/cobblemon/species/generation2/piloswine.json
#	common/src/main/resources/data/cobblemon/species/generation2/ursaring.json
#	common/src/main/resources/data/cobblemon/species/generation3/altaria.json
#	common/src/main/resources/data/cobblemon/species/generation3/camerupt.json
#	common/src/main/resources/data/cobblemon/species/generation3/claydol.json
#	common/src/main/resources/data/cobblemon/species/generation3/flygon.json
#	common/src/main/resources/data/cobblemon/species/generation3/latias.json
#	common/src/main/resources/data/cobblemon/species/generation3/latios.json
#	common/src/main/resources/data/cobblemon/species/generation3/metagross.json
#	common/src/main/resources/data/cobblemon/species/generation3/relicanth.json
#	common/src/main/resources/data/cobblemon/species/generation3/salamence.json
#	common/src/main/resources/data/cobblemon/species/generation3/sharpedo.json
#	common/src/main/resources/data/cobblemon/species/generation3/slaking.json
#	common/src/main/resources/data/cobblemon/species/generation3/tropius.json
#	common/src/main/resources/data/cobblemon/species/generation3/wailmer.json
#	common/src/main/resources/data/cobblemon/species/generation3/wailord.json
#	common/src/main/resources/data/cobblemon/species/generation4/bastiodon.json
#	common/src/main/resources/data/cobblemon/species/generation4/bronzong.json
#	common/src/main/resources/data/cobblemon/species/generation4/drifblim.json
#	common/src/main/resources/data/cobblemon/species/generation4/dusknoir.json
#	common/src/main/resources/data/cobblemon/species/generation4/garchomp.json
#	common/src/main/resources/data/cobblemon/species/generation4/gastrodon.json
#	common/src/main/resources/data/cobblemon/species/generation4/lickilicky.json
#	common/src/main/resources/data/cobblemon/species/generation4/magnezone.json
#	common/src/main/resources/data/cobblemon/species/generation4/mamoswine.json
#	common/src/main/resources/data/cobblemon/species/generation4/rhyperior.json
#	common/src/main/resources/data/cobblemon/species/generation4/staraptor.json
#	common/src/main/resources/data/cobblemon/species/generation4/togekiss.json
#	common/src/main/resources/data/cobblemon/species/generation5/bouffalant.json
#	common/src/main/resources/data/cobblemon/species/generation5/braviary.json
#	common/src/main/resources/data/cobblemon/species/generation5/crustle.json
#	common/src/main/resources/data/cobblemon/species/generation5/darmanitan.json
#	common/src/main/resources/data/cobblemon/species/generation5/golurk.json
#	common/src/main/resources/data/cobblemon/species/generation5/hydreigon.json
#	common/src/main/resources/data/cobblemon/species/generation5/klinklang.json
#	common/src/main/resources/data/cobblemon/species/generation5/serperior.json
#	common/src/main/resources/data/cobblemon/species/generation5/volcarona.json
#	common/src/main/resources/data/cobblemon/species/generation5/zebstrika.json
#	common/src/main/resources/data/cobblemon/species/generation6/gogoat.json
#	common/src/main/resources/data/cobblemon/species/generation6/noivern.json
#	common/src/main/resources/data/cobblemon/species/generation6/skiddo.json
#	common/src/main/resources/data/cobblemon/species/generation6/tyrantrum.json
#	common/src/main/resources/data/cobblemon/species/generation7/dhelmise.json
#	common/src/main/resources/data/cobblemon/species/generation7/mudsdale.json
#	common/src/main/resources/data/cobblemon/species/generation8/corviknight.json
#	common/src/main/resources/data/cobblemon/species/generation8/dragapult.json
#	common/src/main/resources/data/cobblemon/species/generation8a/sneasler.json
#	common/src/main/resources/data/cobblemon/species/generation8a/ursaluna.json
#	common/src/main/resources/data/cobblemon/species/generation8a/wyrdeer.json
#	common/src/main/resources/data/cobblemon/species/generation9/cyclizar.json
#	common/src/main/resources/data/cobblemon/species/generation9/dondozo.json
#	common/src/main/resources/data/cobblemon/species/generation9/dudunsparce.json
#	common/src/main/resources/data/cobblemon/species/generation9/espathra.json
#	common/src/main/resources/data/cobblemon/species/generation9/farigiraf.json
#	common/src/main/resources/data/cobblemon/species/generation9/kilowattrel.json
#	common/src/main/resources/data/cobblemon/species/generation9/orthworm.json
#	common/src/main/resources/data/cobblemon/species/generation9/revavroom.json
2025-11-15 15:53:14 -06:00
Landon db1108f7ef Merge branch 'more-more-riding-fixes' into 'main'
Bunch of riding fixes

See merge request cable-mc/cobblemon!1978
2025-11-15 20:53:21 +00:00
Kenji_64 33a4e31b60 Fixed Wartortle's shiny shell not being green 2025-11-15 19:51:14 +01:00
Test 7cb4e96a64 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-11-15 12:49:39 -05:00
Test ef0f997682 asset updates 2025-11-15 12:48:58 -05:00
Nico MerenqandWeblate 250724ef1f Translated using Weblate (Russian)
Currently translated at 77.9% (6988 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-15 15:05:37 +00:00
Paul 2988a29e28 Merge remote-tracking branch 'origin/main' 2025-11-15 21:59:56 +10:00
Paul fe59748bf6 Rescraped - fixed inverted fire immunity and implemented explicit drowsy and rouse chances 2025-11-15 21:59:47 +10:00
Patch Notes GuyandWeblate 3e1837543d Translated using Weblate (Ukrainian)
Currently translated at 77.5% (6948 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/uk/
2025-11-15 10:45:37 +00:00
Polymeta 0235bc108e Merge branch '1.7-spawns-update' into 'main'
Fix to Cursola spawn. Updated Dreepy line spawns.

See merge request cable-mc/cobblemon!1980
2025-11-15 10:45:18 +00:00
Carmendar 1526c2f037 Merge branch 'main' into implement_pokemon 2025-11-15 04:30:45 -06:00
Carmendar 408cf8c5ca One last poser tweak for the night. 2025-11-15 04:29:59 -06:00
Hiroku 895f8877b1 Merge branch 'neo-fixes-sometimes' into 'main'
Handful of bug fixes, probably more to come.

Closes #1215, #1341, #1719, and #1740

See merge request cable-mc/cobblemon!1975
2025-11-15 10:18:40 +00:00
Neovitalism aab4f3c7aa I like my kneecaps. 2025-11-15 03:31:28 -06:00
violet ceb70dbf2d Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-15 04:26:14 -05:00
Carmendar 6d46992ad7 More poser tweaks. 2025-11-15 03:25:53 -06:00
violet 84242194ba fixed drampa look 2025-11-15 04:25:52 -05:00
violet 529e4bef46 fixed espurr line posers 2025-11-15 04:07:10 -05:00
violet aa1658bb5d fixed alolan muk's portrait 2025-11-15 03:55:16 -05:00
violet 068df2b138 added eelektross and eelektrik placeholder animations + fixed look animations 2025-11-15 03:47:56 -05:00
Veraxiel 6fe68e117f Fix to Cursola spawn. Updated Dreepy line spawns. 2025-11-15 03:33:21 -05:00
Neovitalism 0724c21509 initialize instead 2025-11-15 01:56:38 -06:00
Carmendar 3499758203 Darmanitan Zen poser fix. 2025-11-15 00:29:54 -06:00
Landon 330f60f2d9 Merge branch 'slowpoke-snip' into 'main'
Slowpoke tail snip snip

See merge request cable-mc/cobblemon!1973
2025-11-15 06:28:09 +00:00
RedGenesectNinja 7d97df3407 Fixed Shiny Spring, Summer and Winter Sawsbuck using the wrong models 2025-11-15 00:17:06 -06:00
Nico MerenqandWeblate 1add7ea4cb Translated using Weblate (Russian)
Currently translated at 77.1% (6916 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-15 06:14:04 +00:00
Felipe Bermudes OrmeñoandWeblate e497cd445a Translated using Weblate (Spanish (Mexico))
Currently translated at 26.7% (2394 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-11-15 06:14:02 +00:00
Paul dfb8ff5aa2 Removed time check that should not be there 2025-11-15 16:11:24 +10:00
Carmendar 22b0e0612a Vanillite line shiny textures for real. 2025-11-14 23:57:48 -06:00
Carmendar e52c63d565 Metagross jump stat adjustment. 2025-11-14 23:52:45 -06:00
Carmendar fe7f72cb3d Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-14 23:51:50 -06:00
Carmendar 8187905987 Adjusted walk speed for Gogoat. 2025-11-14 23:51:04 -06:00
RedGenesectNinja 11b3043e6c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-14 22:47:24 -06:00
RedGenesectNinja 8d871ac949 Fixed Dragonair's shiny not working 2025-11-14 22:47:04 -06:00
Carmendar 8f7a523404 stat tweaks. 2025-11-14 22:40:22 -06:00
jackowes 7a74c72df2 - Fix hover not being able to be mounted on the ground and autodismounting you when you touch ground. Theres more changes tatn I thought it would have needed here... so hopefully nothing breaks. 2025-11-14 21:19:14 -06:00
Hiroku 31b136af05 Merge branch 'minor-code-cleanup' into 'main'
Attempted to fix stuff that failed, but at least I did some house cleaning.

See merge request cable-mc/cobblemon!1977
2025-11-15 02:50:07 +00:00
Hiroku 592e438c56 Merge branch 'pokedex-zoom' into 'main'
Fix pokedex zooming sensitivity.

See merge request cable-mc/cobblemon!1976
2025-11-15 02:47:22 +00:00
Carmendar bb98992635 Surface mount tweaks. 2025-11-14 20:02:34 -06:00
JPAKx4 abdc03be8c Fix pokedex zooming sensitivity. 2025-11-14 20:02:27 -06:00
JPAKx4 bfcc4516ff Attempted to fix stuff that failed, but at least I did some house cleaning. 2025-11-14 19:50:42 -06:00
Paul a4a46d20cd missed a lil sumtin [skip-ci] 2025-11-15 11:17:36 +10:00
Paul 12ec7b1e3d Merge remote-tracking branch 'origin/main' 2025-11-15 11:16:24 +10:00
Paul 6fcbbb1e73 Removed tooltip for mob effect values since it's meant to be a secret 2025-11-15 11:16:16 +10:00
Landon Wills d3984843e2 Run scraper 2025-11-14 19:32:31 -05:00
Carmendar 7a14c51df2 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-14 18:05:45 -06:00
Carmendar a7b023203f Merge branch 'main' into implement_pokemon 2025-11-14 18:04:18 -06:00
jackowes 81a241d4a1 - Make in_air more sophisticated to allow for jump animations to start more in line with when the vehicle actually jumps.
- Allow player head rotations on UFO/hover, jet, dolphin, and submarine.
2025-11-14 16:41:21 -06:00
jackowes 7ccb05fcb9 - Fixed incorrect hover transition velocity handoff.
- Fixed metagross walking in air
2025-11-14 16:06:48 -06:00
jackowes 32e81eff4e - Adjust jet running out of stamina to be more forgiving and graceful. Also remove the accidental ability to hover in air sort of after stamina drains.
- Change getRenderOrientation to return true orientation so that when you are the driver of the entity then it mirrors orientation. This is because you are the client that sets the rotation and interoplation is not needed.
2025-11-14 12:39:57 -06:00
Nico MerenqandWeblate e382e89e06 Translated using Weblate (Russian)
Currently translated at 76.6% (6868 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-14 17:21:23 +00:00
Gustavo PuerariandWeblate faf64a6092 Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.2% (8804 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-11-14 17:21:21 +00:00
jackowes 4ea704bd95 - Make remember ride camera default to false. 2025-11-14 11:07:39 -06:00
jackowes 497a686599 - make the motion sick camera have 0 roll. 2025-11-14 10:54:35 -06:00
jackowes b986823b2c - Fix rocket transition when in water.
- Fix transitions to water for all styles. (Was previously not allowing land to transition to if it was in water but its head was out of water)
2025-11-14 10:39:26 -06:00
Neovitalism 534a7e67e1 Merge branch 'main' into neo-fixes-sometimes 2025-11-14 10:20:02 -06:00
Neovitalism e47f014ebd Anti Team Rocket
Fixes two old bugs to stop players from stealing NPC pokémon.

For some reason, even though pokemon are added to an NPCPartyStore, their storeCoordinates are completely unset, acting as if nobody owns it. This is a good enough solution until it can be further looked into where the party is built, I'm just not knowledgeable enough in that department currently.

Fixes https://gitlab.com/cable-mc/cobblemon/-/issues/1215 and https://gitlab.com/cable-mc/cobblemon/-/issues/1341
2025-11-14 10:18:41 -06:00
Polymeta 651ba5b9ba move vanilla fix into fabric mixin as it breaks neoforge
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-11-14 16:12:45 +00:00
MoeBoy76 2b64174cfe fix input order which causes logic bug 2025-11-15 00:56:58 +11:00
MoeBoy76 918282893c Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-11-15 00:50:37 +11:00
Paul 74435945e9 Removed tooltip for food values since it's a bit redundant 2025-11-14 23:20:42 +10:00
Paul 6bf5e1491d Removed poke puffs access until it can be rebalanced 2025-11-14 23:14:22 +10:00
Hiroku 488f38c690 Merge branch 'removable-features' into 'main'
Adds the ability to hide certain features from rendering in the StatsWidget.

See merge request cable-mc/cobblemon!1914
2025-11-14 12:39:40 +00:00
violet dbbca02619 centiskorch texture tweaks 2025-11-14 05:52:46 -05:00
violet c50d5841d8 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-14 05:51:05 -05:00
violet 5489cfb4b0 fixed bellibolt's look anims 2025-11-14 05:39:07 -05:00
violet e421de547f SLOWPOKE TAILS NOW DROP WHEN YOU KILL THEM 2025-11-14 05:30:24 -05:00
geumuandWeblate aa8d0a9d48 Translated using Weblate (Korean)
Currently translated at 61.5% (5513 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-14 10:22:59 +00:00
violet 075dcdb9e9 BRAND NEW COBBLEMON EXCLUSIVE FURFROU FORMS PROPERLY IMPLEMENTED 2025-11-14 04:53:22 -05:00
Carmendar 2ebe8d6434 breach jump for Dragapult 2025-11-14 02:53:18 -06:00
Carmendar d7c77f5f3f a few ride stats adjusted ahead of scraper 2025-11-14 02:50:10 -06:00
Zack the GhastandWeblate 7a8dbbb4ce Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.6% (6059 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-11-14 08:26:53 +00:00
Watuneni iteiteandWeblate b8e1abc80b Translated using Weblate (Japanese)
Currently translated at 94.6% (8484 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-14 08:26:52 +00:00
YasitoandWeblate 12df9d29f5 Translated using Weblate (French)
Currently translated at 100.0% (8962 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-11-14 08:26:51 +00:00
YasitoandWeblate 2df0542631 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8962 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-11-14 08:26:50 +00:00
dhi_holoandWeblate e22b79a47c Translated using Weblate (English (en_PT))
Currently translated at 28.4% (2550 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/en_PT/
2025-11-14 08:26:49 +00:00
Carmendar 572682a23a Merge branch 'main' into implement_pokemon 2025-11-14 01:36:27 -06:00
Carmendar 6241865f95 Grounded again 2025-11-14 01:34:02 -06:00
dhi_holo 67dbda3113 Final Checks
Fixed the icons being outdated formattings, we are good to gold
2025-11-14 17:33:33 +10:00
Carmendar c50d3183e6 Submarine expression tweak 2025-11-14 01:22:35 -06:00
dhi_holo 9eae394ff5 Merge branch 'advancing-advancements' of https://gitlab.com/cable-mc/cobblemon into advancing-advancements 2025-11-14 17:15:14 +10:00
MoeBoy76 76b640984c changelog
[skip-ci]
2025-11-14 18:13:40 +11:00
dhi_holo 72d142a781 Merge branch 'main' into advancing-advancements 2025-11-14 17:08:21 +10:00
MoeBoy76 af1df22e4d ride stat trigger logic finalisation, added getBaseRideStat method to check the minimum value of a stat and updated the advancement 2025-11-14 18:07:15 +11:00
Landon d1b7dc6934 Merge branch 'making-pi-equal-3' into 'main'
Fix major camera issues.

See merge request cable-mc/cobblemon!1972
2025-11-14 06:58:05 +00:00
Neovitalism e2fdf3cffc Change Species#create() to use the species identifier.
Uses the identifier for the species in the name when using Species#create to avoid discrepancies between the name and identifier causing issues. (Like in the case of Type: Null, Farfetch'd, Ho-oh, and many others.)

Fixes https://gitlab.com/cable-mc/cobblemon/-/issues/1740 - thanks for finding this one!
2025-11-14 00:49:31 -06:00
Paul 4a68e53968 Slowpoke tail snip snip 2025-11-14 16:44:09 +10:00
JPAKx4 282bb4784e Accessor grabs the wrong forwards (FORWARDS vs forwards, what is this VIM?) so make it not do that. Fixes the major camera issues from the last two days. 2025-11-14 00:10:24 -06:00
dhi_holo 66787bfea4 Merge branch 'main' into advancing-advancements 2025-11-14 15:03:10 +10:00
dhi_holo c113e68488 Moomoo Mistake
Fixed lang string for moomoo milk tooltip
2025-11-14 15:03:05 +10:00
Hiroku a8267b8ee0 Merge branch 'molang-oh-molang' into 'main'
Removed the additional DoubleValue in seen_credits and is_in_dialogue

See merge request cable-mc/cobblemon!1971
2025-11-14 05:00:28 +00:00
Spicy 81f36b2b15 Removed the additional DoubleValue in seen_credits and is_in_dialogue 2025-11-13 22:49:10 -06:00
Hiroku 73e96740d6 Merge branch 'something-funny-and-creative-dot-mp4' into 'main'
Add 180deg rotation, I should test better for sure.

See merge request cable-mc/cobblemon!1970
2025-11-14 04:06:23 +00:00
JPAKx4 d53f9e5c63 Add 180deg rotation, I should test better for sure. 2025-11-13 21:20:11 -06:00
Hiroku 560bd75fd0 Merge branch 'fix/vanilla-connection' into 'main'
fix: fix vanilla connection with the cobblemon mods

See merge request cable-mc/cobblemon!1969
2025-11-14 02:30:25 +00:00
Paul 8850d38820 Rescraped behaviours to amend swim ability 2025-11-14 11:18:23 +10:00
Carmendar 8284b04426 Merge branch 'main' into implement_pokemon
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation1/rattata.json
#	common/src/main/resources/data/cobblemon/species/generation2/unown.json
#	common/src/main/resources/data/cobblemon/species/generation3/latias.json
#	common/src/main/resources/data/cobblemon/species/generation3/latios.json
#	common/src/main/resources/data/cobblemon/species/generation3/shuppet.json
#	common/src/main/resources/data/cobblemon/species/generation5/hydreigon.json
#	common/src/main/resources/data/cobblemon/species/generation5/volcarona.json
#	common/src/main/resources/data/cobblemon/species/generation9/wiglett.json
2025-11-13 18:16:41 -06:00
Neovitalism ca91d42ddf Shuffle around PlayerMixin#getDataFromShoulderPokemon
Fixes https://gitlab.com/cable-mc/cobblemon/-/issues/1719
Removes unnecessary logic from the server by putting it into the clientside block.
2025-11-13 18:06:47 -06:00
terrainwax 34232b33c7 fix: fix vanilla connection with the cobblemon mods 2025-11-13 22:30:12 +01:00
Landon 03c5a34fc8 Merge branch 'mixin-fix' into 'main'
Avoid relying on local player in common mixin

See merge request cable-mc/cobblemon!1968
2025-11-13 17:29:19 +00:00
Landon Wills 866db3d350 Avoid relying on local player in common mixin 2025-11-13 11:44:02 -05:00
Weblate 0c4bbef855 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-11-13 13:42:34 +00:00
Nico MerenqandWeblate 6fb34b5ee3 Translated using Weblate (Russian)
Currently translated at 76.0% (6819 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-13 13:42:29 +00:00
dhi_holoandWeblate f345b19d57 Translated using Weblate (English (en_PT))
Currently translated at 26.7% (2399 of 8962 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/en_PT/
2025-11-13 13:42:29 +00:00
Landon ee51a8a34b Merge branch 'more-misc-additions' into 'main'
More misc additions

See merge request cable-mc/cobblemon!1950
2025-11-13 13:18:32 +00:00
DeltricandLandon 2769733c51 More misc additions 2025-11-13 13:18:32 +00:00
dhi_holo f1bdaad97d Merge branch 'main' into advancing-advancements 2025-11-13 19:29:15 +10:00
dhi_holo f725e5fcba Improve max_ride_stats description 2025-11-13 19:28:40 +10:00
Landon 8ae79d8e44 Merge branch 'jackowes-riding-fixes' into 'main'
various riding bug fixes

See merge request cable-mc/cobblemon!1966
2025-11-13 09:28:17 +00:00
violet 2237e1eeca added missing emissive textures for magmar, magmortar, torracat, incineroar, sizzlipede, & centiskorch 2025-11-13 04:24:36 -05:00
Hiroku 6f08d610eb Merge branch 'we-dont-hang-anymore' into 'main'
Fixes Fabric server hanging on shutdown while players are logged in

See merge request cable-mc/cobblemon!1964
2025-11-13 09:19:04 +00:00
Hiroku 75f3db16aa Merge branch 'more-poke-snack-stuff' into 'main'
More Poké Snack stuff

Closes #1761

See merge request cable-mc/cobblemon!1931
2025-11-13 09:11:53 +00:00
Hiroku e4ee6b29ab Merge branch 'remove-shadow-people' into 'main'
Remove shadow people from appearing on mounts

See merge request cable-mc/cobblemon!1967
2025-11-13 09:08:42 +00:00
Watuneni iteiteandWeblate cb6b2b9ec5 Translated using Weblate (Japanese)
Currently translated at 94.3% (8447 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-13 09:07:00 +00:00
geumuandWeblate 8eafe14f66 Translated using Weblate (Korean)
Currently translated at 61.5% (5513 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-13 09:07:00 +00:00
Paul 8176e14981 Merge remote-tracking branch 'weblate/lang-updates' 2025-11-13 19:05:24 +10:00
Paul 7d956500f2 Scraped behaviours 2025-11-13 19:04:55 +10:00
Landon Wills c6853b84a6 Remove shadow people from appearing on mounts 2025-11-13 03:58:59 -05:00
dhi_holo bb54f8414e Merge branch 'main' into advancing-advancements 2025-11-13 18:17:07 +10:00
Carmendar 99c7d39705 Grounded. 2025-11-13 01:42:08 -06:00
Polymeta 3cb4984d51 Merge branch 'shine-bright-like-an-evo-stone' into 'main'
Update Lighting Values

See merge request cable-mc/cobblemon!1951
2025-11-13 07:30:10 +00:00
dhi_holoandPolymeta 930ed59234 Update Lighting Values 2025-11-13 07:30:10 +00:00
jackowes 3ea1918bc2 - Fix hand rotations on mount. The mixin that fixes it wasn't adjusted for the orientation refactor. 2025-11-13 00:55:11 -06:00
Carmendar bdd27078b5 Merge branch 'main' into implement_pokemon 2025-11-13 00:33:06 -06:00
jackowes 1dee9bc630 - Move game pause orientation protections to only the lerp factor. This is to prevent camera lerping while the game is paused. It was previously at the top of the setRotations CameraMixin function which would convert you back to vanilla rotations when paused.
- clamp local rideXrotations
- Fix player head rotations while riding.
- Lessen upwards boost on takeoff
2025-11-12 23:09:06 -06:00
Landon d761f2b4dc Merge branch 'riding-go-brr' into 'main'
Many Riding Fixes

See merge request cable-mc/cobblemon!1963
2025-11-13 04:56:11 +00:00
Test 0d6028706d Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-11-12 23:15:25 -05:00
Test 63d6851482 disable sacch dispenser interaction for now 2025-11-12 23:15:04 -05:00
dhi_holo 7c3fdbc921 Merge branch 'main' into advancing-advancements 2025-11-13 14:06:59 +10:00
RedGenesectNinja 9596f08957 Fixed Dusknoir's shiny not working and Updated Bronzong's textures 2025-11-12 21:12:00 -06:00
MoeBoy76 d9433960cd fml, forgot the license 2025-11-13 13:09:02 +11:00
MoeBoy76 89b6fd56b6 Merge remote-tracking branch 'origin/getting-statistical' into getting-statistical 2025-11-13 12:52:58 +11:00
MoeBoy76 10c441e3cd worked out rod casting, updated changelog 2025-11-13 12:52:36 +11:00
MoeBoy76 461b22efa8 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-11-13 12:44:17 +11:00
Carmendar 57a19909aa Merge branch 'main' into implement_pokemon 2025-11-12 19:32:00 -06:00
MoeBoy76 dc1473919e riding trigger added, added empty_bait check to reel in trigger 2025-11-13 12:24:16 +11:00
Carmendar ee20986ee0 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-12 19:23:57 -06:00
RedGenesectNinja 436aa5ea75 Updated textures for a handful of Pokemon 2025-11-12 19:14:19 -06:00
Carmendar e49f761417 Poser fixes and cries added. 2025-11-12 19:09:38 -06:00
Carmendar 95e3ab213a anim fixes for Scorbunny and Sneasler 2025-11-12 18:48:14 -06:00
Apion 7c3158c63b Merge branch 'particle-sounds-1.7' into 'main'
Refactored move sound file names, added all new move sounds

See merge request cable-mc/cobblemon!1965
2025-11-13 00:35:43 +00:00
TeggyandWeblate e9e41933fe Translated using Weblate (Spanish)
Currently translated at 84.6% (7578 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-11-13 00:30:11 +00:00
Nico MerenqandWeblate 7c7fd6c982 Translated using Weblate (Russian)
Currently translated at 75.4% (6757 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-13 00:30:09 +00:00
geumuandWeblate 6ec2820dd8 Translated using Weblate (Korean)
Currently translated at 59.9% (5367 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-13 00:30:07 +00:00
321retrogamer b1054bdf11 Various move-related Sound and Action effect tweaks.
Fixes timing for various Action Effects to better fit their sound design. Additionally, updates sounds for Infestation and Ice Beam and re-adds Ember and Flamethrower sound cues to their respective Action Effects.
2025-11-12 17:49:38 -06:00
Neovitalism 3b227ba3a2 Fixes fabric server hanging on shutdown 2025-11-12 16:01:01 -06:00
JPAKx4 96049abb98 Fix Merge issues 2025-11-12 15:20:36 -06:00
JPAKx4 d661e88a96 Merge branch 'main' into riding-go-brr 2025-11-12 15:19:25 -06:00
Apion 8510e05177 Remove redundant local field in MountedCameraRenderer.kt 2025-11-12 16:13:56 -05:00
JPAKx4 af4fe4d09d Merge branch 'main' into riding-go-brr
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/camera/MountedCameraRenderer.kt
2025-11-12 14:09:14 -06:00
Apion 8b2ffd0f29 Merge branch 'apion-bugfix' into 'main'
Fix bug with camera mixin on NeoForge

See merge request cable-mc/cobblemon!1956
2025-11-12 19:57:34 +00:00
Apion 18cebc794b Clean up variable names in CameraMixin 2025-11-12 14:11:14 -05:00
Apion 64e84dab64 Merge remote-tracking branch 'origin/main' into apion-bugfix
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/camera/MountedCameraRenderer.kt
2025-11-12 13:21:18 -05:00
JPAKx4 9c5535a014 Fix offsets being rotated and offsets being applied twice. Changed default third person offset (negotiable, no idea good values). Fix no view bobbing. Add dismount location logic from horses, might need more testing or accounting for other mount types. 2025-11-12 12:02:03 -06:00
Nico MerenqandWeblate 5993c1e588 Translated using Weblate (Russian)
Currently translated at 71.8% (6433 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-12 16:40:16 +00:00
geumuandWeblate e8f7983dd2 Translated using Weblate (Korean)
Currently translated at 59.5% (5338 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-12 16:40:14 +00:00
Watuneni iteiteandWeblate bdd172bd2d Translated using Weblate (Japanese)
Currently translated at 94.2% (8446 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-12 16:40:12 +00:00
Paul 13842de7d6 Merge remote-tracking branch 'origin/main' 2025-11-12 23:26:31 +10:00
Paul f05e059445 Lil fixes oopsy 2025-11-12 23:26:22 +10:00
Polymeta 038d9e858c Merge branch 'mechanics-sync' into 'main'
Mechanics sync

See merge request cable-mc/cobblemon!1960
2025-11-12 13:12:49 +00:00
lionandPolymeta 9913826e24 Mechanics sync 2025-11-12 13:12:49 +00:00
Polymeta 8f971cc3d6 Merge branch '1.7-spawns-update' into 'main'
Updated all spawn files. Changed dead_coral preset into a block tag.

See merge request cable-mc/cobblemon!1962
2025-11-12 11:38:03 +00:00
Veraxiel 33c74372a4 Updated all spawn files. Changed dead_coral preset into a block tag. 2025-11-12 05:48:29 -05:00
Polymeta 5f11f4bdd6 Merge branch 'Saccharine-Tree-Biome-List-Update' into 'main'
Updated biome list for saccharine tree

See merge request cable-mc/cobblemon!1959
2025-11-12 09:55:01 +00:00
Polymeta 13b4bdc204 Merge branch 'SaccHiveGenerationRebalance' into 'main'
SaccHiveGenerationRebalance

See merge request cable-mc/cobblemon!1961
2025-11-12 09:54:49 +00:00
Paul 451ae00da1 Drops scrape 2025-11-12 19:11:39 +10:00
Carmendar 0c33de61b9 Species file updates for Tauros, Salamence, Latias, Latios and Staraptor. 2025-11-12 03:05:12 -06:00
Carmendar 91a3fb5031 Removed Kilowattrel mounted run. 2025-11-12 03:04:32 -06:00
Carmendar 3a46b2c218 Updated look posing for Tropius, Garchomp and Pidove. 2025-11-12 03:03:28 -06:00
Carmendar 2f631ddc64 Ursaring texture fix 2025-11-12 03:02:39 -06:00
Paul a8cc8278d3 Liechi berry should target the right biome 2025-11-12 18:57:03 +10:00
Carmendar 2a2ef6ff7d Removed mount 2025-11-12 02:42:32 -06:00
Carmendar d3d94a3614 Adjusted Dragonite flying pose when mounted. 2025-11-12 02:42:03 -06:00
Carmendar f34cc3072b Cutiefly Shoulder poses. 2025-11-12 02:41:12 -06:00
Carmendar 68bff6a40b Jet Handling expression tweak. 2025-11-12 00:45:26 -06:00
Landon 58c0136ad1 Merge branch 'quick-misc-additions' into 'main'
Misc Changes

See merge request cable-mc/cobblemon!1941
2025-11-12 06:39:48 +00:00
DeltricandLandon 45238058cb Misc Changes 2025-11-12 06:39:47 +00:00
JPAKx4 a326befcef Fix offsets being rotated and offsets being applied twice 2025-11-11 22:38:43 -06:00
Segfault Guy d1a99608a5 Fix SwapInstruction not updating party positions. 2025-11-11 22:10:50 -05:00
JazzMcNade 52d8887514 Natural trees increased to 50% hives, Grown trees increased to 10% hives 2025-11-11 20:45:24 -06:00
Test 02ae8065ac Set duration for displaying ride controls in config to 0 by default 2025-11-12 01:43:01 +00:00
dhi_holo 2a6381d610 Eggant Is Here Now 2025-11-12 10:47:12 +10:00
dhi_holo 93dba4f3b8 Merge branch 'main' into advancing-advancements 2025-11-12 10:43:55 +10:00
Slippy c37c608010 Updated biome list for saccharine tree 2025-11-11 18:27:42 -06:00
Carmendar a7e7c2e814 Merge branch 'main' into implement_pokemon 2025-11-11 17:52:15 -06:00
Nico MerenqandWeblate 09c4ae96bf Translated using Weblate (Russian)
Currently translated at 70.9% (6352 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-11 22:50:22 +00:00
Guilherme Pereira 367264b06e Merge branch 'main' of gitlab.com:cable-mc/cobblemon into more-poke-snack-stuff 2025-11-11 14:52:37 -03:00
Guilherme Pereira 3631fa909d Merge branch 'more-poke-snack-stuff' of gitlab.com:cable-mc/cobblemon into more-poke-snack-stuff 2025-11-11 14:51:41 -03:00
Guilherme Pereira fc29826bc7 fix cakes not being rendered properly on multiplayer 2025-11-11 14:51:18 -03:00
MoeBoy76 6bf62b3f9d change debug message to log as error 2025-11-11 11:05:38 +00:00
Carmendar 00be470281 Alolan Rattata fix. 2025-11-11 02:58:28 -06:00
geumuandWeblate 8fb93dd488 Translated using Weblate (Korean)
Currently translated at 55.2% (4949 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-11 08:19:44 +00:00
Carmendar 57afbe79c2 Orthworm and Honedge line texture fixes. 2025-11-11 00:49:30 -06:00
Carmendar d5f336ce73 Merge branch 'main' into implement_pokemon 2025-11-11 00:48:17 -06:00
Neovitalism b863554c84 Changed to use the aspects of the pokémon instead of a new field. 2025-11-11 00:14:48 -06:00
Neovitalism 699d6fea17 Revert "Removable Feature Rendering"
This reverts commit d117d79d28.
2025-11-11 00:08:34 -06:00
Nico MerenqandWeblate 2cd066a4c1 Translated using Weblate (Russian)
Currently translated at 69.5% (6233 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-11 03:11:09 +00:00
Nico MerenqandWeblate 68b44db35c Translated using Weblate (Russian)
Currently translated at 67.3% (6032 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-10 22:22:58 +00:00
Nico MerenqandWeblate 18d3fb288a Translated using Weblate (Russian)
Currently translated at 65.7% (5885 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-10 19:28:47 +00:00
Weblate 725b4b7e48 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-11-10 18:19:35 +00:00
geumuandWeblate 28ae27b926 Translated using Weblate (Korean)
Currently translated at 55.2% (4949 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-10 18:19:31 +00:00
Watuneni iteiteandWeblate 21e9e73eee Translated using Weblate (Japanese)
Currently translated at 94.2% (8446 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-10 18:19:29 +00:00
Nico MerenqandWeblate 6bfb318e2d Translated using Weblate (Russian)
Currently translated at 65.6% (5882 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-10 18:19:28 +00:00
violet b79a0b1b6f various animation fixes 2025-11-10 03:17:58 -05:00
Test b7550f7699 overlay texture 2025-11-09 23:36:55 -05:00
violet 57721d1696 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-09 22:51:33 -05:00
violet b0711528d6 tiny tweaks :3 2025-11-09 22:51:19 -05:00
violet 7e968fcff9 Murdered Shulker Forretress 2025-11-09 22:50:41 -05:00
Guilherme Pereira 9770d8ca6b Merge branch 'main' of gitlab.com:cable-mc/cobblemon into more-poke-snack-stuff 2025-11-10 00:28:24 -03:00
Watuneni iteiteandWeblate 04c3e182e7 Translated using Weblate (Japanese)
Currently translated at 93.5% (8376 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-10 02:50:43 +00:00
Test bbcfe95bac cake block, tinting updates 2025-11-09 21:03:50 -05:00
Watuneni iteiteandWeblate 82088651c2 Translated using Weblate (Japanese)
Currently translated at 92.7% (8312 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-11-10 01:39:38 +00:00
Carmendar e399130fda forgor one last change 2025-11-09 18:45:12 -06:00
Carmendar 0083e54f6a Galar Weezing crash fix 2025-11-09 18:27:38 -06:00
Carmendar 9512252b72 ^ 2025-11-09 14:24:41 -06:00
Carmendar 73028d4c2a Gave Dondozo basic land & fixed pivot issues with Bramblin. 2025-11-09 14:20:58 -06:00
geumuandWeblate e3ead8e3e5 Translated using Weblate (Korean)
Currently translated at 50.4% (4515 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-09 19:29:48 +00:00
Nico MerenqandWeblate 9c4b9b35ab Translated using Weblate (Russian)
Currently translated at 65.6% (5880 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-09 19:29:46 +00:00
Carmendar 2f5910c436 Merge branch 'main' into implement_pokemon 2025-11-09 03:09:26 -06:00
Carmendar d1197cbc0b Updated Kangaskhan poser & added held item condition. 2025-11-09 02:30:09 -06:00
Carmendar 2ccf699a86 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-09 01:37:47 -06:00
Carmendar d767420814 Wiglett lost floating privileges. 2025-11-09 01:37:08 -06:00
Carmendar 77100300b1 Fixed Luxray feet textures. 2025-11-09 01:35:05 -06:00
Carmendar 5c80fc03e2 Toxicroak remodel 2025-11-09 01:33:55 -06:00
Carmendar aa39bb84fe Fixed Lanturn t-posing on land. 2025-11-09 00:50:19 -06:00
violet a767b3d0fe Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-11-09 01:28:31 -05:00
violet 3dbcbc34d0 ICE CREAM 2025-11-09 01:28:17 -05:00
violet 0bdadb3794 altered posers for solosis line 2025-11-09 01:20:50 -05:00
JPAKx4 ae6091fc01 Pull code out of the mixins. 2025-11-08 22:51:31 -06:00
dhi_holo 05b5782cd5 Merge branch 'main' into advancing-advancements 2025-11-09 12:54:24 +10:00
dhi_holo 0c220a8990 Berry Colour Tags
Small sorting thing to make it easier to find specific berry colours for cooking/crafting/smelting
2025-11-09 12:53:58 +10:00
Tyzillion b905888a0b Gust more like fart. 2025-11-08 20:17:23 -05:00
Tyzillion 5917e52ffc >.> 2025-11-08 20:01:05 -05:00
Tyzillion deb20cb418 Refactored move sound file names to match repo, Implemented Gust,
Added sounds to:
acid, aerialace, bodyslam, bubble, bubblebeam, bulldoze, bulletpunch, closecombat, eruption, gust, icebeam, infestation, lavaplume, magicalleaf, mist, mudbomb, powdersnow, razorleaf, shadowball, sludgebomb, thunder, thunderbolt, thundershock, watergun, waterpulse, and willowisp.
2025-11-08 19:53:02 -05:00
Apion 929e4b2391 Licenses 2025-11-08 15:43:50 -05:00
Apion c593a8b7e6 Fixed CameraMixin on neoforge 2025-11-08 15:00:22 -05:00
Apion d0fc166e09 Fix SoundEngineMixin on neoforge 2025-11-08 14:44:33 -05:00
geumuandWeblate 78f752b4a1 Translated using Weblate (Korean)
Currently translated at 48.7% (4366 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-08 19:29:08 +00:00
Apion b4c971398d Fix BrewingStandMenuMixin on neoforge 2025-11-08 14:01:02 -05:00
geumuandWeblate f0f78a01e0 Translated using Weblate (Korean)
Currently translated at 48.7% (4366 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-08 18:16:24 +00:00
geumuandWeblate 8c36ee15cd Translated using Weblate (Korean)
Currently translated at 48.6% (4355 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-08 16:54:27 +00:00
阿鱼andWeblate 3231d97cd3 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (8957 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-08 16:54:26 +00:00
Nico MerenqandWeblate 9fce4d3b6b Translated using Weblate (Russian)
Currently translated at 64.7% (5801 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-08 16:54:25 +00:00
阿鱼andWeblate 0f031545c1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.1% (8877 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-11-08 08:30:14 +00:00
geumuandWeblate 2b80189a79 Translated using Weblate (Korean)
Currently translated at 46.9% (4208 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-08 07:59:51 +00:00
geumuandWeblate 2e88b0194e Translated using Weblate (Korean)
Currently translated at 46.6% (4176 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-08 06:51:21 +00:00
Nico MerenqandWeblate b0e278d1a7 Translated using Weblate (Russian)
Currently translated at 63.3% (5674 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-11-08 06:51:12 +00:00
geumuandWeblate 9c646d9d53 Translated using Weblate (Korean)
Currently translated at 46.6% (4174 of 8957 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-11-08 06:51:10 +00:00
Guilherme Pereira dd19140a83 change mark chance effect to drops reroll 2025-11-07 10:33:54 -03:00
dhi_holo da787bf9bf Merge branch 'main' into advancing-advancements 2025-11-07 16:15:29 +10:00
Paul 57a839d000 Removed some test stuff I forgor about 2025-11-06 22:14:08 +10:00
Paul e77e49c8b1 Minor cleanup 2025-11-06 22:13:03 +10:00
Paul ce6d142bd4 Merge remote-tracking branch 'origin/main' into molang-json-interaction 2025-11-06 22:12:17 +10:00
MoeBoy76 f2db63164c general riding and PokéRod cast/reel stats 2025-11-05 16:05:52 +11:00
MoeBoy76 604b4d39ea Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-11-05 14:26:27 +11:00
Guilherme Pereira be96e45c4e change colors variable name 2025-11-04 08:41:42 -03:00
Guilherme Pereira 42eb08e715 Merge branch 'main' into more-poke-snack-stuff 2025-11-03 18:08:10 -03:00
Guilherme Pereira 03470aa623 add poke snack spawn pokemon pre and post events 2025-11-03 17:58:14 -03:00
Paul 5d3741f2e5 Added JSON file interactions for molang and function arguments for q.run_script 2025-11-02 11:23:50 +10:00
Guilherme Pereira d09d636113 add facing direction to snacks 2025-10-30 16:54:45 -03:00
Guilherme Pereira ff335f779f improve color mixing of snacks 2025-10-30 13:25:37 -03:00
Guilherme Pereira b70316e347 switch the snacks’ colors to be based on food colors again 2025-10-30 10:05:30 -03:00
Guilherme Pereira a352e67c1b lots of bugs and rowap berry effect 2025-10-29 21:42:55 -03:00
Guilherme Pereira 71297dfb3a fix nearby check for poke snack 2025-10-29 18:46:08 -03:00
Guilherme Pereira 9141694c2a Merge branch 'main' of gitlab.com:cable-mc/cobblemon into poke-snack-spawner 2025-10-29 18:00:30 -03:00
Paul 1f8fa8cae3 Prevent snacks from spawning pokemon if no players are nearby 2025-10-27 13:50:33 +10:00
Paul 42e405530c Major rework of Spawner hierarchy, removed SpawnerManagers, moved pokesnacks to be manually ticked 2025-10-27 13:40:52 +10:00
dhi_holo 5e21ac94dc Merge branch 'main' into advancing-advancements 2025-10-25 17:13:13 +10:00
Guilherme Pereira c76dfc3130 refactor poke snacks to use random ticks 2025-10-25 00:29:06 -03:00
Guilherme Pereira cca9de04a7 avoid poke snack spawners behaving weirdly 2025-10-22 21:39:08 -03:00
Guilherme Pereira 78d47004bf remove dead code 2025-10-22 21:12:19 -03:00
Guilherme Pereira 30f97e6243 move poke snack spawner creation to poke snack spawner manager 2025-10-22 21:00:35 -03:00
Neovitalism d117d79d28 Removable Feature Rendering 2025-10-22 18:56:26 -05:00
Guilherme Pereira 3d4d797e7f add bite time effect to poke snacks 2025-10-22 15:08:58 -03:00
Guilherme Pereira 39feb9cf6c hook POI system to poke snacks 2025-10-22 13:53:48 -03:00
Guilherme Pereira 8f53757879 allow poke snacks to override the default pokemon per chunk spawn limit 2025-10-22 10:30:46 -03:00
Guilherme Pereira e1d2f125d6 add bucket multiplying influence to poke snacks 2025-10-22 10:00:59 -03:00
Guilherme Pereira fa3ed69ee2 move poke snack spawner to block entity 2025-10-22 03:38:07 -03:00
Guilherme Pereira 8c02ca3576 create poke snack spawner 2025-10-21 19:45:20 -03:00
dhi_holo 1d055253d2 Merge branch 'main' into advancing-advancements 2025-10-10 16:00:30 +10:00
dhi_holo d56c5520f9 Merge branch 'main' into advancing-advancements 2025-10-04 17:26:10 +10:00
dhi_holo 89bc893f06 gamerule.healersHealPC 2025-10-04 17:25:50 +10:00
dhi_holo acc8d066e5 stOre 2025-10-03 19:17:00 +10:00
dhi_holo 6608268117 Update cobblemon.json
fixed typo
2025-10-03 14:03:35 +10:00
dhi_holo bdecab25a6 Merge branch 'main' into advancing-advancements 2025-10-03 13:38:45 +10:00
dhi_holo 81ed97a68b Update cobblemon.json
Removed removed item, added new items
2025-09-30 11:03:26 +10:00
dhi_holo 1e051deb9e Update CHANGELOG.md 2025-09-29 18:06:37 +10:00
dhi_holo 38c54e255a Chromatic Upgrades
- Removed Vivichoke advancement
- Reworded Galar Fossil advancement
- Renamed Master Rod advancement, made hidden by default
- Name tweak for IV Candy advancement
- Description update for regional delicacy advancement
- Renamed Poke Bait advancement
- Description update to ride stats
- Removed Aprijuice advancement
- Combined interaction advancements
- Added Saccharine advancement
- Moved Poke Snack advancement
- Updated some icons for advancements
2025-09-29 15:34:14 +10:00
dhi_holo e7ad38d1df Interactions and Clean Up
Added more Interaction based advancements, moved some stuff around, cleaned up visuals and description for max ride stats
2025-09-28 23:13:59 +10:00
dhi_holo 67c0abea8f Better Brush Desc 2025-09-28 21:15:54 +10:00
dhi_holo 85c1543df1 More tweaks
Brushing Pokemon advancement now works swell, Aprijuice advancement good, started work on the concept for Max Ride Stats, still need to actually get a trigger for it though
2025-09-28 17:10:15 +10:00
dhi_holo f38a1f83e2 More
Started on Bait and Brush advancements, renamed A Luring Aroma
2025-09-28 00:36:02 +10:00
dhi_holo 28785a01f6 Update revive.json
Reduced output to 1
2025-09-26 20:04:08 +10:00
dhi_holo 01c4260763 Merge branch 'main' into advancing-advancements 2025-09-25 20:05:09 +10:00
dhi_holo 150b3eb178 Snack 2025-09-25 20:05:07 +10:00
dhi_holo 5ab52d37f2 Fix Typo 2025-09-25 19:50:26 +10:00
dhi_holo ce191fd4c7 3 New, Minor Reorg
New: Cooking Regional Delicacies, Cooking EV Mochi, Cooking Poké Snack
Cleaned Up: Any Plant no longer announces to chat, Battle Win is on root, Use Candy is on Place Campfire Pot (also moves IV Candy to that tree instead)
2025-09-24 19:34:20 +10:00
MoeBoy76 9a7e349101 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-09-23 09:33:46 +10:00
MoeBoy76 07a7d2a51a Statistics correctly register and if something goes wrong a more helpful crash should be thrown. 2025-09-23 09:33:28 +10:00
MoeBoy76 d2b192cb07 stats still don't register 2025-09-22 13:36:54 +10:00
MoeBoy76 d8e3e93a87 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-09-22 10:06:52 +10:00
MoeBoy76 af12df38ed stats should work for NF now 2025-09-22 10:05:03 +10:00
Konoha aee89f1c92 Preliminary Bag Clause implementation 2025-09-09 18:15:37 -04:00
MoeBoy76 7fb8268fae Lang tweaks 2025-08-04 10:38:54 +10:00
MoeBoy76 8b49eb1526 Stats work and Advancement fixes to match wiki 2025-08-04 10:19:25 +10:00
MoeBoy76 c6cdcf83a9 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-08-04 08:26:06 +10:00
MoeBoy76 4bf82083b4 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-04-28 09:02:44 +10:00
MoeBoy76 6579fd8ebe more stats work, they load now and have lang 2025-04-23 11:02:12 +10:00
MoeBoy76 4d62ef771a Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into getting-statistical 2025-04-23 10:11:33 +10:00
MoeBoy76 7784a3a20c initial stats work 2025-04-22 09:49:47 +10:00
4305 changed files with 138037 additions and 38490 deletions
+11
View File
@@ -0,0 +1,11 @@
### Additions
### Changes
- Replaced the entity AI for Pokémon and NPCs with an entirely custom one. Yeah we changed the entity AI in 1.7 too, you're remembering right.
- Improved performance of entity AI.
### Fixes
### Developer
### Molang & Datapacks
-26
View File
@@ -1,26 +0,0 @@
### Additions
- Rebuilt Pokémon AI to use Minecraft's Brain system, allowing for more complex behaviours and interactions.
- As an early pass of this, pastured Pokémon will now sleep when appropriate, and may come up to you when they see you.
- Probably also added a whole bunch of bugs.
- Dog Pokémon (Growlithe, Arcanine, etc.) intimidate Skeletons.
- Cat Pokémon (Meowth, Persian, etc.) intimidate Creepers and Phantoms.
- Sleep-related Pokémon (Munsharna, Komala, etc.) intimidate Phantoms.
- Some Pokémon naturally hunt each other.
- Some Pokémon herd together.
- Added a Behaviour Editor to the NPC editing screen.
- Added /behaviouredit command for opening the Behaviour Editor on Pokémon and NPCs.
- Editing variables for Pokémon is not yet supported.
### Developer
- baseScale in NPCs has been removed from classes and presets, and in the entity it is replaced with hitboxScale and renderScale.
- Added `EntityCallbacks` to `NPCEntity` and `PokemonEntity`. You can trigger custom callback types by using `[Entity].callbacks.process(...)`
### Fixes
- Fixed Pokémon with a moving walk target frequently spinning in place as they re-calculate their path.
### MoLang & Datapacks
- Added a `behaviours` datapack folder which motivates the Behaviour Editor screen on NPCs and Pokémon.
- Added "callback" support on PokemonEntity and NPCEntity that allows MoLang scripts to be executed in response to certain scenarios.
- Added very many behaviours to choose from.
- Removed many NPC presets that now exist as behaviours. This is a breaking change if you are using NPCs with these presets.
- NPCs with these presets should be modified to instead list under `"behaviours"` all the equivalent behaviours.
-35
View File
@@ -1,35 +0,0 @@
### Additions
- Added the Campfire Pot, made from apricorns and placed onto campfires.
- This pot can be used to make bait for fishing, Poké Cakes, Lure Cakes, local specialties, and potions (less efficiently than a brewing stand).
- There is a different pot for each apricorn colour because at this point I think we may have an addiction.
- Added Aprijuice, made from the Campfire Pot using apricorns with seasoning to give flavours.
- Aprijuice can be fed to ride-able Pokémon to improve their riding characteristics, depending on the flavour and the Pokémon's nature.
- Added Lure Cakes, made from the Campfire Pot using honey and berries.
- Lure Cakes can be used to modify the spawn rate of Pokémon in the wild.
- Added the Saccharine Tree, which can be found in the wild and is used to obtain Honey Bottles.
- The leaves of the tree can be harvested to obtain honey, which can be used in the Campfire Pot to make Lure Cakes.
- The Log of the tree can be interacted with using a honey bottle to create a Honey-Slathered Saccharine Log, which increases the change of spawning a Pokémon with a Hidden Ability.
- Added Hearty Grains
- Clicking on the Progress Arrow will show the JEI Recipe Book for the Campfire Pot, which will show all recipes that can be made with it.
- Added a Ton of Redstone Compatibility.
- Dispenser can now Honey and Unhoney:
- Saccharine Log
- Saccharine Leaves
- Redstone can Close and Open the Lid of a Cooking Pot
- Powered = Closed
- Unpowered = Open
- Hoppers can be used to insert items into a Cooking pot
- Top = Seasonals
- All Sides = Crafting
- Bottom = Extract the Result
- Observer will recognise when a Cooking pot is Closed or Opened
- Comparator Calculates a Signal Strength depending on the items inside the cooking pot
- Sculk Sensor
- Saccharine Leaves
- Opening and Closing the Cooking Pot
- Saccharine Log
### Datapack and Addon Changes
- Renamed the fishing_baits datapack folder to spawn_bait_effects.
- Added `seasonings` datapack folder for controlling usable items in the campfire pot and what colour and flavour they apply.
- Added campfire pot recipe type, which you could use to make anything work as fishing bait.
-13
View File
@@ -1,13 +0,0 @@
### Additions
- Added functionality for marks.
- Added data for all marks and ribbons from the mainline Pokémon games.
- Implemented fishing, personality, weather, and time related marks, that can rarely be granted to a wild-spawned Pokémon.
- Added marks screen within the summary UI.
- Added `/givemark <player> <partySlot> <mark>` command to give a mark to a Pokémon.
- Added `/takemark <player> <partySlot> <mark>` command to remove a mark from a Pokémon.
- Added `/giveallmarks <player> <partySlot>` command to give all available marks to a Pokémon.
### MoLang & Datapacks
- Added Flows for `bobber_spawn_pokemon_post`, `pokemon_entity_spawn`, and `fossil_revived`.
- Added `marks` datapack folder.
- Added MoLang functions `entity.is_in_rain`, `pokemon.add_marks(Mark...)`, `pokemon.add_potential_marks(Mark...)`, `pokemon.add_marks_with_chance(Mark...)`, `pokemon.apply_potential_marks`, and `world.is_snowing_at(x, y, z)`.
-38
View File
@@ -1,38 +0,0 @@
### Additions
- Added ability to rename PC Boxes by clicking on the name of a box.
- Added box options buttons for boxes, toggleable by clicking the right icon button in the bottom bar.
- The option buttons on the left side allow for sorting the box by name, level, Pokédex number, gender, and type. Shift clicking allows for sorting in reverse order.
- The button on the right allows for changing the box wallpaper.
- 10 additional color-based wallpapers have been added.
- 5 unlockable biome-based wallpapers have been added, which can be unlocked by visiting:
- Forest biome
- Ocean biome
- Cave Biome
- The End
- The Nether
- Added filter functionality in PC UI, which supports `PokemonProperties` (e.g. `shiny=yes` shows all shiny Pokémon).
- Names can be filtered by exact or partial matches, e.g. entering "cha" will show Charmander, Charmeleon, etc.
- Added `/changewallpaper <player> <boxNumber> <wallpaper>` command to change a box wallpaper through commands.
- Added `/renamebox <player> <boxNumber> <name>` command to rename a PC box through commands.
- Added IVs and EVs stat displays in PC.
- The displays can be cycled through by scrolling when the display is hovered over.
- Added ability to cycle through boxes by scrolling when the box is hovered over.
- PC will now open to last box viewed within a session.
### Changes
- Slots in pastures will now have darker backgrounds and italicised Pokémon names if the Pokémon is not owned by the player.
- The pasture slot will show the name of the Pokémon owner when hovered if the Pokémon is not owned.
- Increased the default PC box count from 30 to 40 to accommodate the fact that we have way more Pokémon now. If you've changed this config option then you'll need to edit it again after starting up with 1.7!
### Developer
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
- Added `ChangePCBoxWallpaperEvent.Pre` and `ChangePCBoxWallpaperEvent.Post` to prevent players from changing wallpapers or changing their selection.
- Added `WallpaperCollectionEvent` which gets called when clients connect to a server, allowing the server to handle which of the client-found wallpapers it's allowed to move (collected wallpapers can be removed for example to make it "vanish" client-side).
- Added `WallpaperUnlockedEvent`.
- Renamed `SetPCBoxPokemonPacket` and the respective handler to `SetPCBoxPacket`.
### Addons
- Added Flows for `player_tick_pre`, `player_tick_post`, `advancement_earned`, `right_clicked_entity`, `right_clicked_block`, `player_died`, `wallpaper_unlocked`.
- Flows now have `q.` for any context properties in addition to the `c.` properties, making it a bit more convenient when calling other scripts from Flows.
- Added `unlockable_pc_box_wallpapers` datapack folder for wallpapers that need to be unlocked before they're usable.
- Wallpapers are loaded from `assets/<namespace>/textures/gui/pc/wallpaper/` and all wallpapers in this folder are available to the client to choose by default.
-4
View File
@@ -1,4 +0,0 @@
### Additions
- Added the ability to ride Pokémon by shift-right clicking and selecting the ride option.
- Added /calculateseatpositions command for approximating hitbox locations for riding configurations.
-10
View File
@@ -1,10 +0,0 @@
### Additions
- Added support for NPCs to use Pokémon models and vice versa. This will require changes in addons that add fossil types due to naming conflicts between fossils and the Pokémon species.
- Added `/changejointscale` command to change the scale of a joint in a model. Unbelievably funny.
### Developer
- Removed all VaryingModelRepository subclasses into the parent class.
### Addons
- Added `transformedParts` to the root of poser JSONs so it now exists in both poses and the model overall.
-25
View File
@@ -1,25 +0,0 @@
### Additions
- Pokémon can now spawn in herds, either as distinct herd groupings or simply several Pokémon spawning at once.
### Fixes
- Fixed the "enabled" property in spawn files not actually being respected. Where do they find these devs?
- Fixed Terralith's shrubland not counting as plains for spawning purposes the way it was intended to.
### Developer
- Spawning Influences now have the context of what the other buckets are when adjusting bucket weights. This will break existing influences that do bucket weight adjustment.
- Renamed heaps of things in the spawning system to make more sense.
- SpawningContext is now SpawnablePosition
- WorldSlice is SpawningZone
- SpawningProspector is now SpawningZoneGenerator
- Majorly refactored the hierarchy of Spawner
- The base Spawner interface provides more functions to allow single-point and area spawning given appropriate inputs.
- TickingSpawner is removed in favour of outside code handling ticking logic.
- AreaSpawner is removed.
- BasicSpawner is the first implementation of Spawner which can be used for any purpose.
- PlayerSpawners are now mixin'd into ServerPlayer and ticked from ServerPlayer#tick.
- A hierarchy diagram can be found at `./docs/spawner-hierarchy.png` in the mod repository.
- The SpawnerManager class has been removed as its functionality is all now handled elsewhere.
- Renamed things in Spawn Rules to go with the other renames:
- contextSelector is now spawnablePositionSelector
- context is now spawnable_position
+40 -2986
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
## [1.0.0 (November 12th, 2022)](#1-0-0)
- Initial release.
+56
View File
@@ -0,0 +1,56 @@
## [1.1.0 - The Swim and Sleep Update (November 27th, 2022)](#1-1-0)
#### "Ideally not at the same time."
### Additions
- Added a new GUI for viewing party information, rearranging moves, and evolving Pokémon. It looks too good.
- Starter Pokémon will sleep on top of you if sent out when you get on a bed.
- Added sleeping animations for starters, the Weedle family, and the Caterpie family. More to come.
- Added Alolan Rattata and Alolan Raticate, Sableye, Deerling and Sawsbuck, and Pyukumukurutudulu or whatever it's called.
- Added swimming AI so Pokémon don't sink to the bottom in water.
- Aquatic Pokémon like Magikarp desperately move to water if they're on land.
- Added status condition indicators in the party overlay.
- Added HP labels to the battle interface so that you can see how much health you actually have.
- Added spawn data for all final and special evolutions previously lacking spawn data.
- Added shiny textures for many Pokémon (thank you MageFX!): Aerodactyl, Articuno, Zapdos, Moltres, Chansey, the Dratini family, Electabuzz, Goldeen and Seaking, Hitmonchan and Hitmonlee, Jynx, Kabuto and Kabutops, Magmar, Lickitung, Mr. Mime, Omanyte and Omastar, Rhyhorn and Rhydon, Koffing and Weezing, Porygon, Scyther, Seadra, Staryu and Starmie, and Tangela. Phew!
- Added a couple of new advancements.
- Added new items: Calcium, Carbos, HP Up, Iron, Protein, and Zinc. Currently only obtainable in Creative Mode (It's a surprise tool that will help us later).
### Changes
- Significantly improved AI pathing for larger entities so they won't keep trying to move to places they cannot possibly fit.
- Changed the starter menu and summary menu keybinds to `M` by default.
- Pokémon that are sent out slowly raise friendship. Before this it was faster and even worked when not sent out (wildly unbalanced).
- Updated Link Cable and Protector item sprites to be prettier.
- Slightly polished the Poké Ball opening and Poké Ball item use sounds.
- `/givepokemon random`, `/spawnpokemon random`, and `/spawnallpokemon` will now only choose implemented Pokémon.
- The battle message box now displays even when the battle GUI is minimised so that you can still see what's going on.
- Moved the `R` prompt in battle to be higher on the screen so that it's not as distracting.
### Fixes
- Fixed shinies and form variations not displaying in the party or PC.
- Fixed servers getting stuck on shutdown due to non-closed showdown server connections.
- Fixed a niche situation where players could challenge themselves. It's a little inspirational if you think about it.
- Fixed Pokémon natures not saving such that every time you restarted they had a totally different nature.
- Fixed some underground Pokémon spawning above ground instead. I'm told other weird spawns were probably fixed at the same time.
- Fixed Pokémon sometimes running in place. "It's still possible, but much less likely" - Yeah, ok devs.
- Fixed mod incompatibility with many Architectury API mods, including *Biome Makeover* and *Earth2Java*.
- Fixed a mod incompatibility with Minecraft Transit Railway Fabric and probably a bunch of other Fabric mods.
- Fixed being unable to customize keybinds on Forge.
- Fixed Summary keybinding being labeled as PokéNav. That comes later.
- Fixed apricorns spawning without leaves which meant sometimes apricorns were growing on the side of dirt and stone which doesn't make much sense to me.
- Fixed messages appearing in the console whenever a healer is used.
- Fixed spawning in several biome tag categories.
- Fixed resource pack support for Pokémon models and textures.
- **Model Fixes**
- Fixed Paras and Nidoqueen looking very weird.
- Fixed Hitmonchan asserting dominance with a T-pose as well as Grimer and Muk pointing their hands to the sky.
- Fixed specific Pokémon suddenly pausing their animation after staying still for a long time.
- Fixed Mankey's feet being buried in the ground.
- Updated the Substitute model and updated its shiny texture to be better for the red-green colorblind.
- Improved Horsea, Seadra, and Kingdra animations, especially on land.
- **Battle Fixes**
- Fixed an issue with battles where Pokémon had a different max HP causing some desync issues with the health bars.
- Fixed Magnitude battle messages.
- Moves that are disabled or out of PP now show transparently in the battle GUI instead of being hidden completely.
- Statuses like sleep and frozen no longer last forever if it was carried over from a previous battle.
### Localization
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
+3
View File
@@ -0,0 +1,3 @@
## [1.1.1 (November 27th, 2022)](#1-1-1)
### Fixes
- Fixed a critical issue with servers where Pokémon data didn't properly synchronize and so you couldn't see any.
+52
View File
@@ -0,0 +1,52 @@
## [1.2.0 - The Customization Update (January 1st, 2023)](#1-2-0)
#### "There are going to be so many fakemon..."
### Additions
- Added models for Natu and Xatu, Murkrow and Honchkrow, Wailmer and Wailord.
- Added new PC interface and it is beautiful.
- Reworked the battle system so that battles load faster, cause fewer bugs, and can run on shared server hosts. This is a very big change that also reduced the size of the mod by 50mb!
- Added full resource pack and data pack customization of models, textures, animations, spawning, and spawn file presets to make custom Pokémon species and variations very easy to create. You can find the guide for creating custom Pokémon on [our website](https://cobblemon.com/guides/custompokemon.html)!
- Added water surface spawning for Pokémon like Lapras.
- Added emissive texture support to Pokémon render layers.
- Added compatibility for Mod Menu ([CurseForge](https://www.curseforge.com/minecraft/mc-mods/modmenu), [Modrinth](https://modrinth.com/mod/modmenu)).
- Added blank ambient Pokémon cries so cries can be added via resource packs.
- Added new sounds for GUIs and item uses.
- Added `nature` and `pokeball` options to commands such as `/spawnpokemon` and `/givepokemon`.
### Changes
- Reinforced party and PC saving to make data corruption from crashes less bad.
- Added a config option for whether the starter config will be exported, making it more maintainable as we add starter Pokémon.
- Battles now start with the options menu open for convenience.
- Doubled the default charge rate of healers. You'd need to reset your config under `./config/cobblemon/main.json` to see this change!
- Changed the default Apricorn seed chance config value from 6% to 10%.
- The mod now correctly reports our dependency on Architectury API so people don't get super confused when things don't work.
- Pokémon now look at their opponents during battle.
- Updated Sableye's animations to be super freaky.
- Changed the healer advancements to make the healing machine's mechanics more obvious.
### Fixes
- Fixed an incompatibility with [Porting Lib](https://github.com/Fabricators-of-Create/Porting-Lib) used by Fabric ports of mods such as Create or Twilight Forest.
- Fixed HP and max HP values in the battle GUI not being correct.
- Fixed some animations on snake-type Pokémon being super slow.
- Fixed a typo in the English name for Calcium. Calcuim.
- Fixed Pokémon gradually becoming rarer around you if you move long distances.
- Fixed a shoulder mount crash on Fabric.
- Fixed a rare issue where chunks would take a really long time to generate.
- Fixed a singleplayer bug where battles wouldn't work after leaving then rejoining a world.
- Fixed stat calculations for everything except HP. HP was fine though :).
- Fixed a randomized Pokémon spawning in mountains that corrupted the data of whatever party or PC it got into. Yikes.
- Fixed a rare crash involving literally random number generation. A random crash involving random numbers.
- Fixed all regular Mewtwo having the stats and types of Mega Mewtwo X - same deal with many other Pokémon.
- Fixed the framing of many Pokémon in GUIs.
- Fixed texture glitches with Rattata and Nidoqueen (again!).
- Fixed dropped item forms of all Pokéballs and the Healing Machine, and slightly adjusted all other display settings
- Fixed issues with forms not showing the correct evolution in the evolution menu.
- Fixed some alternate forms not having the alternate stats and types.
- Fixed moves that only work in double battles not being selectable at all (such as Helping Hand and Aromatic Mist).
- Fixed abilities not remaining legal in some forms.
- Fixed Poké Ball capture effects not triggering after a successful capture, such as the Heal Ball's healing effect.
- Fixed multiple-hit moves sending gibberish into the battle chat.
- Fixed Pyukumuku not being appropriately scaled.
- Fixed shiny and other variations of Pokémon not showing in the battle GUI.
- Fixed Eevee being poorly positioned and un-animated on shoulders.
- Fixed a Pokémon's hitbox not updating when it evolves while sent out.
- Fixed a Pokémon's PP going from zero to above the maximum when entering another battle.
+150
View File
@@ -0,0 +1,150 @@
## [1.3.0 - The Foundation Update (March 17th, 2023)](#1-3-0)
#### "Now we can start doing the really cool stuff."
### Dependencies
- Upgraded Fabric API dependence to 0.75.1+1.19.2
- Upgraded Architectury API dependence to 6.5.69
- Cobblemon Forge now depends on Kotlin for Forge.
### Additions
- Added new models and animations for Poké Balls and reworked their mechanics to feel much smoother instead of being pure frustration.
- Added party scrolling via holding R and using the mouse wheel so you don't need to take your hand off your mouse.
- Added a cap of Pokémon spawns in an area because waiting a while made things insane. This is controlled by a new `pokemonPerChunk` config option.
- Added models and animations for heaps of Pokémon (101): Riolu, Lucario, Chimchar, Monferno, Infernape, Turtwig, Grotle, Torterra, Popplio, Brionne, Primarina, Treeko, Grovyle, Sceptile, Snivy, Servine, Serperior, Tepig, Pignite, Emboar, Oshawott, Dewott, Samurott, Grookey, Thwackey, Rillaboom, Scorbunny, Raboot, Cinderace, Sobble, Drizzile, Inteleon, Fennekin, Braixen, Delphox, Froakie, Frogadier, Greninja, Chespin, Quilladin, Chesnaught, Miltank, Torkoal, Kricketot, Kricketune, Heatmor, Durant, Wooloo, Dubwool, Pumpkaboo, Gourgeist, Sigilyph, Cryogonal, Whismur, Loudred, Exploud, Misdreavus, Mismagius, Tatsugiri, Eiscue, Luvdisc, Stantler, Wyrdeer, Gible, Gabite, Garchomp, Sneasel, Weavile, Elgyem, Beheeyem, Baltoy, Claydol, Nacli, Naclstack, Alcremie, Milcery, Dhelmise, Morelull, Shiinotic, Xerneas, Klink, Klang, Klinklang, Joltik, Galvantula, Honedge, Duoblade, Aegislash, Spiritomb, Mawile, Carvanha, Sharpedo, Seedot, Nuzleaf, Shiftry, Lotad, Lombre, Ludicolo, Pineco, Forretress, and Spinda.
- Added generation 3, 4, 5, 6, 7, and 8 Starter Pokémon to the starter select screen.
- Added particle effect support for model animations
- Added particle effect and animation for Gastly.
- Added sleep and faint animations to many Pokémon.
- Added item holding for Pokémon. Any Minecraft item can be given to a Pokémon by holding shift and right-clicking them. Traditional Pokémon held items will have their expected battle effects.
- Added heaps of held items with crafting recipes: Assault Vest, Big Root, Black Belt, Black Sludge, Charcoal, Choice Band, Choice Scarf, Choice Specs, Dragon Fang, Exp. Share, Focus Band, Hard Stone, Heavy-Duty Boots, Leftovers, Light Clay, Lucky Egg, Magnet, Miracle Seed, Muscle Band, Mystic Water, Never-Melt Ice, Poison Barb, Quick Claw, Rocky Helmet, Safety Goggles, Sharp Beak, Silk Scarf, Silver Powder, Soft Sand, Spell Tag, Twisted Spoon, and Wise Glasses.
- Added heaps of evolution items with crafting recipes: Milcery's sweets items, Chipped Pot, Cracked Pot, Deep Sea Scale, Deep Sea Tooth, Dragon Scale, Galarica Cuff, Galarica Wreath, Peat Block, Prism Scale, Razor Claw, Razor Fang, Reaper Cloth, Sachet, Sweet Apple, Tart Apple, and Whipped Dream.
- Existing evolution items all now either have a crafting recipe or drop from Pokémon.
- Added the Item [tags](https://minecraft.fandom.com/wiki/Tag) `cobblemon:held/experience_share` and `cobblemon:held/lucky_egg` allowing you to mark any items you desire to have the effects implied in the tag name.
- Added an interface that appears when interacting with your Pokémon while sneaking. The interface allows for interactive options such as shouldering and exchanging held items.
- Added blinking animations to many Pokémon.
- Added animated texture support.
- Added translucent option for aspect layers.
- Added glowing textures to many Pokémon and it looks amazing.
- Added the Saturation shoulder effect.
- Added the Haste shoulder effect, initially for Joltik.
- Added the Water Breathing shoulder effect, initially for Wooper.
- Added the Speed shoulder effect, initially for Pichu and Pikachu.
- [Dispensers](https://minecraft.fandom.com/wiki/Dispenser) can now use shears to automatically harvest fully grown Apricorns.
- Added milking to Miltank.
- Added shearing to Wooloo and Dubwool.
- Added data for generation 9 Pokémon species, moves, and ability data. They're all still Substitute models, but their moves and abilities work.
- Added support for custom Pokémon to implement 'quirks' such as blinks.
- Added sound effect for harvesting Apricorns.
- Added icon to summary and PC interfaces to indicated if a Pokémon is shiny.
- Added the `/spawnpokemonat <pos> <properties>` command, the `pos` argument uses the same syntax as the Minecraft [summon](https://minecraft.fandom.com/wiki/Commands/summon) command.
- Added the `/giveallpokemon` command which is definitely safe and not insane.
- Added compatibility with Carry On by preventing the mod being able to interact with Cobblemon entities, the mod caused too many gameplay detrimental features to stay enabled.
- Added healing to your party when you sleep in a bed.
- Added the 'ability' Pokémon Property so commands can specify the ability.
- Added block tag support to the 'neededBaseBlocks' and 'neededNearbyBlocks' spawn condition.
- Added a config option for disallowing players from damaging Pokémon by hand.
- Apricorn seeds can now be used with the [Composter](https://minecraft.fandom.com/wiki/Composter), these have the layer increase chance of 65% like Apricorns and various Minecraft crops.
- Added support for Pokémon species data appending making it so datapack developers no longer need to overwrite files.
- Added an implementation of every [catch rate](https://bulbapedia.bulbagarden.net/wiki/Catch_rate) from generation 1 to 9, these can be used by changing the `captureCalculator` config value:
- `generation_1` Sets the calculator to the generation 1 implementation.
- `generation_2` Sets the calculator to the generation 2 implementation.
- `generation_2_fixed` Sets the calculator to the generation 2 implementation with the status multiplier bug fixed.
- `generation_3_4` Sets the calculator to the generation 3 and 4 implementation.
- `generation_5` Sets the calculator to the generation 5 implementation.
- `generation_6` Sets the calculator to the generation 6 implementation.
- `generation_7` Sets the calculator to the generation 7 implementation.
- `generation_8` Sets the calculator to the generation 8 implementation.
- `generation_9` Sets the calculator to the generation 9 implementation.
- `cobblemon` Sets the calculator to the custom Cobblemon implementation. This is the default value.
- `debug` Sets the calculator to the debug/cheat implementation, every attempt will be a successful critical capture.
### Changes
- Pokémon now save to the world by default, meaning the same Pokémon will remain in the world and not disappear after you log out and log back in. They still despawn over time though.
- Significantly sped up the Poké Ball shake animation so it takes less time to try to catch Pokémon.
- Update the PC and Healing Machine models and bounding boxes.
- The Healing Machine and PC now emit light when fully charged or when turned on respectively.
- The PC block screen will now turn on when being used.
- The Healing Machine will now visually display its charge level using 6 stages.
- The Healing Machine will now emit a redstone signal with the strength of 1 for every 10% charge it has when attached to a [Redstone Comparator](https://minecraft.fandom.com/wiki/Redstone_Comparator).
- Made it so that particles are not shown whenever you have a shoulder Pokémon that gives potion effects.
- Changed hitbox and size definitions for Decidueye, Blastoise, and Magmortar
- Apricorns can now be harvested with Axes, the speed will scale with enchantments and tool material, only dropping the Apricorn if fully grown, these will still destroy the Apricorn so the manual harvest still is recommended unless you're just keen on destroying trees.
- Apricorns are now a part of the vanilla tag `minecraft:blocks/mineable/axe`.
- Apricorns are now compatible with any mod that breaks a whole tree at once.
- Apricorns no longer have a config value for the seed drop chance these are now a part of their loot table which can be found in `cobblemon/loot_tables/blocks/<color>_apricorn.json`.
- Advancements were redone to be slightly more interesting, with improved names, descriptions, and sorting.
- Updated models and textures for Tentacool line, Gengar, Slowpoke line, Tyrogue line, Doduo line, Dratini, Dragonair, Quagsire, and Piplup line. There were probably others, the team lost track.
- Improved sending out Pokémon at the start of battle so that they are positioned in a less annoying way.
- Name Tags will no longer be used on Pokémon and Poke Ball entities, this prevents the item from being wasted.
- Lowered spawn rate of Tauros.
- Sableye now spawns near gem ores as well as amethyst.
- Added evolution stones and items to item tags
- Pokémon now play their cry animations when clicked on the starter selection screen.
### Fixes
- Fixed catch rates being entirely too difficult.
- Fixed various strange battle issues such as Flying types being vulnerable to Ground type moves and status effects hitting despite vulnerabilities.
- Fixed shiny Gyarados not using the red Gyarados texture.
- Improved the framing of all in-game Pokémon in the party and PC GUIs so they aren't halfway out of the screen or something else crazy.
- Fixed incompatibility with Kotlin for Forge (by depending on Kotlin for Forge ourselves)
- Fixed Gengar, Goodra, and many other Pokémon showing the types of an alternate form despite those not being modelled yet.
- Fixed datapack Pokémon not being able to battle.
- Fixed Pokémon always being created with a moveset as if they're level 1 instead of their current level.
- Fixed an issue of Pokémon not rendering in GUIs on some Mac displays.
- Fixed a soft-duplicate that could occur when a party Pokémon is pushed through a Nether Portal or left in a boat.
- Fixed Pokémon that faint from poison appearing to be on full health and suckering you into false hope.
- Fixed incorrect spawns of Tentacool, Tentacruel, Dragonite, Politoed, Tangrowth, Lickilicky, Electivire, and Magmortar.
- Fixed crashes involving opening the Pokémon summary GUI with an empty party.
- Fixed lower brightness settings causing Pokémon to appear much too dark in menus such as the party and PC.
- Fixed Showdown sometimes failing to start, causing crashes.
- Fixed Showdown initialization happening several times when you login, more depending on how many times you have relogged this session.
- Fixed Showdown failing to update on first attempt. We totally weren't accidentally deleting our target directory or anything, nope.
- Fixed HP recovery related battle actions not animating for the client nor updating the in-game Pokémon HP.
- Fixed moves that force a switch such as Teleport and U-Turn soft locking battles.
- Fixed missing battle text for Bide, Speed Boost, Belly Drum, Anger Point, and Haze.
- Fixed battle messages for many field effects starting, ending, and actions caused by them such as blocking certain moves.
- Improved battle messages for effects that prevent a move from being executed such as a Taunt, requiring a recharge, flinched, etc.
- Fixed move names not being translated in battle messages.
- Fixed stat change messages for boosts over 3 stages.
- Fixed experience calculation not being completely accurate.
- Fixed positioning of Poké Balls when rendered in Healing Machines.
- Fixed a desync issue on servers where all Pokémon seemed like they were special forms when they weren't.
- Fixed an incompatibility with [Exordium](https://www.curseforge.com/minecraft/mc-mods/exordium).
- Fixed datapack Pokémon language key generation. A Pokémon under the namespace `example` named `Pogemon` will now correctly look for the lang key `example.species.pogemon.name`.
- Fixed client not receiving messages for the different "stages" for the move Bide.
- Fixed the Medium Slow and Medium Fast experience group IDs, they're now `medium_slow` and `medium_fast`. Any custom datapack Pokémon will require an update.
- Fixed Pokémon friendship being capped to the maximum level config value instead of the friendship one when loading Pokémon data.
- Fixed Poké Balls taking forever to capture Pokémon if you are underwater or up in the air where it takes a long time to hit the ground.
- Fixed Pokémon being unable to spawn on blocks such as snow layers.
- Fixed Pokémon spawning inside of trees.
- Fixed Pokémon experience not loading after a restart and instead going back to the minimal amount for the current level.
- Fixed being able to use `/healpokemon` in battle.
- Fixed being able to select fainted party members in the switch menu causing the battle to lock.
- Fixed `/spawnpokemon` command not supporting any command source other than players.
- Fixed issues with Charizard's sleep pose.
- Fixed players being able to use multiple healer machines at once.
- Fixed Pokémon layers not rendering when a Pokémon is on your shoulder.
- Fixed Caterpie and Weedle not moving or looking at players. That was meant to be Metapod and Kakuna; how embarrassing.
- Fixed Pokémon not carrying over the correct equivalent original ability when evolving from stages that only had one ability.
- Fixed Deerling and Sawsbuck not spawning with the correct season.
- Fixed issue of not being able to drag the scroll bar in summary and battle interfaces.
- Fixed optional aspects not saving and loading properly.
- Fixed layering logic so multiple texture layers can exist on a Pokémon (probably).
- Fixed not all Poké Balls being associated with the `cobblemon:pokeballs` item tag.
- Fixed the `/pokemoneditother` command not working.
- Fixed ambient sound file path for Porygon2.
- Fixed forms not being able to unset the secondary type of a Pokémon in the stat JSON.
- Fixed moves that haven't carried over from generation 8 onwards having the description they did in the generation 8 games instead of their last valid one.
- Fixed shoulder mounted pokemon not returning to party on healer use and on evolution
### Developer
- Reworked CatchRateModifier, as such, existing implementations need to be updated.
- Fixed minimumDistanceBetweenEntities option being half of what it's set as.
- Fixed the contents of CobblemonEvents, CobblemonBlocks etc having getters instead of just being public static properties.
- Added ApricornHarvestEvent.
- Added a new item for representing Pokémon within native UI menus or item frames which display as the Pokémon's model. It's called a PokemonItem, with static functions to build one.
### Localization
- Added complete translations for French, German, Simplified Mandarin, Brazilian Portuguese, and Pirate English.
- Added partial translations for Traditional Mandarin, Italian, and Spanish. We'd love more help with this!
- Thank you to all of the fantastic volunteer translators for taking the time to help with this!
+96
View File
@@ -0,0 +1,96 @@
## [1.3.1 (March 31st, 2023)](#1-3-1)
### Additions
- Added Slugma, Magcargo, Nosepass, and Probopass.
- Elgyem family now drops Chorus Fruit, Geodude family now drops Black Augurite.
- Added missing spawn files for Golett and Bergmite family.
- Apricorns can now be smelted into dyes.
- Added animations to Staryu line and Porygon line.
- Added faint animations to Klink line.
- Add lava surface spawn preset.
- Added an `any` evolution requirement allowing you to define `possibilities` of other evolution requirements, for example, this allows you to create an evolution that requires the Pokémon to be shiny or a female.
- Added the `/spawnpokemonfrompool [amount]` or `/forcespawn [amount]` command to spawn Pokémon(s) in the surrounding area using the natural spawn rates/pool of that area, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.spawnpokemon` if a permission mod is present. On a successful execution of the command, the amount of Pokémon spawned will be the output.
- Added the `/pokebox` and `/pokeboxall` commands to move Pokémon(s) to the PC from a Player's party, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.pokebox` if a permission mod is present. On a successful execution of the command the output will be the number of pokemon moved to the Player's PC.
- Added the `/pc` command which opens up the PC UI the same way interacting with the block would, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.pc` if a permission mod is present.
### Changes
- You can now click the portraits of other Pokémon in the starter selection screen to navigate directly to them.
- You can now click the right and left arrow keys to navigate PC boxes.
- Link Cables will now require Pokémon to hold any held item normally required for their evolution.
- After a battle, the last Pokémon used now becomes the selected one in your party.
- The `/teach` command can now only allow the Pokémon to be given moves in their learnset, this can be controlled with the permission `cobblemon.command.teach.bypass`, to account for that change the base command now requires the permission `cobblemon.command.teach.base`, this change is meant only for people using a mod capable of providing permissions such as [LuckPerms](https://luckperms.net/).
- Apricorns will no longer collide with their block form when picked, this should improve the experience in automatic farms.
- Increased spawn chances for many Pokémon requiring specific blocks to be nearby.
- Put Cryogonal in more snowy biomes.
- Ditto as well as the Eevee, Gible, and Riolu families have been made more common.
- Lowered spawn rate of Gyarados on the surface of water.
- Apricorn leaves can now be used in the [Composter](https://minecraft.fandom.com/wiki/Composter) block, these have the same chance to raise the compost pile the Minecraft leaves do.
- Updated Gengar's model and texture.
- Updated Swinub line model and animations.
- Tweaked portrait frames for the Pidgey line and for Walking Wake.
- Changed all buff shoulder effects to only give a level 1 buff instead of level 2.
- Made Weavile a little bigger.
- Changed the recipes for Mystic Water, Miracle Seed, and Charcoal Stick to utilise the evolution stones, as well as Never-Melt Ice having an alternate recipe using the Ice Stone.
- Replaced the `Failed to handle` battle messages to `Missing interpretation` to make it more clear that mechanics do work just still pending dedicated messages.
- Healing Machine and PC are now mine-able with pickaxes and Apricorn leaves are mine-able using hoes.
### Fixes
- Fixed killing a Dodrio killing your game. Dodrio will never look the same to us.
- Fixed non-Fire-type Pokémon being immune to lava.
- Fixed custom Pokémon not being usable in battle, properly. A last minute fix caused this to break again; what are these devs not paid for?
- Fixed being locked in an endless healing queue if you broke the healing machine during use.
- Fixed an issue with the experience calculation when the Exp. Share is held.
- Fixed Friendship-based attacks not using friendship values from your Pokémon.
- Fixed Link Cables consuming held items they shouldn't due to not validating the held item of a Pokémon.
- Fixed a crash when Aromatherapy cured the status of party members.
- Fixed moves learnt on evolution not being given when said evolution happens. If you were affected by this issue your existing Pokémon will now be able to relearn those moves.
- Fixed console spam when rendering Pokémon model items.
- Fixed battle messages for 50+ moves and abilities and items.
- Fixed the possible duplicate when capturing Pokémon (probably, this one's hard to reproduce to confirm it's fixed).
- Previously duplicated Pokémon are cleaned from PCs and parties on restart.
- Fixed an issue with some particle effects applying after a Pokémon has died or on top of the wrong Pokémon when using specific mods.
- Fixed Pokémon not looking at each other in battle.
- Fixed Experience Candy and Experience Share attempting to bring Pokémon above level cap causing crashes.
- Fixed level 100 Pokémon having experience go over the cap total amount they should have.
- Fixed `/pokemonspawnat` having the argument positions reverted making it impossible for Brigadier to understand when to suggest coordinates. It is now the intended `/spawnpokemonat <pos> <properties>`.
- Fixed performance issues with shouldered Pokémon in certain systems.
- Fixed learnset issues for Pokémon whose only modern debut was LGPE/BDSP/LA.
- Fixed shiny Zubat, Grimer, Omanyte, Elgyem, Delphox and Aegislash displaying their normal texture.
- Fixed sleeping in beds allowing fainted Pokémon to receive experience after a battle ends somehow.
- Fixed an issue where a Pokémon will claim to have learnt a new move they already have in their moveset when learnt at an earlier level in their previous evolution. I realize that's confusing.
- Fixed Dispensers not being able to shear Wooloo. This will also extend to other mods that check if an entity is valid to shear.
- Fixed the currently held item of your Pokémon not dropping to the ground when removing it if your inventory was full.
- Fixed creative mode allowing you to make your Pokémon hold more than 1 of the same item.
- Fixed a Pokémon duplication glitch when teleporting between worlds.
- Fixed dedicated servers being able to reload Cobblemon data with the vanilla `/reload` command causing unintended behavior for clients.
- Fixed underground Pokémon spawning above ground.
- Fixed Pokémon portrait not reverting back to the Pokémon after a failed capture during battle.
- Fixed edge texture artifacts on pane elements for Tentacool and Tentacruel models.
- Fixed crash caused by Pokémon pathing
- Fixed Pokémon not returning to their balls when being healed in a healing machine
- Fixed all Gen IX Pokémon as well as forms added in PLA and Wyrdeer, Kleavor, Ursaluna, Basculegion, Sneasler, Overqwil, and Enamorus having 0 exp yields.
- Fixed Irons Leaves having bluetooth back legs. If you saw it, you know what I mean.
- Fixed Golurk not having shoulder plates on its shoulders.
- Fixed some water Pokémon walking onto land from the water even though they are fish.
- Fixed Porygon2 and PorygonZ being too small.
- Fixed Snivy line head look animation.
- Fixed Staryu line not being able to swim.
- Fixed an incompatibility with [Thorium](https://modrinth.com/mod/thorium) patch for [MC-84873](https://bugs.mojang.com/browse/MC-84873).
- Fixed Pidgeotto wings when walking.
- Fixed Delphox walk animation.
- Fixed Froakie line sleep animations in battle.
- Fixed Pokémon missing the non-level up moves they could relearn when rejoining a world until a new move was added to their relearn list.
- Fixed instantly fleeing from Pokémon set to be unfleeable.
- Fixed Pumpkaboo line forms not working. (Currently sizes aren't visual but check base stats to see which size you have.)
- Fixed a bug that caused already interpreted messages for moves to be mistaken as uninterpreted.
- Fixed a Pokémon spawner bug that caused Pokémon to not spawn due to dropped item entities.
- Fixed a bug that causes Pokémon model items to be invisible.
### Developer
- Add events that are fired just before and after a Pokémon is released (ReleasePokemonEvent.Pre and .Post)
### Localization
- Added complete translations for Japanese, Thai, and Canadian French.
- Added partial translations for Russian, Ukrainian, Mexican Spanish, and Korean.
- Updated every existing language's translation.
- All the translators that contributed are amazing.
+443
View File
@@ -0,0 +1,443 @@
## [1.4.0 - The Friends and Farms Update (October 13th, 2023)](#1-4-0)
#### "No, we don't provide the friends."
### Additions
- Added pasture blocks, used to let your PC Pokémon roam around an area.
- Added nicknaming from the summary menu of a Pokémon (click their name).
- Added trading between players. Press R while looking at another player and you'll figure the rest out.
- Added mints for changing Pokémon stats. These are most commonly found at high altitudes.
- Added [Revival Herbs](https://wiki.cobblemon.com/index.php/Revival_Herb), with pep-up flowers when fully grown, growing in lush caves.
- Added [Medicinal Leeks](https://wiki.cobblemon.com/index.php/Medicinal_Leek), growing on the surface of rivers and ponds. It is a potion ingredient and can be cooked as food!.
- Added [Big Roots](https://wiki.cobblemon.com/index.php/Big_Root), generating from cave ceiling dirt which sometimes spread as energy roots.
- Added [69 Berry Trees](https://wiki.cobblemon.com/index.php/Berry_Tree) and [Berries](https://wiki.cobblemon.com/index.php/Berry). Some are found in village farms, some from planting different berries close to each other.
- Added mulches: Mulch Base, Growth Mulch, Surprise Mulch, Coarse Mulch, Humid Mulch, Rich Mulch, Loamy Mulch, Peat Mulch, and Sandy Mulch
- Added [Vivichokes](https://wiki.cobblemon.com/index.php/Vivichoke), obtainable from wandering villager trades and some loot chests.
- Added medicine brewing using medicinal leeks and berries in brewing stands.
- Added Pokémon cries when in battles and being sent out.
- Added medicinal items: Berry Juice, Heal Powder, Remedy, Fine Remedy, Superb Remedy, Revive, Max Revive, Potion, Super Potion, Hyper Potion, Max Potion, Full Restore, Full Heal, Antidote, Awakening, Burn Heal, Ice Heal, and Paralyze Heal.
- Added battle items: X Attack, X Defence, X Sp.Atk, X Sp.Def, X Speed, Dire Hit, and Guard Spec.
- Added EV items: Power Anklet, Power Band, Power Belt, Power Bracelet, Power Lens, Power Weight.
- Added food items: Roasted Leek, Leek and Potato Stew, Braised Vivichoke, and Vivichoke Dip
- Added evolution items: Auspicious Armor and Malicious Armor, which can be used to evolve Charcadet into Armarouge or Ceruledge respectively.
- Added (mostly brewing) recipes for HP Up, Protein, Iron, Calcium, Zinc, Carbos, PP Up, PP Max, and Medicinal Leek to Magenta Dye.
- Added held items: Bright Powder, Destiny Knot
- Added AI for Nosepass to point towards world spawn when idle. We just think it's neat.
- Added shoulder mounting for Mimikyu.
- Added flying placeholder animations to Pidgey, Pidgeotto, Pidgeot, Golbat, Crobat, Scyther, Scizor, Zapdos, Moltres, Articuno, Dragonite, Rowlet, Dartrix, and Decidueye.
- Added loot to various vanilla chest loot tables (Link Cable in Ancient Cities, Woodland Mansions, End Cities, and Igloos, Vivichoke Seeds in Jungle Temples, Dungeons, and Plains, Savanna, Snowy, and Taiga Villages, and all 7 Apricorn Sprouts in Desert, Plains, Savanna, Snowy, and Taiga Villages, as well as the Bonus Chest, which can also have 5 of the basic Poké Ball types)
- Added a `doShinyStarters` gamerule to make it quick and easy to be offered shiny starters.
- Added a `doPokemonLoot` gamerule to toggle Pokémon dropping items/exp on death.
- Added ability activation announcement when in battle.
- Added animations for Wailord and made it BIGGER.
- Added Cherry Torterra variant.
- Added 2 new face spots for Spinda. The number of unique Spindas increases...
- Added Forretress Shulker variant.
- Added the `/teststore <player> <store> <properties>` command allowing command block/mcfunction users to query a party, PC or both for Pokémon matching specific properties and returning the match count, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.teststore` if a permission mod is present.
- Added the `/querylearnset <player> <slot> <move>` command allowing command block/mcfunction users to query a party slot and check if the Pokémon can learn a specific move returning a 1 if yes otherwise 0, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.querylearnset` if a permission mod is present.
- Added the `/testpcslot <player> <slot> <properties>` command allowing command block/mcfunction users to query a pc slot and check if the Pokémon matches specific properties returning a 1 if yes otherwise 0, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.testpcslot` if a permission mod is present.
- Added the `/testpartyslot <player> <slot> <properties>` command allowing command block/mcfunction users to query a party slot and check if the Pokémon matches a specific properties returning a 1 if yes otherwise 0, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.testpartyslot` if a permission mod is present.
- Added the `/clearparty <player>` command for emptying a player's party.
- Added the `/clearpc <player>` command for emptying a player's PC.
- Added the `/pokemonrestart <reset_starters>` and the `/pokemonrestartother <player> <reset_starters>` command allowing command block/mcfunction users to reset a players Pokémon data.
### Pokémon Added
#### Gen 2
- Chikorita
- Bayleef
- Meganium
- Totodile
- Croconaw
- Feraligatr
- Cyndaquil
- Quilava
- Typhlosion
- Spinarak
- Ariados
- Shuckle
- Chinchou
- Lanturn
- Aipom
- Gligar
- Hoothoot
- Noctowl
- Mareep
- Flaaffy
- Ampharos
- Sudowoodo
- Snubbull
- Granbull
- Phanpy
- Donphan
- Teddiursa
- Ursaring
#### Gen 3
- Taillow
- Swellow
- Relicanth
- Duskull
- Dusclops
- Shroomish
- Breloom
- Cacnea
- Cacturne
- Poochyena
- Mightyena
- Wingull
- Pelipper
- Numel
- Camerupt
- Clamperl
- Huntail
- Gorebyss
- Surskit
- Masquerain
- Chimecho
- Barboach
- Whiscash
- Volbeat
- Illumise
- Zigzagoon
- Linoone
- Ralts
- Kirlia
- Gardevoir
- Nincada
- Ninjask
- Shedinja
- Beldum
- Metang
- Metagross
#### Gen 4
- Carnivine
- Shinx
- Luxio
- Luxray
- Ambipom
- Gliscor
- Dusknoir
- Chingling
- Bonsly
- Chatot
- Combee
- Vespiquen
- Buizel
- Floatzel
- Starly
- Staravia
- Staraptor
- Gallade
#### Gen 5
- Bouffalant
- Roggenrola
- Boldore
- Gigalith
- Venipede
- Whirlipede
- Scolipede
- Yamask
- Cofagrigus
- Patrat
- Watchog
- Lillipup
- Herdier
- Stoutland
- Cottonee
- Whimsicott
- Pidove
- Tranquill
- Unfezant
- Timburr
- Gurdurr
- Conkeldurr
#### Gen 6
- Scatterbug
- Spewpa
- Vivillon
- Skrelp
- Dragalge
- Bunnelby
- Diggersby
- Phantump
- Trevenant
- Fletchling
- Fletchinder
- Talonflame
#### Gen 7
- Wishiwashi
- Cutiefly
- Ribombee
- Stufful
- Bewear
- Comfey
- Alolan Exeggutor
- Alolan Raichu
- Alolan Meowth
- Alolan Persian
- Komala
- Wimpod
- Golisopod
- Crabrawler
- Crabominable
- Mudbray
- Mudsdale
#### Gen 8
- Arrokuda
- Barraskewda
- Nickit
- Thievul
- Falinks
- Galarian Farfetch'd
- Sirfetch'd
- Rookidee
- Corvisquire
- Corviknight
- Galarian Ponyta
- Galarian Rapidash
- Yamper
- Boltund
- Galarian Zigzagoon
- Galarian Linoone
- Obstagoon
- Galarian Meowth
- Perrserker
- Ursaluna
#### Gen 9
- Sprigatito
- Floragato
- Meowscarada
- Fuecoco
- Crocalor
- Skeledirge
- Quaxly
- Quaxwell
- Quaquaval
- Flittle
- Espathra
- Garganacl
- Fidough
- Dachsbun
- Armarouge
- Ceruledge
- Cetoddle
- Cetitan
- Shroodle
- Grafaiai
- Tandemaus
- Maushold
- Varoom
- Revavroom
- Squawkabilly
- Glimmet
- Glimmora
- Annihilape
- Tinkatink
- Tinkatuff
- Tinkaton
- Maschiff
- Mabosstiff
- Lechonk
- Oinkologne
- Paldean Wooper
- Clodsire
### Changes
- Removed the existing shoulder effects from Pokémon until we have more balanced versions of them (they're too powerful!)
- Updated models and textures of Weedle, Dwebble and Crustle, Spiritomb, Koffing and Weezing, Kadabra and Alakazam, Emolga, Oshawott, Doduo and Dodrio, Dratini and Dragonair and Dragonite, Sneasel and Weavile, Gyarados, Hitmonlee and Hitmonchan, Chesnaught, Spinda, Mamoswine, Steelix, Misdreavus and Mismagius, Buneary and Lopunny, Golduck, Meowth and Persian, Fennekin and Braixen and Delphox, Snivy and Servine and Serperior, Ratatta and Raticate, Nidorina and Nidoqueen, Nidoran Male and Nidoking, Riolu and Lucario, Haunter and Gengar, Mankey and Primeape, Mew and Mewtwo, Arcanine, Magnemite and Magneton and Magnezone, Exeggcute and Exeggutor, Elekid and Electabuzz and Electivire, Pichu and Pikachu and Raichu, Wooper, Drowzee and Hypno, Aerodactyl, Spearow and Fearow, Lickitung and Lickilicky, Pidgey and Pidgeotto and Pidgeot, Scyther and Scizor and Kleavor, Popplio and Brionne and Primarina, Torchic and Combusken and Blaziken, Happiny and Chansey and Blissey.
- Updated animations for Steelix, Turtwig and Grotle and Torterra, Ponyta and Rapidash, Piplup and Prinplup and Empoleon, Drowzee and Hypno, Farfetch'd, Exeggcute and Exeggutor, Bidoof, Chimecho, Lickitung and Lickilicky, Popplio and Brionne, Luvdisc, Chimchar and Monferno and Infernape, Sobble and Drizzile and Inteleon, Greninja, Heatmor, Aerodactyl, Ditto, Lotad and Lombre and Ludicolo, Pumpkaboo and Gourgeist.
- Updated sprites for EV medicines, the rare candy, and the apricorn door item.
- Updated textures for apricorn doors and all the evolution stone ores.
- Ponyta and Rapidash now have animated textures; they look insane.
- Updated Apricorn Leaves color.
- Wild Pokémon now heal if you are defeated by them or flee from them.
- Doubled the default time between ambient Pokémon cries (they have cries if you're using a resource pack to add them)
- Moved spawn attempts per tick to a config option (ticksBetweenSpawnAttempts)
- PCs can now be waterlogged
- Starter selection prompt now appears as a tutorial-esque toast instead of plain text
- Reorganised the advancements recipes folder
- Pokéedit command now supports IVs and EVs.
- Reorganised creative categories
- Pokémon can now wander into non-solid blocks such as foliage
- Thrown Poké Balls now despawn after 30 seconds so that they don't fly forever.
- Dive Balls will now have the same motion speed underwater as if they were thrown in the air.
- Hardcoded potion shoulder effects have been removed. You can now use any potion vanilla or otherwise with the parameters you'd like, for more information see the [Datapack & Resourcepack Creators](#datapack-&-resourcepack-creators) section.
- Clicking categories of the Stat subsection or the party reorder button in the Summary screen will now produce a click sound.
- Updated PC Recipe.
- Improved Pokémon AI and movement.
- Friendship will slowly increase when Pokémon are shoulder-mounted.
- Master Balls are now unable to be burned when dropped into fire/lava. They're made from stronger stuff.
- Pokémon will appear red when hurt, like regular entities, except when they're fainting.
- Pokémon's air meter no longer depletes while battling underwater.
- Sleeping partially restores PP of Pokémon
- Shoulder mounts now match the shoulder position a bit more accurately when sneaking.
- Poison Heal will now cause poisoned Pokémon to heal outside of battle.
- Updated Poké Ball, PC, UI, evolution and Healing Machine sounds.
### Added cries to the following Pokémon:
- All starters and their evolutions
- Caterpie, Metapod, Butterfree
- Weedle, Kakuna, Beedrill
- Pidgey, Pidgeotto, Pidgeot
- Rattata, Raticate
- Spearow, Fearow
- Ekans, Arbok
- Pichu, Pikachu, Raichu, Alolan Raichu
- Cleffa, Clefairy, Clefable
- Mankey, Primeape, Annihilape
- Ponyta, Rapidash, Galarian Ponyta, Galarian Rapidash
- Farfetch'd, Galarian Farfetch'd, Sirfetch'd
- Onix, Steelix
- Tauros
- Ditto
- Eevee, Vaporeon, Jolteon, Flareon, Espeon, Umbreon, Leafeon, Glaceon, Sylveon
- Hoothoot, Noctowl
- Mareep, Flaaffy, Ampharos
- Aipom, Ambipom
- Wooper, Quagsire, Clodsire
- Snubbull, Granbull
- Miltank
- Poochyena, Mightyena
- Taillow, Swellow
- Ralts, Kirlia, Gardevoir, Gallade
- Shroomish, Breloom
- Nincada, Ninjask, Shedinja
- Buneary, Lopunny
- Chingling
- Chatot
- Riolu, Lucario
- Pidove, Tranquill, Unfezant
- Roggenrola, Boldore, Gigalith
- Venipede, Whirlipede, Scolipede
- Maractus
- Dwebble, Crustle
- Yamask, Cofagrigus
- Bunnelby, Diggersby
- Fletchling, Fletchinder, Talonflame
- Scatterbug, Spewpa, Vivillon
- Honedge, Doublade, Aegislash
- Skrelp, Dragalge
- Phantump, Trevenant
- Pumpkaboo, Gourgeist
- Bergmite, Avalugg
- Mudbray, Mudsdale
- Stufful, Bewear
- Mimikyu
- Rookidee, Corvisquire, Corviknight
- Nickit, Thievul
- Wooloo, Dubwool
- Yamper, Boltund
- Tandemaus
- Fidough, Dachsbun
- Squawkabilly
- Nacli, Naclstack, Garganacl
- Charcadet, Armarouge, Ceruledge
- Maschiff, Mabosstiff
- Shroodle, Grafaiai
- Flittle, Espathra
- Tinkatink, Tinkatuff, Tinkaton
- Varoom, Revavroom
- Glimmet, Glimmora
- Cetoddle, Cetitan
- Tatsugiri
### Fixes
- Fixed spawning moon phase dependent Pokémon only when the moon phase is wrong (that's a funny woopsy)
- Fixed large Pokémon spawning partially inside walls where they suffocate.
- Fixed custom Pokémon in your party or PC not being removed when the addon is removed, causing major issues.
- Fixed messages for entry hazards, screens, weather, damage, healing, Tailwind, Perish Song, Destiny Bond, Shed Skin, Uproar, Forewarn, Disguise, Arena Trap, Yawn, Curse, Clamp, Whirlpool, Liquid Ooze, Miracle Eye, Safeguard, Magic Bounce, Lock On, Focus Energy, Confusion, and more.
- Fixed Porygon not evolving with an Upgrade.
- Fixed super sized Pumpkaboo not having any moves.
- Fixed Infernape look animation.
- Fixed Garchomp T-posing while swimming which was very funny.
- Fixed a bug that caused sleeping Pokémon to stay asleep. Forever. The years passing them by as they dream of a world without hate...
- Fixed a bug that would freeze a battle when a Pokémon gets trapped by an ability, making the trap abilities even scarier and trap-like than they were before.
- Fixed the Poké Ball close animation canceling whenever colliding with a block.
- Fixed lighting and Pokémon label issues when a Pokémon item frame is nearby.
- Fixed Pokémon being able to spawn outside the world border as a tease.
- Fixed deepslate water stone ore items looking like deepslate fire stone ores. Huh?
- Fixed a bunch of client-side logging errors when Pokémon are shoulder mounted. You didn't notice? Good.
- Fixed a crash when wild Pokémon have to struggle under specific circumstances.
- Fixed uncolored pixels on Yanma's shiny texture.
- Fixed apricorn tree leaves looking gross on the Fast graphics mode.
- Fixed hoes not breaking apricorn tree leaves any faster.
- Fixed Shiftry's PC model position.
- Fixed the `/pc` command not playing the opening sound.
- Fixed different forms of Pokémon not being able to appear as different sizes.
- Fixed the Healing Machine soft locking you from using others when removed by non-players.
- Fixed animations being sped up when using the Replay Mod.
- Fixed particle animations not running when a Pokémon is off-screen.
- Fixed Pokémon variants and layers not rendering correctly when shouldered and playing on a dedicated server, existing shoulders affected will need to be retrieved and shouldered again.
- Fixed shoulder effects not staying applied through situations that remove potion effects such as drinking milk.
- Fixed Shedinja not being able to recover naturally.
- Fixed Shedinja evolving to use the consumed Poké Ball and removed the held item to prevent dupes.
- Fixed Shedinja healing above 1 HP.
- Fixed Shedinja, basically.
- Fixed shearing Pokémon dropping 0-2 wool instead of 1-3.
- Fixed some alignment issues in the stat hexagon of the summary menu. OCD people rejoice.
- Fixed capture calculations not applying ball bonuses entirely correctly.
- Fixed battles soft-locking when consecutive Pokémon faint on switch-in.
- Fixed timing and color of battle window messages.
- Fixed players being able to trade, battle and let out their Pokémon while in spectator mode.
- Fixed Galarian Yamask not being able to evolve and by proxy the `damage_taken` evolution requirement.
- Fixed Bisharp not being able to evolve and by proxy the `defeat` evolution requirement.
- Fixed White-Striped Basculin not being able to evolve because of a broken `recoil` evolution requirement.
- Fixed Primeape, Qwilfish and Stantler not being able to evolve because of a broken `use_move` evolution requirement.
- Fixed Bramblin, Pawmo, and Rellor not being able to evolve because of a broken `blocks_traveled` evolution requirement.
- Fixed displayName property in spawn files not doing what it's meant to do.
- Fixed Pokémon not sleeping in the wild like we wanted them to.
### Developer
- Added SpawnEvent, ThrownPokeballHitEvent, PokemonSentEvent, PokemonRecalledEvent.
- Added BattleFledEvent, BattleStartedEvent, BattleFaintedEvent.
- Added persistent NBT property inside Pokémon to store quick and simple data.
- Species and FormData have had their evolutions, pre-evolution and labels properties exposed. It is still recommended to work using a Pokémon instance when possible.
- Added capture check to BattleVictoryEvent.
- The various hardcoded potion shoulder effects have been removed, make use of PotionBaseEffect.
- Added ContextManager for tracking causes and contexts of conditions created during a battle. See BattleContext for types of conditions that are tracked.
- Added MongoDB support for storing Pokémon and Player data. Must be enabled in config, requires MongoDB core and sync drivers (4.10.0+).
- CobblemonShowdown updated to version 10.
- Generation of a battle can be set in BattleFormat.
- Pokémon now have `teraType`, `dmaxLevel`, and `gmaxFactor` properties. Gimmicks can be used during battle by adding the respective identifiers to `keyItems` in PlayerData: `key_stone`, `z_ring`, `dynamax_band`, and `tera_orb`. Dynamax is only supported in Gen 8 battles. Mega Evolution and Z-Power require custom held items to be added (e.g. an item with the path `gengarite` will allow Gengar to Mega Evolve). Currently custom Z-Crystals and Mega Stones are not supported.
### Datapack & Resourcepack Creators
- All potion related shoulder effects have had their IDs changed. They now all share the same type being `potion_effect` and use the vanilla Potion data [parameters](https://minecraft.fandom.com/wiki/Potion#Item_data). For example, here is the converted Pidgey asset:
- `json
{
"type": "potion_effect",
"effect": "minecraft:slow_falling",
"amplifier": 0,
"ambient": true,
"showParticles": false,
"showIcon": false
}
`
- Renamed the `walked_steps` evolution requirement to `blocks_traveled`.
- Added support for scale in animations.
- Added support for jump keyframes (i.e. pre and post keyframes)
- Added structure spawning conditions
- Added Advancement trigger for defeating Pokémon and collecting varieties of Pokémon.
- Added support for "isBattle" and "isTouchingWater" properties on resource pack Pokémon poses. This allows your custom Pokémon to be posed differently when in battle.
- Added support for "isVisible" on a transformed part on resource pack Pokémon poses. This allows your custom Pokémon to have bones disappear in specific poses, such as hiding Greninja's throwing star when not in a battle pose.
- Added support for battle music. Sounds can be added to the `battle.pvp.default` and `battle.pvw.default` sound events.
- Added 'enabled' optional property on model layers, allowing later variations to disable previously-defined layers. See [this issue](https://gitlab.com/cable-mc/cobblemon/-/issues/335) for how this looks.
- Cobblemon items can now all have their own tooltips via resourcepacks. To add a tooltip, add a lang entry like "item.cobblemon.{item_id}.tooltip". If you want to add multiple tooltip lines you can do so with "item.cobblemon.{item_id}.tooltip_1" and upwards.
- Item interaction evolutions and held item requirements now support NBT by creating an object JSON containing the key `item` for what used to be the existing condition support and a `nbt` key for the NBT format, this is the string [format](https://minecraft.fandom.com/wiki/NBT_format) expected in commands. Existing data does not need to be updated.
- Fixed faint animations not working properly in add-ons.
- Fixed non-existent species in spawn pool files causing random species to spawn.
### Localization
- Added partial translations for Dutch, Polish, Swedish, Hungarian, Czech, Cyprus Greek, and even Esperanto.
- Updated translation for French and Canadian French, Simplified Chinese, Japanese, Korean, Spanish and Mexican Spanish, Pirate English, German, Thai, Turkish, Portuguese and Brazilian Portuguese, Ukrainian, and Russian.
+130
View File
@@ -0,0 +1,130 @@
## [1.4.1 (December 23rd, 2023)](#1-4-1)
### Additions
- Added battle spectating. Press R on a player in a battle and you can spectate and bully them for their tactics.
- Added the Litwick and Drifloon lines.
- Cobblemon now has compatibility with [Adorn](https://modrinth.com/mod/adorn), allowing you to craft Apricorn wood furniture.
- Berries can now be used in recipes from [Farmer's Delight](https://modrinth.com/mod/farmers-delight) and [Farmer's Delight (Fabric)](https://modrinth.com/mod/farmers-delight-fabric), as well as any other mods using the same berry tags.
- Boats, signs and hanging signs are now craftable with Apricorn wood.
- Added the Fairy Feather, Iron Ball, Cleanse Tag, Flame Orb, Life Orb, Smoke Ball, and Toxic Orb held items.
- Added the Inferno, Void, and Forsaken patterns for Vivillon. These can be obtained by evolving a Spewpa in the Nether, End, or Deep Dark respectively.
- Bees can now be fed using Pep-Up Flowers.
- Mooshtank can now be milked with a bowl for Mushroom Stew.
- Updated Showdown version to use generation 9 battle data.
- Added cries to Beldum, Metang and Metagross.
- Added a `/bedrockparticle` command to run Snowstorm-format particle effects.
- Added data for Dipplin, Fezandipiti, Munkidori, Ogerpon, Okidogi, Poltchageist and Sinistcha.
- Added additional nickname trigger "Grumm" for Inkay's evolution.
### Changes
- Using Potions, Status Heals, Ethers, and Antidotes will now return a glass bottle
- Using a Remedy, Fine Remedy, or Superb Remedy will no longer lower friendship with a Pokémon.
- The Healing Machine now has a [much more difficult recipe](https://wiki.cobblemon.com/index.php/Healing_Machine), placing it later game.
- Made the EXP. Share recipe cheaper.
- Turtwig can now be put on your shoulder.
- Updated Zubat line model, texture, and animations.
- Updated Geodude line models and textures.
- Added animations for Hitmontop, Tyrogue, and Mightyena.
- Tweaked animations for Dusknoir, Ratatta, Bewear, Exeggutor, and Alolan Exeggutor.
- Sized Kantonian Exeggutor down. Still big, but not TOO big.
- Tweaked cries for Pikachu, Raichu and Alolan Raichu.
- Fixed Swimming behaviors for Wimpod line, Oshawott line, Quaxly line, and Clodsire
- Changed the way level scaling works in spawning. By default, anything with a spawn range of up to 5 either side of the party highest level and everything else will spawn per its specified ranges.
- The nature of Pokémon will now be displayed italicized when a mint has been applied. Hovering over the nature will display the mint that was applied.
- Slightly lowered the volume of all cries.
- Giving Pokémon items now plays a sound
- Updated the Poké Ball model and animations.
- Pasture blocks will now also connect their bottom left and right sides to walls, iron bars, glass panes, and any other modded block that follows the same connection rules.
- The config option `consumeHeldItems` has been removed, please see the Datapack & Resourcepack Creators section for instructions on the updated method.
- Heal Powder can now be composted with a 75% chance of adding a layer
- Mental, Power, White, and Mirror Herbs can now be composted with a 100% chance of adding a layer.
- Added glowing eyes to Hoothoot and Noctowl.
- Mining Evolution Stone Ores with a Fortune pickaxe will now increase the amount of items received.
- Black Augurite can now be used to craft stone axes and obsidian.
- Using Experience Candies brings up the Party Pokémon Select screen when not targeting a Pokémon.
- Added tab completion for statuses to commands.
- Remedies can now be cooked in a Smoker and on a Campfire.
- Vertically flipped the Destiny Knot recipe.
### Fixes
- Fixed Raticate, Onix, Unfezant, Bergmite, Avalugg, Boltund and Revavroom cries not playing.
- Fixed Alolan Ratticate animations causing a crash.
- Fixed Quaxwell not doing its cry.
- Fixed Shroomish not using its idle.
- Fixed how Weight and Height is calculated for Pokémon, fixing the damage from moves like Low Kick.
- Fixed a staggering number of battle messages.
- Fixed various stone related blocks not being valid for Big Roots to spread onto on the Fabric version.
- Updated the registration of compostable items to improve compatibility with Fabric forks such as Quilt. Please note this does not mean we officially support Quilt, this change was only done since it was possible by correcting the registration to use the new intended way in the Fabric API.
- Fixed Dispensers being unable to shear grown Apricorns.
- Fixed Bowl not being given back to player after using Berry Juice
- Fixed missing text for attempting to catch an uncatchable Pokémon
- Fixed Moonphases for Clefairy line
- Fixed issue where Potions, Super Potions, and Hyper Potions did not work during battle
- Fixed the compatibility patch with the Forge version of [Carry On](https://modrinth.com/mod/carry-on) due to a bug on the mod, the Fabric version was unchanged and is still compatible.
- Added the ability to place Berries on modded Farmland blocks.
- Shouldered Pokémon now hop off when selected in team and R is pressed. This also is in effect in battles leading to shouldered Pokémon jumping of the shoulder of the trainer when it is their turn.
- Made more items compostable and changed the process for making items compostable.
- Added the ability for Hoppers to fill Brewing Stands with Medicinal Brews and Potions.
- Apricorn blocks are now flammable. Probably should have started that way, but we got there.
- The default pose for Pokémon being passengers is now "standing".
- Fixed issue where some IVs were changing every time a player logged back in.
- Fixed advancement crash from bad datapack evolution data.
- Fixed global influences being applied to TickingSpawners twice.
- Reverted the default SpawningSelector back to FlatContextWeightedSelector. This fixes multiple weight related issues, including weights with SpawningInfluences.
- Apricorn Planting advancement should work again.
- Advancement "Vivillonaire" should now allow High Plains and Icy Snow Vivillon to register.
- Fixed the last battle critical hits evolution requirement not working.
- Fixed the damage taken evolution requirement not saving progress.
- Fixed the defeated Pokémon evolution requirement not saving progress.
- Fixed potion brewing recipes not showing up JEI and similar mods on the Forge version.
- Fixed an exploit that could convert a single piece of Blaze Powder into an extra Medicinal Brew on the Forge version.
- Fixed an issue where health percentages would show incorrectly after healing
- Fixed the move Revival Blessing not allowing you to select from fainted party members.
- Fixed villagers not being able to pick up and plant mint seeds, vivichoke seeds, and revival herbs.
- Fixed Exeggcute faint.
- Fixed various spawn configuration issues across the board.
- Fixed a possible visual duplication of sent out Pokémon.
- Fixed battle text for Trace, Receiver, and Power of Alchemy.
- Fixed tooltips being appended too late in items.
- Fixed battles ending background music when battle music is not present.
- Fixed battles ending background music, instead of pausing, when battle music is played.
- Fixed a bunch of regionals to actually be obtainable, namely the unmodelled ones
- Fixed battle text for moves that were missing.
- Fixed a formatting error that affected Pokémon nicknames when the storage type is JSON.
- Fixed a crash that could occur on some servers relating to chunk loading and teleporting.
- Fixed an issue with Inkay's evolution requirement.
- Fixed conflicting evolution requirements that would cause the Ocean, River, Sun, and Tundra variants of Vivillon to be unobtainable through evolution.
- Fixed the Modern variant of Vivillon not being obtainable through evolution.
- Fixed Pokémon pathing through berry bushes, harming themselves in the process.
### Developer
- Fixed the `SpawnEvent` not respecting usage of `Cancelable#cancel`.
- Added the `EvolutionTestedEvent`, this allows listening and overriding the final result of evolution requirement tests.
- Rebuilt the scheduling API to more clearly force side choices and allow more local temporal frames of reference for tasks.
- Added utility script that can be used to generate all Spawn JSONS for all pokemon from the spawning spreadsheet in 1 click ([cobblemon_spawn_csv_to_json.py](utilityscripts%2Fcobblemon_spawn_csv_to_json.py)).
- The `HeldItemManager` has a new method `shouldConsumeItem`, this will return false by default to prevent breaking changes, see the documentation and update your implementations as needed.
- Added and implemented minSkyLight and maxSkyLight as config options for SpawnConditions
- Player specific battle themes can now be assigned to `PlayerData#battleTheme`.
- Changed design of `BattleStartedPreEvent`. Will now expose the `PokemonBattle`.
### Datapack & Resourcepack Creators
- Added 3 new item tags: `cobblemon:held/consumed_in_npc_battle`, `cobblemon:held/consumed_in_pvp_battle` & `cobblemon:held/consumed_in_wild_battle` these will determine which items get consumed in the implied battle types by Cobblemon, keep in mind the controller for this behaviour can be overriden by 3rd party.
- Unique wild encounter themes can now be associated with a specific species (or form) by assigning a SoundEvent identifier to the `battleTheme` field in the species' data configuration.
- Added a `structure` evolution condition, used to check if a Pokémon is in a given structure.
### Localization
- Updated translations for:
- French and Canadian French
- Simplified and Traditional Chinese
- Spanish and Mexican Spanish
- Pirate English
- German
- Thai
- Portuguese and Brazilian Portuguese
- Polish
- Italian
- Dutch
- Ukrainian
- Russian
Thank you so much to all of our community translators that bring the mod to the rest of the world!
+362
View File
@@ -0,0 +1,362 @@
## [1.5.0 - The Ruins and Revival Update (May 12th, 2024)](#1-5-0)
#### "You're telling me that Mojang has added archaeology to the game? Hmm... that gives me an idea."
### Additions
- Added 17 ruin structures, where you can find Pokémon-themed Armor Trims and Pottery Sherds, Tumblestones, and more.
- Added 23 fossil structures, where you can brush Suspicious Sand/Gravel for [Fossils](https://wiki.cobblemon.com/index.php/Fossil). You can add [custom fossils using datapacks](https://wiki.cobblemon.com/index.php/Fossils_File).
- Added the Data Monitor, Fossil Compartment, and Restoration Tank blocks. Placed in the correct formation, you can use these to create a [Restoration Machine](https://wiki.cobblemon.com/index.php/Resurrection_Machine) where you can bring fossils back to life. Use organic material to fill the tank first!
- Added 3 variants of [Tumblestone](https://wiki.cobblemon.com/index.php/Tumblestone), which can be planted near Lava or Magma to grow harvestable Tumblestone Clusters.
- Added Tumblestone Blocks, a storage block crafted from 9 Tumblestones.
- Added Ancient Poké Balls, which are aesthetic variants crafted from Tumblestones.
- Added the Ancient Feather, Wing, and Jet Balls, which fly further than regular Poké Balls.
- Added the Ancient Heavy, Leaden, and Gigaton Balls, which are heavier and don't fly as far as regular Poké Balls. These will receive more functionality in a future update.
- Added visual effects for many Poké Balls when sending out or capturing Pokémon.
- Added a new send-out ball toss animation that showcases the ball used for the Pokémon.
- Added simple move animations for Pokémon in battle with a proof of concept (Flamethrower) for more complicated animations. More and more specific animations will come in future updates.
- Added Original Trainer to the summary menu. To edit the OT through commands, you must specify originaltrainertype=<Player/NPC>, and originaltrainer=<Username or UUID/NPC Name>
- Added support for planting Apricorn trees, berries, and mints in [Botany Pots](https://modrinth.com/mod/botany-pots)
- Added the hidden "True Vivillionaire" advancement.
- Added the [Display Case](https://wiki.cobblemon.com/index.php/Display_Case) block. Use it to display your archaeological findings, Poké Balls, or other items.
- Added 6 Pokémon-themed Pottery Sherds, obtained from ruin structures. Sherds... sh-erds. Weird word.
- Added a Pokémon-themed armor trim, obtained from ruin structures.
- Added Nether Fire Stone Ore to, surprisingly, the Nether.
- Added Terracotta Sun Stone Ore to Badlands biomes.
- Added the EV Boosting Feathers.
- Added [Gilded Chests](https://wiki.cobblemon.com/index.php/Gilded_Chest), available in all Apricorn colors.
- Added Relic Coins, Relic Coin Pouches, and Relic Coin Sacks. Gimmighoul might be interested in these.
- Added Type Gems. These will have additional uses later, so you should start collecting them.
- Added new held items: Ability Shield, Absorb Bulb, Air Balloon, Binding Band, Blunder Policy, Cell Battery, Covert Cloak, Damp Rock, Eject Button, Eviolite, Expert Belt, Float Stone, Focus Sash, Heat Rock, Icy Rock, Iron Ball, Light Ball, Loaded Dice, Red Card, Shell Bell, Sticky Barb, Smooth Rock, Soothe Bell and Weakness Policy.
- Added Hisui starters to the starter selection menu. They come inside of ancient Poké Balls.
- Added a bubble quirk to Krabby that only plays during clear sunsets. It looks familiar...
- Added forfeit option to PVP battles.
- Added visual changes for entities affected by Illusion, Imposter, or Transform in battle.
- Added shoulder mounting for Squirtle, Ralts, Roggenrola, Charcadet, Sizzlipede, Litwick, Cutiefly, Flabebe, Flittle, and Scatterbug
- Added species data for Hydrapple, Iron Boulder, Iron Crown, Pecharunt, Raging Bolt, and Terapagos
- Added various new tags for search-ability and better mod compatibility.
- Added the [Ability Capsule](https://bulbapedia.bulbagarden.net/wiki/Ability_Capsule) and [Patch](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch). These have no way of getting them (for now) and only work as intended with the traditional ability format of 1 to 2 common abilities and 1 hidden ability.
### Pokémon Added
#### Gen 2
- Sentret
- Furret
- Qwilfish
- Heracross
- Skarmory
- Larvitar
- Pupitar
- Tyranitar
#### Gen 3
- Lileep
- Cradily
- Anorith
- Armaldo
- Tropius
- Roselia
- Aron
- Lairon
- Aggron
- Solrock
- Lunatone
- Makuhita
- Hariyama
- Trapinch
- Vibrava
- Flygon
#### Gen 4
- Shieldon
- Bastiodon
- Cranidos
- Rampardos
- Budew
- Roserade
- Hippopotas
- Hippowdon
#### Gen 5
- Tirtouga
- Carracosta
- Archen
- Archeops
- Zorua
- Zoroark
- Petilil
- Lilligant
- Darumaka
- Darmanitan
- Woobat
- Swoobat
- Sandile
- Krokorok
- Krookodile
- Frillish
- Jellicent
- Cubchoo
- Beartic
- Deino
- Zweilous
- Hydreigon
- Larvesta
- Volcarona
- Alomomola
- Ferroseed
- Ferrothorn
#### Gen 6
- Tyrunt
- Tyrantrum
- Amaura
- Aurorus
- Goomy
- Sliggoo
- Goodra
- Carbink
- Flabébé
- Floette
- Florges
- Klefki
#### Gen 7
- Turtonator
- Fomantis
- Lurantis
- Salandit
- Salazzle
- Jangmo-o
- Hakamo-o
- Kommo-o
- Alolan Diglett
- Alolan Dugtrio
#### Gen 8
- Gossifleur
- Eldegoss
- Arctozolt
- Arctovish
- Dracozolt
- Dracovish
- Basculegion
- Hisuian Decidueye
- Hisuian Typhlosion
- Hisuian Samurott
- Hisuian Lilligant
- Hisuian Sliggoo
- Hisuian Goodra
- Hisuian Zorua
- Hisuian Zoroark
- Hisuian Voltorb
- Hisuian Electrode
- Hisuian Qwilfish
- Overqwil
- Hisuian Sneasel
- Sneasler
- Stonjourner
- Cufant
- Copperajah
- Dreepy
- Drakloak
- Dragapult
- Impidimp
- Morgrem
- Grimmsnarl
#### Gen 9
- Gimmighoul
- Using Relic Coins, you can increase Gimmighoul's Coin Stash. Upon reaching 999, it can be evolved into Gholdengo.
- Additionally, if you give Gimmighoul a Netherite Scrap, you can increase its Netherite Stash. But what will that do to when you evolve it?
- Gholdengo
#### Cobblemon Exclusives
- Hisui Bias Rowlet
- Hisui Bias Dartrix
- Hisui Bias Cyndaquil
- Hisui Bias Quilava
- Hisui Bias Oshawott
- Hisui Bias Dewott
- Hisui Bias Goomy
- Hisui Bias Petilil
These are our compromise for having both regular and Hisuian forms of these Pokémon in the game. Hisui Biased variations will evolve into the Hisuian evolutions under most conditions. They are otherwise purely cosmetic differences.
### Added cries to the following Pokémon
- Alolan Raticate
- Vulpix, Ninetales
- Zubat, Golbat, Crobat
- Meowth, Persian
- Psyduck, Golduck
- Growlithe, Arcanine
- Geodude, Graveler, Golem
- Doduo, Dodrio
- Seel, Dewgong
- Muk, Grimer
- Krabby, Kingler
- Voltorb, Electrode, Hisuian Voltorb, Hisuian Electrode
- Tangela, Tangrowth
- Snorlax
- Cubone, Marowak
- Koffing, Weezing
- Aerodactyl
- Elekid, Electabuzz, Electivire
- Omanyte, Omastar
- Kabuto, Kabutops
- Lapras
- Scyther
- Hisui Bias Cyndaquil, Hisui Bias Quilava
- Igglybuff
- Yanma, Yanmega
- Gligar, Gliscor
- Qwilfish, Hisuian Qwilfish, Overqwil
- Sneasel, Hisuian Sneasel, Weavile, Sneasler
- Larvitar, Pupitar, Tyranitar
- Swinub, Piloswine, Mamoswine
- Aron, Lairon, Aggron
- Trapinch, Vibrava, Flygon
- Cacnea, Cacturne
- Barboach, Whiscash
- Lileep, Cradily
- Anorith, Armaldo
- Tropius
- Chimecho
- Bidoof, Bibarel
- Buizel, Floatzel
- Gible, Gabite, Garchomp
- Hisui Bias Oshawott, Hisui Bias Dewott
- Petilil, Lilligant, Hisui Bias Petilil, Hisuian Lilligant
- Basculin, Basculegion
- Sandile, Krokolok, Krookodile
- Darumaka, Darmanitan
- Archen, Archeops
- Zorua, Zoroark, Hisuian Zorua, Hisuian Zoroark
- Tyrunt, Tyrantrum
- Amaura Aurorus
- Carbink
- Goomy, Sliggoo, Goodra, Hisui Bias Goomy, Hisuian Sliggoo, Hisuian Goodra
- Klefki
- Hisui Bias Rowlet, Hisui Bias Dartrix
- Komala
- Impidimp, Morgrem, Grimmsnarl
- Cufant, Copperajah
- Dreepy, Drakloak, Dragapult
- Dracozolt, Arctozolt, Dracovish, Arctovish
- Lechonk, Oinkologne
- Maushold family of three and four
### Changes
- Alolan Pikachu and Exeggcute changed to Alola Bias.
- Pokémon now transition more smoothly between different poses.
- Updated models for Mimikyu, Alcremie, Squirtle, Wartortle, Blastoise, Pidgey, Pidgeotto, Pidgeot, Omanyte, Omastar, Growlithe, Arcanine, Nidoran Male, Nidoran Female, Lapras, Swinub, Piloswine, Basculin, Rowlet, Dartrix, Decidueye, Kabuto, Kabutops, Piplup, Prinplup, Elekid, Electabuzz, Cubone, Marowak, Paras, Mawile, Drifloon, Drifblim, Venonat, Venomoth, Yanma, Yanmega, Psyduck, Dusknoir, Diglett, Dugtrio, Natu, Xatu, Oshawott, Samurott, Torchic, Grovyle, Sceptile, Sizzlipede, Mismagius, and Raboot.
- Updated animations for Squirtle, Wartortle, Blastoise, Pidgey, Pidgeotto, Diglett, Dugtrio, Magikarp, Dragonite, Omanyte, Omastar, Kabuto, Pinsir, Chinchou, Lanturn, Ralts, Kirlia, Gardevoir, Gallade, Buizel, Garchomp, Pumpkaboo, Falinks, Lechonk, Litwick, Lampent, Chandelure, Carnivine, Galarian Meowth, Galarian Rapidash, Venonat, Venomoth, Phanphy, Donphan, Dratini, Dragonair, Happiny, Chansey, Blissey, Volbeat, Illumise, Numel, Sizzlipede, Centiskorch, Obstagoon, Timburr, Gurdurr, Conkeldurr, Drifloon, and Drifblim.
- Resized Drifloon.
- Added more held items to the held item tag, and Metal Coat to the held item tab.
- Added all ores to the modloader ore tags, and added tags for each ore type to the mod (both blocks and items).
- Changed the Destiny Knot to be crafted with a Ghast Tear rather than a diamond. We have big plans for the Destiny Knot...
- You can now punch grown apricorns to harvest them. We saw so many content creators breaking apricorns with their fists that it was making us die inside.
- The "Poké Ball" Vivillon variant is now obtainable by evolving a Spewpa after obtaining the "Aspiring Vivillionaire" advancement.
- Renamed the "Vivillionaire" advancement to "Aspiring Vivillionaire"
- Removed the Inferno, Forsaken, Poké Ball, and Void patterns from the Aspiring Vivillionaire advancement.
- Updated the biome tags for Spewpa's evolutions into the various Vivillon patterns. You should mostly be getting one evolution option at a time now.
- Apricorn Sprouts can now be planted directly on Apricorn leaves to create a new Apricorn of the same color.
- Added tooltips to interaction GUIs to make it clearer what they do.
- Poké Ball recipes now use tags for their center ingredient, rather than specifically Copper Ingots, Iron Ingots, Gold Ingots, and Diamonds, allowing for further datapack customisation and mod compatibility.
- Starter Toast now closes once the corresponding button is pressed once.
- Moved some items into the vanilla Food & Drinks category.
- Stacked Cobblemon Potion Bases can now be quick moved into Brewing Stands.
- Changed the Healing Machine recipe to swap the Max Revive for a Revive so that it is a bit easier to craft.
- Upped the rate that Gastly drop Ghast Tears from 2.5% to 5%, further helping the crafting of a Healing Machine.
- Pokémon with a low Blaze Powder drop chance now drop it more frequently in the Nether.
- Reorganised a few advancements.
- Pokémon entity shadows now scale when the Pokémon is being sent out or recalled.
- Remade Torkoal particles, now they only appear when in battle.
- Improved the shiny icon within summary and PC interfaces.
- Changed the Poison Barb sprite so that it doesn't look like a sword when held. It's a Poison Barb, not a Poison Sword. Wait, that gives me an idea.
- Moon Stone ore generates more frequently in Taigas and has been added to Magical and Spooky biomes. Ooo... Sorry.
- Density, Season, and Nether biome tags have been moved and renamed within the biome tags directory.
- Added particles to Lucario when in battle. Lucario is special.
- Movesets updated for Blueberry DLC.
### Fixes
- Re-added the recipe for the Iron vitamin. Well, technically it's a mineral.
- Fixed Exeggcute and Pikachu not being able to evolve.
- Fixed evolution priority for Exeggcute and Pikachu regional evolutions. Using a thunder stone on Kantonian Pikachu on the beach will give Alolan Raichu. A second thunder stone would then give Kantonian Raichu.
- Fixed battle text for the Poison Touch Ability.
- Finally found Sudowoodo and Bonsly. They were missing spawn data. Same with Drifloon and Litwick. Uh... sorry about that.
- Fixed Squawkabilly forms not being recognized.
- Fixed the bounce animation for Poké Balls being delayed by like, a full second. It's enough to drive you mad.
- Note blocks now play the correct sound on the Apricorn Plank-based blocks.
- Fixed an issue with transformed parts in posers causing whacky positional issues.
- Fixed Poké Balls freezing in an open state if you're looking away at the moment that it's meant to close. This actually fixes some other things but it's hard to explain.
- Fixed thrown Poké Balls technically having no name.
- Fixed very many issues with Bedrock particle effects. There are probably many more. Life goes on.
- Fixed Arbok patterns not being as specific in spawning as they were intended to be.
- Fixed Pokémon not avoiding danger at all when pathfinding.
- Fixed Pokémon pathing over snow layers and carpets.
- Fixed the Sobble line not being able to swim or breathe underwater.
- Fixed mod incompatibility with [Just Enough Resources](https://modrinth.com/mod/just-enough-resources-jer).
- Fixed mod incompatibility with [Visual Overhaul](https://modrinth.com/mod/visual-overhaul).
- Fixed an issue that allowed Pokémon to spawn on rails.
- Fixed the data set on Pokémon when abilities are given via properties such as in `/spawnpokemon`.
- Fixed Pokémon sometimes losing hidden abilities when evolving. This fix will only take effect for newly created Pokémon because of technical reasons that were explained to me but which I then forgot.
- Fixed capture messages not displaying in battle.
- Fixed the Illusion ability causing the wrong Pokémon to be targeted in battle.
- Fixed battles started with fainted party members causing a soft-lock on defeat.
- Fixed some issues with eyes in the faint animations of Hitmonlee and Phantump
- Fixed missing evolution moves, for example Stone Axe for Kleavor.
- Cleaned up empty evolutions declaration in species data (And no, I'm not listing all 169. No I don't care what you pay me, I'm not doing it).
- Fixed non-consumable held items being consumed or swapped in battle permanently.
### Developer
- Significantly changed the way the properties in PokemonEntity work. This could break some plugins (not in a big way, but changes will be needed for some things).
- Rebuilt the scheduling API to more clearly force side choices and temporal frames of reference for tasks. The developers say that how it works is cool but I stopped listening.
- Added dialogue API and data registry. This is powerful, and there is a full example in the Cobblemon mod you can trigger using `/opendialogue <username> cobblemon:example`. The example JSON is inside the data folder of the mod.
- Opened up the ItemDropEntry class to allow for it to be extended.
- Added a new "advancement" evolution variant that takes an advancement identifier and succeeds if the player has the advancement.
- Made the spawning API capable of non-entity spawning. You can make it 'spawn' commands if you want. Go nuts.
- Made `PokemonProperties.parse` more interoperable with Java. Save yourself and stop using Java.
- Added the `HeldItemEvent`, this comes with 2 implementation `HeldItemEvent.Pre` and `HeldItemEvent.Post`.
- Corrections to the ability implementation have been made that make `Ability.forced` function as intended and never reroll an ability for a Pokémon, please check your implementations to ensure the corrected behavior is intended for your use case.
- `Pokemon.ability` no longer has a public setter. Please migrate to using `Pokemon#updateAbility`, this handles the ability coordinate storage for you when necessary.
- `Ability.forced`, `Ability.index` and `Ability.priority` have all had their setters internalized, there is no longer any need to manually adjust these migrate to the method mentioned above to handle that process for you.
- `AbilityChanger` has been added to API alongside some implementations, this is subject to change as the ability capsule and patch currently only expect the traditional behaviour in the Pokémon games of 1 or 2 regular abilities and 1 hidden ability.
- `Pokemon#rollAbility` has been added which re9rolls for a legal ability for the Pokémon.
- `docs/cobblemon-tags` tags and spawn-presets can now be auto-generated from the current tags in the Cobblemon mod with the `generateSpawnPresetList.py` and `generateTagList.py` scripts.
- `public_spawns_to_json.py` script has been added to give the powerful spawn.json generator a simplistic UI.
- Updated Showdown with Gen 9 DLC.
- Changed mixins to be Java 17 for compatibility level instead of 16, removing a warning from startup logs.
### Datapack & Resourcepack Creators
- The maximum amount of fossils that can fit in the Fossil Analyzer can be adjusted in the config.
- Custom fossils can be defined using a list of items and the resulting Pokémon. An example of `aerodactyl.json`:
`JSON
{
"result": "aerodactyl",
"fossils": [
"cobblemon:old_amber_fossil"
]
}
`
- Fetus models can be defined in `bedrock/fossils`.
- Fetus textures can be defined in `textures/fossils`.
- Fuel for the Restoration Machine is registered inside the `natural_materials` folder. To register more fuels, create a JSON file containing an array of objects. Each object supports the following fields:
- `content`: Integer containing the amount of fuel to add.
- `item` OR `tag`: Identifier of the item or item tag to be inserted.
- `returnItem`: Identifier of an item to return to the player after consumption.
- Added 3 new item tags: `ancient_poke_balls`, `fossils`, and `tumblestones`.
- Added a spawn rules system to modify general spawning behaviour, see the [wiki](https://wiki.cobblemon.com/index.php/Spawn_Rules) for more information.
- Added dialogue datapack folder and `/opendialogue` command.
- Added the item tag `cobblemon:held/leaves_leftovers` this can be used to flag apple-like items that can create leftovers when eaten.
- You can now add support for dynamic lighting implementations, Cobblemon ships with a default implementation for [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) and the [Dynamic Lights Reforged](https://www.curseforge.com/minecraft/mc-mods/dynamiclights-reforged), add the following to any species or form:
`JSON
{
"lightingData": {
"lightLevel": 14,
"_lightLevelCommentRemoveMe": "Above supports 0 to 15",
"liquidGlowMode": "LAND",
"_liquidGlowModeCommentRemoveMe": "Above supports LAND, UNDERWATER or BOTH"
}
}
`
- Following up on this change `light_source` was removed as a possible shoulder effect due to becoming unnecessary and never having had a default implementation.
- Added the item tag `cobblemon:ability_changers`, contains the `cobblemon:ability_capsule` & `cobblemon:ability_patch` by default.
- Added the item tag `cobblemon:held/is_friendship_booster`, allows items to give the Soothe Bell effect of a boost of 1.5x Friendship gained, contains `cobblemon:soothe_bell` by default.
+105
View File
@@ -0,0 +1,105 @@
## [1.5.1 (May 27th, 2024)](#1-5-1)
### Additions
- Added unique send out particles for Cherish, Dream, Beast, and Ancient Origin balls.
- Made Wooloo and Dubwool dye-able like sheep. So cute!
- Added stat up and down particles.
- Most status effects now have particles! These include: Paralysis, Poison, Sleep, Confusion, Infatuation.
#### Move Particle Effects
- Confusion
- Cotton Guard
- Growl
- Ice Punch
- Fire Punch
- Thunder Punch
- Minimize
- Quick Attack
- Protect
- Swords Dance
- Sand Attack
- Poison Powder
- Sleep Powder
- Stun Spore
- Powder
- Rage Powder
- Spore
- Thunder Wave
### Changes
- Sounds for Relic Coin Sacks have been correctly renamed. Relic Coin Pouches received new sounds for breaking and placing.
- Readjusted Petilil portraits so they fit a bit better.
- Improved handling of Pokémon taken from the Restoration Tank block to be a bit more stable.
- Made Mulch cheaper to craft.
### Fixes
- Fixed a bug in which adding organic material to the restoration tank via right click was adding the full count of the stack currently in hand - but only taking 1 of the item.
- Fixed a niche issue where some properties of entities were not initialized correctly, causing Pokémon that appeared to be level 1 until you battle them.
- Fixed Fossilized Drake being missing from the Fossils item tag.
- Fixed Gilded Chest block entity not being cleared on block break, creating spooky ghost blocks. Old ones can be fixed by placing something like a furnace where it was, then breaking the furnace.
- Fixed sherd brokenness on Forge.
- Fixed Supplementaries incompatibility.
- Fixed Fossil Compartment crash with Jade / WAILA forks.
- Fixed pasture block PC lookups when the player is offline.
- Fixed an untranslated battle message that occurs when using a move that just ran out of PP (e.g. Fire Blast that just got spited mid-turn).
- Fixed held items being eaten even when the held item evolutions are already unlocked.
- Fixed Hisuian Decidueye not being Grass/Fighting.
- Fixed both Decidueye forms learning both Triple Arrows and Spirit Shackle.
- Fixed Pineco being unable to evolve into Shulker Forretress.
- Fixed Kabutops T-posing when underwater. It doesn't have proper swimming animations yet, though.
- Fixed Pidgey's missing walk animation.
- Fixed Cyndaquil's hidden flames clipping if it was swimming.
- Fixed Chimecho and Chingling being unable to spawn near bells. They are meant to!
- Fixed Tyrantrum and Wailord Party Overlay models peeking through the chat box. It was kinda funny though.
- Fixed hitbox sizes for Seedot, Nuzleaf, and Shiftry.
- Fixed Budew and Lechonk sliding if they walked for too long.
- Fixed Shedinja T-posing in battle.
- Fixed recoil evolution condition not working, making things like Basculegion unobtainable.
- Fixed issue where poser debug tools didn't work on JSON posers.
- Fixed issue where gilded chests don't close when going far away.
- Fixed issue where the restoration tank's renderer was reading old data, making it appear wrong.
- Fixed issue where the lights on the restoration tank would not animate if it was facing east. Very specific.
- Fixed client crash with the fossil machine when updating block state on a chunk that is unloaded in the client. I don't understand this but the devs are sure that all of those are real words.
- Fixed Restoration Tank crash with Create upon the tank block's destruction.
- Fixed Restoration Tank over consuming items when interacting with Create blocks.
- Fixed addons that add very many moves to a learn-set causing disappearing Pokémon (visually) issues on servers.
- Fixed Hyper Cutter and Big Pecks incorrectly stating that it prevented accuracy from being lowered in battle.
- Fixed missing messages for Rough Skin and Iron Barbs in battle.
- Fixed a bug where sometimes Pokémon sendouts wouldn't create an entity, or the entity would spawn at 0 0 0 which is not a good place for a Pokémon to be. Or any of us, really.
- Fixed issue in which a locked gilded chest would animate to the open state when the client fails to open it, such as when it is locked.
- Fixed a bug where aspects of a form would not be properly reflected on form changes (eg. Normal -> Hisui).
- Fixed generic battle effect sounds not sounding the way they were intended to.
- Fixed particle effects often not having access to some specific entity functions from MoLang.
- Fixed particles sometimes lasting a single tick too long, causing (very quick) visual glitches.
- Fixed particle rotations being inverted.
- Fixed particle events not spawning at the instigating particle's location.
- Fixed a bunch of spam during world generation.
- Fixed a bug in which throwing a Poké Ball at a player owned Pokémon with the ability Illusion would reveal its true species. Hilarious meta strategy.
- Fixed root-part animations not working for JSON posed Pokémon. You didn't notice this but if we didn't fix this in this update then if you use Quick Attack a lot you'd have seen a whole lot of [this](https://cdn.discordapp.com/attachments/1076993968803434627/1242660506783715369/Minecraft__1.20.1_-_Singleplayer_2024-05-21_22-08-17.mp4?ex=66549408&is=66534288&hm=ff95ee293eb15634fd63e6546534ea279540a1c892605e8d561593ca2c5600c5&) which is damn funny but very unintended.
### Developer
- Changed SpawnAction#complete to return a nullable generic R (the spawn action result) instead of a boolean. Provides more information this way.
- Added an event that fires when a fossil is revived, with or without a player.
- Added IVS and EVS property extractors.
- Fixed PCStore#resize not allowing PC boxes size reduction.
### Data Pack & Resource Pack Creators
- Added support for MoLang conditions for quirks and poses.
- Changed the AttackDefenceRatio requirement to StatCompare and StatEqual. There is some backwards compatibility for AttackDefenceRatio, though.
- Changed "dimensions" spawn condition to check with dimension IDs instead of effects, so custom dimension IDs can be used.
- Added parametric motion and rotation support to particle effects.
- Added entity_scale as a molang var for particles (likely only applicable to Pokemon)
- Added support for primary quirk animations using the following format:
`JSON
{
"quirks": [
"q.bedrock_primary_quirk('<pokemon>', '<animation>', <minSeconds>, <maxSeconds>, <loopTimes>, '<excludedLabels>', q.curve('<waveFunction>'))"
]
}
`
- Added support for custom stashes, similar to Gimmighoul's coin and scrap stashes.
- Added the ability to create custom brewing stand recipes.
### Localization
- Updated translations for:
- Simplified and Traditional Chinese.
- Spanish.
+5
View File
@@ -0,0 +1,5 @@
## [1.5.2 (May 27th, 2024)](#1-5-2)
### Fixes
- Fixed Wooloo and Dubwool dyeing making your game start dying. Only if you do it on a server.
- Fixed Gimmighoul causing PCs and parties to look glitched out, also only in a server.
- Fixed players being able to dye other people's sheep Pokémon.
+487
View File
@@ -0,0 +1,487 @@
## [1.6.0 - The Record Catch Update (December 25th, 2024)](#1-6-0)
#### "Now that there's a fishing mechanic, the mod is actually good!"
### Additions
- Added the Pokédex as a craftable item that can be placed on lecterns.
- Added Pokémon (and item) fishing using modified fishing rods - Poké Rods! You'll need a Poké Rod smithing template, a fishing rod, and some type of Poké Ball. Each Poké Ball makes a differently themed rod because it's cool.
- Added Lure Ball functionality, increasing the catch rate of Pokémon that were caught on a fishing rod.
- Added Repeat Ball functionality, increasing the catch rate of Pokémon that are already registered as caught in a player's Pokédex.
- Added flat level battling with options to set all Pokémon to level 50, 100, or 5 for the duration of a battle. No experience or EVs are granted for a flat battle.
- Added support for Double Battles, Triple Battles, and Multi-battles.
- Added raft platforms for non-swimming, non-flying Pokémon to stand on during battles that take place on the water's surface (Flying Pokémon will fly over water in battle, and water breathing Pokémon will swim in water during battle).
- Added smarter send-out positions for Pokémon in battle. They should get in your way less!
- CriticalCaptures and Pokédex progress capture multiplier now work with the Pokédex.
- Added shiny Pokémon particle effects and sounds to help find them.
- Added effects for the burn status effect.
- Added effects for the moves: Seismic Toss, Withdraw, Bite, Crunch, Super Fang, Hyper Fang, Pursuit, Mist, Haze, Lick, Kinesis, Psychic, Water Sport, and Mud Sport.
- Added extra visuals to early berry growth stages.
- Added Polished Tumblestone and Tumblestone Brick block sets from Tumblestone, Black Tumblestone, and Sky Tumblestone.
- Moves impacted by the abilities Pixelate, Refrigerate, Aerilate, Galvanize, and Normalize now display as their altered typing.
- Added Fire, Water, Thunder, Leaf, Ice, Sun, Moon, Shiny, Dawn, and Dusk Stone storage blocks.
- Added Eject Pack, Metronome, Protective Pads, Punching Glove, Room Service, Scope Lens, Shed Shell, Terrain Extender, Throat Spray, Utility Umbrella, Wide Lens, and Zoom Lens held items.
- Added a full evolution particle effect for Pokémon that are sent out when evolution is started.
- Added a Nurse profession that can be unlocked by having villagers claim a healing machine block.
- Pokémon are now animated when seen in any GUI that isn't the party GUI.
- Added animation and sounds for trading.
- Added icons for pending trade, team-up, and battle requests from other players.
- Quirk animations can now occur for Pokémon that are shoulder mounted.
- Added new sounds for Poké Balls bouncing off of Pokémon and landing on the ground during capture.
- Added a unique set of sounds for Ancient Poké Balls.
- Added a sound for using Exp Candy and Rare Candy items.
- Added revamped Poké Ball animation for Pokémon breaking out.
- Added battle log messages for switching out Pokémon.
- Added config setting `displayEntityNameLabel` and `displayEntityLabelsWhenCrouchingOnly` to control what and when is displayed for the pokemon label.
- Added `no_ai` and `freeze_frame` options to the `/spawnpokemon` command.
- Added `moves` option to Pokémon properties, allowing you to set the moves of a Pokémon in commands and spawn files using comma-separated move names.
- Added a `natural` block state property for the healing machine block; when property is set to true, the block will have a different texture and drop an iron ingot instead of itself.
- Added a `battleInvulnerability` gamerule to make players invulnerable to any damage during a battle.
- Added a `mobTargetInBattle` gamerule to exclude players from being targeted by mobs during a battle.
- Added a `/freezepokemon` command to pause a Pokémon's animation at a specific point in time.
- Added `/spawnnpc` and `/spawnnpcat` commands.
- Added `hiddenability=false` option to `/spawnpokemon` and `/pokemonedit` commands, allowing the Pokémon's ability to be reverted to a normal ability.
- Added `aspect` and `unaspect` PokemonProperty arguments (which also includes commands such as `/pokemonedit`, `/spawnpokemon`, and `/givepokemon`) to allow forcing or un-forcing an aspect on a Pokémon.
- Added `type` alternatively `elemental_type` PokemonProperty argument, this is only used for filtering and is not applied to Pokémon. Example `type=fire` would be true for Charmander but false for Squirtle.
### Structures Added
- Fishing boat structure that contain an Explorer Map leading to a shipwreck cove and a Poké Rod Smithing Template.
- Stonjourner Henge Ruins, Luna Henge Ruins, and Sol Henge Ruins.
- Submerged Shipwreck Cove and Lush Shipwreck Cove.
- Pokémon Centers to all 5 village types.
### Pokémon Added
#### Gen 1
- Alola Bias Cubone (built-in resource pack)
- Alolan Marowak
#### Gen 2
- Ledyba
- Ledian
- Sunkern
- Sunflora
- Wobbuffet
- Girafarig
- Corsola
- Remoraid
- Octillery
- Mantine
- Smeargle
- Delibird
#### Gen 3
- Slakoth
- Vigoroth
- Slaking
- Corphish
- Crawdaunt
- Feebas
- Milotic
- Wynaut
- Absol
- Spheal
- Sealeo
- Walrein
- Bagon
- Shelgon
- Salamence
- Kecleon
#### Gen 4
- Mantyke
- Finneon
- Lumineon
- Shellos
- Gastrodon
- Rotom
#### Gen 5
- Purrloin
- Liepard
- Scraggy
- Scrafty
#### Gen 6
- Clauncher
- Clawitzer
#### Gen 7
- Pikipek
- Trumbeak
- Toucannon
- Mareanie
- Toxapex
- Sandygast
- Palossand
- Bruxish
#### Gen 8
- Cramorant
- Hatenna
- Hattrem
- Hatterene
- Pincurchin
#### Gen 9
- Wattrel
- Kilowattrel
- Veluza
- Farigiraf
- Klawf
- Finizen
- Palafin
- Wiglett
- Wugtrio
- Flamigo
- Dondozo
#### Unique Forms
- Magikarp Jump variants for Magikarp
- Magikarp Jump variants for Gyarados (built-in resource pack, enabled by default on Fabric)
### Added cries to the following Pokémon
- Sandshrew, Sandslash
- Magnemite, Magneton, Magnezone
- Gastly, Haunter, Gengar
- Rhyhorn, Rhydon, Rhyperior
- Happiny, Chansey
- Horsea, Seadra, Kingdra
- Magby, Magmar, Magmortar
- Porygon, Porygon2, Porygon-Z
- Sentret, Furret
- Misdreavus, Mismagius
- Corsola
- Mantyke, Mantine
- Girafarig, Farigiraf
- Wynaut, Wobbuffet
- Lunatone
- Solrock
- Corphish, Crawdaunt
- Feebas, Milotic
- Kecleon
- Absol
- Spheal, Sealeo, Walrein
- Relicanth
- Bagon, Shelgon, Salamence
- Munchlax
- Finneon, Lumineon
- Purrloin, Liepard
- Timburr, Gurdurr, Conkeldurr
- Joltik, Galvantula
- Elgyem, Beheeyem
- Golett, Golurk
- Deino, Zweilous, Hydreigon
- Flabébé, Floette, Florges
- Clauncher, Clawitzer
- Mareanie, Toxapex
- Wimpod, Golisopod
- Bruxish
- Hatenna, Hattrem, Hatterene
- Pincurchin
- Klawf
- Finizen, Palafin \[Zero\], Palafin \[Hero\]
- Dondozo
### Added shoulder mounts for the following Pokémon
- Weedle
- Caterpie
- Spearow
- Mew
- Murkrow
- Smoochum
- Larvitar
- Tailow
- Plusle
- Minun
- Beldum
- Starly
- Buneary
- Combee
- Pachirisu
- Tepig
- Pidove
- Petilil, Hisui Bias Petilil
- Zorua, Hisui Bias Zorua
- Elgyem
- Fletchling
- Skrelp
- Klefki
- Litten
- Fomantis
- Morelull
- Dreepy
- Sprigatito
- Shroodle
- Tatsugiri
- Glimmet
- Gimmighoul \[Roaming\]
### Animation updates for the following Pokémon
- Bellsprout, Weepinbell, Victreebel
- Shellder, Cloyster
- Porygon, Porygon2, Porygon-Z
- Furret
- Swinub, Piloswine, Mamoswine
- Skarmory
- Tyrogue
- Spinda
- Torkoal
- Nincada, Ninjask
- Lunatone
- Solrock
- Buneary, Lopunny
- Magnezone
- Alomomola
- Tepig, Pignite, Emboar
- Flabebe, Floette, Florges
- Litten, Torracat, Incineroar
- Fomantis, Lurantis
- Dreepy, Drakloak
- Kleavor
- Scorbunny
- Gimmighoul \[Roaming\]
### Model updates for the following Pokémon
- Bulbasaur, Ivysaur, Venusaur
- Charmander, Charmeleon, Charizard
- Caterpie
- Kakuna, Beedrill
- Lapras
- Porygon, Porygon2, Porygon-Z
- Igglybuff, Jigglypuff, Wigglytuff
- Poliwhirl, Poliwrath
- Bellsprout, Weepinbell, Victreebel
- Shellder, Cloyster
- Gastly, Haunter
- Onix
- Krabby, Kingler
- Rhyhorn, Rhydon, Rhyperior
- Horsea, Seadra, Kingdra
- Goldeen, Seaking
- Magby, Magmar, Magmortar
- Magikarp, Gyarados
- Munchlax, Snorlax
- Swinub, Piloswine, Mamoswine
- Mudkip, Marshtomp, Swampert
- Baltoy, Claydol
- Carvanha
- Relicanth
- Prinplup, Empoleon
- Gible, Gabite, Garchomp
- Riolu, Lucario
- Snivy, Servine, Serperior
- Tepig, Pignite, Emboar
- Krookodile
- Dwebble, Crustle
- Joltik, Galvantula
- Klink, Klang, Klinglang
- Golett, Golurk
- Fennekin, Braixen, Delphox
- Phantump, Trevenant
- Litten, Torracat, Incineroar
- Popplio, Brionne, Primarina
- Mudbray
- Lurantis
- Scorbunny, Cinderace
- Quaxly
- Skeledirge
- Tatsugiri
### Changes
- Buffed Dusk Ball catch multipliers: Increased multiplier to 3.5 (from 3.0) in light level 0. Increased multiplier to 3.0 (from 1.5) in light levels 1-7.
- Altered the item model for Medicinal Leeks and Roasted Leeks to be held like sticks and other rod items.
- Adjusted some berry balance values like yield and growth times.
- Adjusted volumes of sounds made by Display Cases, Berry Bushes, Energy Root, Medicinal Leek, Vivichoke, Mints, Revival Herbs and Gilded Chests.
- Changes to mulch buffs/durations.
- Updated potion sprites.
- Changed Link Cable recipe to be much cheaper.
- Updated sounds for Medicinal Leeks, Big Roots, Energy Roots and Revival Herbs.
- Updated UI sounds for clicking and evolving Pokémon.
- Updated cries for Chansey, Crobat, Hoothoot, Noctowl.
- Removed the interchangeable evolution results for the first stage Hisuian starters to prevent confusion. The method still exists for stage 2 to 3, but stage 1 to 2 was not distinguishable enough for many users.
- Vivillon wings will stop being clear when you remove any Vivillon related resourcepacks. The default pattern will be the meadow wings.
- Wild Pokémon interaction range increased to 12 blocks (from 10 blocks).
- Player trade range increased to 12 blocks (from 10 blocks).
- PvP battle range increased to 32 blocks (from 10 blocks).
- Spectate range increased to 64 blocks (from 10 blocks).
- The inventory key now closes our GUIs if they are open, mirroring how Minecraft screens usually work.
- The noise from the pasture and PC blocks being interacted with now activates Sculk sensors.
- Updated dialogue GUI assets with proper assets not made by a programmer. Well, it was still a programmer, but- someone who can also draw!
- Updated party switching interface when in battle.
- Relic coin pouches can now be waterlogged.
- The "Press R to start battle prompt" will now disappear after a player's first battle has been won. You've probably figured that detail out by then.
- The default number of digits for the Pokédex number in the summary has been increased, from 3 to 4. There sure are a lot of Pokémon these days.
- The pasture block model's screen is now off by default.
- The Poké Balls creative tab is now named Utility Items as it also encompasses Poké Rod and Pokédex items.
- Moves can now be benched without specifying a replacement move, allowing for empty move slots.
- Moves learned via Sketch now persist after battle.
- Hidden Power now displays its effective typing.
- Updated particles for moves: Confusion, Protect, Sand Attack, and Quick Attack.
- Updated particles for status effects: Paralysis, Poison, and Sleep.
- Updated particles on Gastly.
- Revamped stat buff and de-buff particles.
- Improved the performance of display cases that contain Pokémon photos.
- Updated sounds for Poké Balls closing, opening and for Pokémon breaking out.
- Improved the performance of display cases that contain Pokémon Model items.
- Removed species Base Stats from the summary interface as it is now viewable within the Pokédex.
- Changed summary tab text labels to icons. You'll get used to them. Or else.
- Clicking the summary interface exit button while the swap moves or evolve screen is open will cause the interface to switch back to the party screen. The button will exit the interface otherwise.
- Ancient Poke Balls now jump once rather than shaking 3 times when capturing Pokémon.
- The jump height indicate the number of shakes that would have occurred.
- A high wobbly jump indicates 1 shake.
- A high jump indicates 2 shakes.
- A medium jump indicates 3 shakes.
- A short jump indicates that you caught the Pokémon.
- Pokémon sent out during battle will spawn facing their opponent.
- Pokémon sent out outside a battle will spawn facing their trainer.
- Wailord is now 25% bigger. ... [But I have an idea.](https://tenor.com/view/star-wars-more-gif-21856591)
- Region-biased Pokémon forms are now optional to a built-in resource pack. This pack is enabled by default for Fabric. For NeoForge users, all our built-in resource packs default to disabled because that's all it supports right now.
- Update item sprites for Cell Battery, Chipped Pot, Covert Cloak, Cracked Pot, Masterpiece Teacup, Red Card, Sachet, and Unremarkable Teacup.
### Fixes
- Fixed Ability Patches not reverting Hidden Abilities back to Normal Abilities.
- Fixed awarding Pokémon experience upon forfeiting battles.
- Scaled down Amaura's fetus model to avoid clipping through the tank while animating.
- Fixed Cubone's cry not having a sound (as if that Pokémon needed to be more tragic).
- Fixed the sendout sound erroneously playing when a wild Pokémon breaks out of a Poké ball.
- Flamethrower is no longer missing sounds.
- Fixed the Seafloor spawning context not being a usable context.
- Fixed Pokemon spawning in non-full blocks like slabs.
- Fixed Gilded Chests not dropping the chest itself when broken, only the contents.
- Fixed Pokémon losing their Hidden Ability through evolution if the middle stage did not have a Hidden Ability.
- Hidden Power no longer plays the water type action effect (It now plays the normal type action effect).
- Fixed Crumbling Arch structures not blending in with the world.
- Fixed Energy Root being usable on a fainted Pokémon.
- Fixed Pokémon not being sent out when starting a battle while recalling said Pokémon.
- Fixed species comparison not using namespace for both sides in `PokemonProperties.isSubsetOf`.
- Fixed `PokemonProperties#asString` prefixing nicknames with a '$'.
- Fixed shearable Pokémon not dropping correct wool colors.
- Fixed pasture spawning Pokémon inside solid blocks when closest spawning position is blocked off.
- Fixed Tumbling Down advancement not being granted by tumblestone variants.
- Improve error handling when loading spawn sets to ensure invalid configurations don't crash the server.
- Fixed empty `JsonPlayerData` files resulting in players being unable to join server/world.
- Sound for evolving Pokémon through the Summary Menu is now correctly playing again.
- Fix Starter prompt not showing up.
- Fixed owned Poké balls floating upwards if pausing the game mid-transition (which looked absolutely hilarious).
- Fixed all mouse buttons working for Battle UI navigation (now it's only primary/left click).
- Fixed trading Pokémon setting their friendship to 0 instead of the base value.
- Fixed a scenario where a Pokémon that rolled to spawn with a special Tera type sometimes having a Tera type that is already a part of their natural typing.
- Fixed PokemonProperty argument suggestions for `tera` and `tera_type` not suggesting `stellar`.
- Fixed being able to stack Relic Coin Pouches on top of each other.
- Fixed model loader generating misleading crash-reports when client is crashing - that resurrection tank error wasn't our fault! We're innocent, your honour!
- Big Roots and Energy Roots now share the same sounds as intended.
- Fixed sounds made by blocks playing at a lower pitch than intended.
- Fixed Chimchar and Monferno comically T posing whenever they sleep.
- Fixed Cetitan's cry breaking its walk and sleep animations.
- Fixed the Magby line not having any placeholder walk animations.
- Fixed Duskull and Dusclops using skylight levels for their nether spawn data. There is no sun in the Nether!
- Fixed Hisuian Zoroark using base Zoroark stats.
- Fixed Bellossom clipping into the player head when shoulder mounted.
- Fixed Shroomish's look range to prevent it from looking higher than it should.
- Fixed Maushold's faint animations not playing. It's even sadder than Tandemaus!
- Fixed Slowking's battle idle.
- Fixed Grafaiai's walk speed to prevent model sliding.
- Fixed Alolan Exeggutor's tail not showing in the party UI. It will now also stand in front of all Pokémon in the party menu :)
- Fixed Timburr duplicating its log while fainting.
- Fixed hitbox sizes for Grotle and Torterra being set to default values.
- Fixed Hisuian Sneasel using Johtonian Sneasel's cry. Johto-nian. Jotonion. Jotunheim?
- Fixed Trevenant T-posing after 8 seconds of sleeping. I also do that.
- Fixed Bewear T-posing for a bit if a wild one faints where you can see.
- Fixed Noctowl's placeholder fly animation.
- Corrected Lotad blinking animation.
- Fixed reviving items causing errors when used in battle.
- Fixed messages for Focus Sash, Confusion, Mummy, Ice Face, Own Tempo, and Revive.
- Improve error handling when loading spawn-sets to ensure invalid configurations don't crash the server.
- Fixed Crumbling Arch Ruins generating a giant cube of air and removed the chest.
- Fixed possible crash on large population servers due to concurrent access of data.
- Quickly sending out and recalling Pokémon now looks smoother and can no longer be spammed to cause desync issues.
- Pokémon are now invulnerable during sendout animation and intangible during recall animation.
- Scrolling with party keybinding now behaves properly when using high scroll speed or scroll sensitivity.
- Fixed battle log GUI flashing when Battle GUI is opened.
- Bag Items used during a turn will now be refunded if the battle ends before the next turn begins.
- Pokémon whose current owner is not its Original Trainer now gain extra experience.
- Fixed Fossil Resurrection advancement not being granted.
- Fixed village generation caps not applying for berry farms. You were not meant to see more than two berry farms per village! This has been broken for ages but no one noticed... Hmmm... We could just remove it from here...
- Fixed the Ice Face ability activation being displayed incorrectly in a battle.
- Fixed edge case of F1 and R locking you in battle with no R functionality (requiring ESC to get out).
- Fixed Poké Ball render orientation in battle interface when capturing.
- Fixed sync issues with recently learned moves where their PP would not go down until you logout and in.
- Fixed some Pokémon photos in display cases flashing if the Pokémon has gender differences.
- Fixed Bidoof and Jigglypuff sleep animations stopping after some time, causing them to be 'asleep' while T-posing menacingly.
- Fixed entities not changing poses unless you're looking at them.
- Fixed cries not playing on send-out if the Pokémon is off-screen.
- Fixed text row selection highlight in battle log.
- Fixed top black border rendering in scroll interfaces in summary UI.
- Fixed aspect tracking for Advancements.
- Fixed illusion not copying aspects or caught ball.
- Prevent summary stats tab from making sounds when clicking on an already open tab.
- Fixed display case not being able to be fed items from underneath.
- Fixed Pokémon battling in water continuously sinking to the bottom.
- Fixed passive healing and wake from faint not disabling when their config values are set to 0.
- Fixed an issue where rebinding the R key to a mouse button prevented players from closing the battle interface using that button.
### Developer
- `SpawnCause` is now an implementation of `SpawningInfluence`.
- Many types related to `Pokemon` including itself now have dedicated `Codec`, please migrate to them from the NBT/JSON/PacketBuffer write/read methods.
- `PokemonBattle` now starts on turn 0.
- Renamed Pokemon.hp to Pokemon.maxHealth to make it clearer. Backwards compatibility is provided but it is an active deprecation, please migrate away from it.
- Serialization of PokemonStores and Pokemon themselves now require registry access, which will break some sidemods. This sucked for us more than it will suck for you! If you have a world or player instance, you can get it from there.
- ``TeraTypes`` now implements ``Iterable``.
- Added `forcedAspects` to Pokémon to make it easier to easily add basic aspects to a Pokémon in a way that persists. We already know that everyone is going to overuse this.
- Made the `Pokemon.aspects` setter private. This could technically break side-mods but if you are affected by this then you were using it wrong! Use `Pokemon.forcedAspects` to fix it.
- Cobblemon's main logger is properly static now.
- `PokemonEntity.enablePoseTypeRecalculation` can be used to disable automatic pose type recalculation.
- Added CollectEggEvent and HatchEggEvent for compatibility usage.
- Added events for:
- Showdown Instructions
- Mega Showdown Instruction
- Terastallize Showdown Instruction
- ZPower Showdown Instruction
- Bait Consumed, Bait Set, and an event to register custom BaitEffect Functions
- Bobber Bucket Chosen
- Bobber Spawn Pokémon
- Pokérod Cast
- Pokérod Reel
- Pokémon Heal (with context)
- Added HealingSource, an interface applied to all sources of healing from player actions, for easier tracking of healing sources.
- Move Change
- Shiny Chance Calculation Event (with player context)
- Dex Information Changed (Pre and Post); this event is fired when the Pokédex is updated with new information.
- Rebuilt large swaths of the model animation code to simplify it.
- Renamed a bunch of things from %Poseable% to %Posable% because spelling.
- Renamed StatelessAnimation to PoseAnimation.
- Renamed StatefulAnimation to ActiveAnimation.
- Documented the animation system.
- Allowed for SpawnSnowstormEntityParticleHandler to handle non-posable entities (due to being non-posable, locators are useless - to set the offset use the settings in the particle itself).
- Added property chaining support for duplicate CustomPokemonPropertyType elements.
### Data Pack & Resource Pack Creators
- Added experimental `flow` datapack directory for handling events using MoLang event handlers.
- Added support for "shedders" similar to Shedinja's evolution logic.
- Fixed the placeholder `WingFlapIdle` animation so the wings are not rotating opposite to each other.
- 'player' type dialogue faces can now be explicitly stated so that NPC mods that use fake players can show in dialogue portraits.
- Added `isLeftSide` field for dialogue faces. This determines what side of dialogue box the portrait is on.
- `sounds/attacks` directory has been renamed to `sounds/move`.
- Moves sharing generic sounds now have unique sound events, allowing them to be changed with resource packs.
- All move sound events have been renamed to `move.<NAME>.<SOURCE>` for consistency.
- Status moves have been moved out of the `attacks` directory and split into volatile and nonvolatile.
- `status.badlypoison.actor` sound event has been renamed to `status.toxpoison.actor`
- Mulch and berry harvesting sound events have been renamed and moved to their respective directories in `sounds/block`.
- All sounds related to evolving Pokémon have been moved to the `sounds/evolution` directory.
- Sound events for all blocks now start with `block`.
- Gimmighoul chest and item interaction sounds have been moved to where its cry is.
- Unused sound files and sound events have been removed.
- Poké Ball sounds are now in their animation files, making them more flexible to edit.
- Added MoLang compatibility in the isVisible property for transformed parts.
- Added `q.has_aspect('some_aspect')` function to animations, posers, and entity particle effects.
- Added support for conditional pose animations.
- Added a new universal locator called "top".
- Added `eggs_collected` and `eggs_hatched` Advancement triggers.
- Added missing `minYaw` configuration to the `q.look()` function for JSON posers.
- Some pose condition names have been changed:
- `isTouchingWaterOrRain` has been changed to `isInWaterOrRain`
- `isSubermegedInWater` has been changed to `isUnderWater`
### Localization
- Updated translations for:
- Czech, German, Greek, Spanish, Mexican Spanish, French, Canadian French, Hungarian, Italian, Japanese, Korean, Dutch, Polish, Portuguese, Brazilian Portuguese, Russian, Ukrainian, Simplified Chinese, and Traditional Chinese
- Migrated translation project to Weblate at https://lang.cobblemon.com/projects/cobblemon/mod/
+219
View File
@@ -0,0 +1,219 @@
## [1.6.1 (January 26th, 2025)](#1-6-1)
### Additions
- Added crossover paintings from Close Combat: Premonition, Altar, Slumber, and Nomad.
- Added Galarica Nuts, used for crafting Galarica Cuffs and Wreaths. Dropped from certain Pokémon. Take a wild guess which.
- Added compatibility with Repurposed Structures. (Thank you, TelepathicGrunt!)
- Added an evolution method for Karrablast to evolve into Escavalier in singleplayer.
- Pokédexes can now be placed in Chiseled Bookshelves.
- Added optional box argument to the /pc command.
- Pokédex and Dialogue screens now close when the inventory keybind is pressed.
- Added config setting `maxPokedexScanningDetectionRange` to control from what distance the player can scan Pokémon using the Pokédex.
- Added config setting `hideUnimplementedPokemonInThePokedex` which hides unimplemented Pokémon from the Pokédex when set to true.
- Added debug renderer for posable entity locators.
- Added crossover paintings from Close Combat, Premonition, Altar, Slumber, and Nomad.
- Added optional box argument to the /pc command
### Changes
- Pokémon will now be dynamically revealed to the Pokédex as they're seen instead of revealing entire parties at the end of battle regardless.
- Unseen wild Pokémon will update their name from '???' to their real name as soon as a battle starts to reflect the battle UI showing the actual species name.
- Pokémon under the illusion effect will reveal their disguise to the Pokédex first and then the base Pokémon once the disguise is broken.
- Added more support for a variety of Fabric/NeoForge Convention tags.
- Reformatted some tags to be more consistent.
- Edited some recipes to utilize tags instead of direct item ids, for greater mod compatibility.
- Berries will drop if broken at age 0
- Improved Fortune drops on Mint Seeds
- New Slowpoke shiny texture.
- Updated drops for many Pokémon.
- Completely resynced Pokémon move and stat data based on later games. Learnsets have changed considerably to maximise available moves.
- Cobblemon save data now saves .old files where applicable as a means to recover from file corruption due to crashes or similar abrupt stops
### Pokémon Added
#### Gen 5
- Ducklett
- Swanna
- Shelmet
- Accelgor
- Karrablast
- Escavalier
- Rufflet
- Braviary
- Foongus
- Amoonguss
#### Gen 6
- Binacle
- Barbaracle
#### Gen 7
- Dewpider
- Araquanid
- Alolan Geodude
- Alolan Graveler
- Alolan Golem
#### Gen 8
- Galarian Slowpoke
- Galarian Slowbro
- Galarian Slowking
#### Gen 9
- Paldean Tauros
### Added cries to the following Pokémon
- All Nidorans
- Shellder, Cloyster
- Pinsir
- Tyrogue, Hitmontop
- Spinda
### Animation updates for the following Pokémon
- Primeape
- Munchlax
- Snorlax
- Poliwrath
- Goldeen
- Seaking
- Dondozo
- Wobbuffet
- Charcadet
- Armarouge
- Ceruledge
- Geodude
- Graveler
- Golem
- Sandile
- Krokorok
- Krookodile
### Model updates for the following Pokémon
- Slowpoke
- Slowbro
- Slowking
- Eiscue
- Tauros
- Goldeen
- Seaking
- Charcadet
- Armarouge
- Ceruledge
- Pinsir
- Geodude
- Graveler
- Golem
- Magnezone
### Cry updates for the following Pokémon
- Sceptile
### Changes
- Completely re-synced Pokémon move and stat data based on later games. Learnsets have changed considerably to maximise available moves.
- Pokémon will now be dynamically revealed to the Pokédex as they're seen in battle instead of revealing entire parties at the end of battle.
- Unseen wild Pokémon will update their name from '???' to their real name as soon as a battle starts to match how the battle UI shows the actual species name.
- Pokémon under the illusion effect will reveal their disguise to the Pokédex first and then the base Pokémon once the disguise is broken.
- Berries will now drop from berry trees if broken at age 0 so you aren't punished for mistaken planting.
- Increased Fortune drops on Mint Seeds.
- Updated Slowpoke's shiny texture.
- Updated drops for many Pokémon.
- Adjusted the evolution sound to match the timing of the particle effect.
- Made berry trees shear-able by dispenser blocks. I'm sure nobody will make unholy contraptions with this.
- Edited some recipes to utilize tags instead of direct item IDs, for better mod compatibility.
- Added more support for a variety of Fabric/NeoForge conventional tags.
- Reformatted some tags to be more consistent.
### Fixes
- Fixed Pokédex sometimes crashing when switching forms.
- Fixed Pokédex interface not transitioning out when closed.
- Fixed texture dimensions for the player and Pokémon interact interface.
- Fixed crash related to Tom's Simple Storage mod and the Fossil Machine.
- Fixed not being able to retrieve a fossil from the Fossil Machine with an empty hand.
- Fixed Pokémon being collidable (collidible? collissionable? kaleidoscopable?) while being captured by a Poké Ball.
- Fixed `full_party`, `own_zangoose_seviper`, `use_revive` and `use_candy` Advancement triggers.
- Fixed `healing_machine` Advancement by using the correct 1.21 trigger.
- Fix Display Cases not dropping items if destroyed through explosions.
- Fixed an issue where the first Pokémon in the pastured Pokémon list clipped into the interface.
- Fixed all Pokémon facing South on spawn.
- Fixed bait being consumed even when not reeling in any Pokémon.
- Fixed Miltank milk magically disappearing out of your bucket.
- Fixed Pokémon nicknames migrating from 1.5.2 not being displayed properly.
- Fixed capitalization in one of our config options. It was a very important fix. Very important. Old configs are fine.
- Fixed Poké Rods not working if Lure or Luck of the Sea enchantments get removed by other mods.
- Fixed crashes related to Pokémon when they are ready to evolve while holding an enchanted item. Very specific.
- Fixed a crash that sometimes occurred when evolving Nincada.
- Fixed Cobblemon plants not being compostable on NeoForge.
- Fixed hide UI (F1 key) not hiding the party overlay.
- Fixed NPC MoLang command `player_lose_command` not working.
- Fixed misaligned tooltips with edit boxes in the NPC editor screen.
- Fixed Pokémon riding two boats when attempting to deploy a platform on water.
- Fixed the summary screen showing there's experience to reach the next level when they are at the level cap.
- Fixed Pokémon forgetting moves when evolving on specific cases.
- Fixed Adorn compatibility, including improvements when using JEI/REI (Apricorn items now show up under the collapsed entries rather than standalone).
- Fixed error message appearing on battle log when using Solar Beam with Sunny Day.
- Fixed Pokémon Model offsets for larger species.
- Fixed `/pokedex grant all` command not giving male/female/shininess completion for some Pokémon.
- Fixed `/pokedex grant only` and `/pokedex remove only` not respecting the form parameter passed.
- Fixed variant forms appearing incorrectly in the Pokédex when the normal form had not been unlocked.
- Fixed Pokémon occasionally being shot into the sky during battle. No Pokémon were harmed by this bug, probably.
- Fixed NPC editing GUI not updating aspects until a game restart.
- Fixed some users being unable to open their PC if a Pokémon in it had a lot of PP raises beyond normal bounds. How did you get those, anyway? Tell me or the Bellossom gets it.
- Fixed some color variants (Dubwool, Conkeldurr and Undyed wooloo) being missing in the Pokédex.
- Fixed invalid species or held items causing Players to not be able to load into their world anymore (commonly happening after removing addons/mods).
- Fixed Wooloo variants not being automatically registered in the owner's Pokédex when dyed.
- Fixed Vivichoke Dip and Leek & Potato Stew not returning a bowl upon consumption.
- Fixed Fossil Restoration Tank not accepting Hay Bales as organic material.
- Fixed Potion items applying double their intended healing value.
- Fixed Fast Ball capture bonuses applying to all Pokémon, making it the Best Ball instead of the Mediocre Edge-Case Ball.
- Fixed "learned new move" messages appearing for already-known moves on Pokémon evolutions.
- Fixed Pokémon Item Models breaking shadows nearby when being placed in Display Cases or Item Frames.
- Fixed berries not giving bonus yields when planted in their preferred biomes. I'm sure we've fixed that 5 times now.
- Fixed the NeoForge version not supporting "SodiumDynamicLights".
- Fixed players disconnecting from servers if they made changes to certain config options.
- Fixed players with shouldered Pokémon not being able to rejoin their 1.5.2 worlds using 1.6.
- Fixed `PokemonProperties` utilizing `ability=<some ability>` being treated as a forced ability even when it is a legal ability for the Pokémon.
- Fixed type formatting in Pokédex scanner mode when dual types require two lines.
- Fixed trading sometimes crashing the game or server.
- Fixed Wild shiny sounds not respecting the `shinyNoticeParticlesDistance` config setting.
- Fixed Pokémon being able to evolve mid-battle.
- Fixed NPC held items being able to be stolen by players. Don't be a thief!
- Fixed evolutions that require a held item consuming it as soon as meeting requirements when it should only be consumed upon evolution.
- Fixed Pokémon showing only the default form when selecting them as a target in battle.
- Fixed a possible error coming out of reeling fishing rods in specific situations.
- Fixed incorrect weights being used when Poké Fishing with Luck of the Sea.
- Parametric particle motion now works.
- Event-spawned particles now work.
- Particles can now have independent coordinate spaces.
- Fixed suffocation of Pokémon when a pokeball breaks near a wall
### Developer
- Updated the Pokédex data updated events to always include a `Pokemon` instance, and optionally a `DisguiseData` instance.
- Updated fields in `SpawnNPCPacket` and `SpawnPokemonPacket` to be visible and mutable.
- Updated `UnvalidatedPlaySoundS2CPacket` to be public instead of internal and made its fields mutable.
- Added `hideNameTag` field and `HideNPCNameTag` nbt tag to `NPCEntity` to allow hiding the name tag of the NPC.
- Added the player to `PokerodReelEvent` so you know who is doing the reeling.
### MoLang & Datapacks
- Added flows for:
- `forme_change`: Triggered when a Pokémon changes form in battle.
- `mega_evolution`: Triggered when a Pokémon mega evolves in battle. (Note: Third-party mods are required for this feature currently)
- `zpower_used`: Triggered when a Pokémon uses a Z-Power move in battle. (Note: Third-party mods are required for this feature currently)
- `terastallization`: Triggered when a Pokémon terastallizes in battle. (Note: Third-party mods are required for this feature currently)
- `battle_fainted`: Triggered when a Pokémon faints in battle.
- `battle_fled`: Triggered when a player flees from battle.
- `battle_started_pre`: Triggered when a battle starts. Cancelable!
- `battle_started_post`: Triggered when a battle starts.
- `apricorn_harvested`: Triggered when an Apricorn is harvested.
- `thrown_pokeball_hit`: Triggered when a thrown Pokéball hits a Pokémon.
- `level_up`: Triggered when a Pokémon levels up.
- `pokemon_fainted`: Triggered when a Pokémon faints.
- `pokemon_gained`: Triggered when a player gains a Pokémon.
- Added MoLang functions:
- For Pokémon:
- `pokemon.apply(PokemonProperties)`: Applies the given properties to the Pokémon.
- `pokemon.owner`: Returns the owner of the Pokémon or 0.0 if there is no owner or they are not online.
- For all entities:
- `entity.is_standing_on_blocks(depth, blocks...)`: Returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
- Added NPC field:
- `hideNameTag`: Hides the name tag of the NPC.
- Added `baseScale` property to NPCs.
- Added MoLang particle queries for getting distance to targeted entities.
File diff suppressed because it is too large Load Diff
+61
View File
@@ -0,0 +1,61 @@
# Changelog
## [1.7.1 (November 29th, 2025)](#1-7-1)
### Additions
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader.
- Added brewing recipe for Throat Spray.
- Added vanilla sprinting's field of view change to Pokémon land mounts.
- Added a customizable keybind for the riding freelook button.
- Added double tap to sprint on land mounts.
### Changes
- Made Jet pitch turning 1.5x faster across all Pokémon.
- Party Pokémon now attack only mobs that are attacking their owner, instead of randomly targeting unrelated mobs and getting themselves hurt.
- Reduced the cost of the Vivichoke Seed trade with the Wandering Trader.
### Fixes
- Fixed incorrect camera pivot on Bird, Jet, and Dolphin mounts, leading to some disorienting riding.
- Fixed players suffocating while on vanilla mounts.
- Fixed a graphics crash that could occur on some machines when campfire pots were nearby.
- Fixed ride controls overlay being displayed to passengers. The passengers probably don't need to know about those.
- Fixed mount jumping so that it doesn't switch back to ground animations.
- Fixed ridden Pokémon land collision and some issues around stepping up blocks. Land mounts are smoother overall now.
- Fixed Furfrou's pink and magenta trims being swapped. Only a man could make that mistake.
- Fixed friendship being reset to the default value when evolving a Pokémon.
- Fixed Combees not depositing honey upon leaving a hive if they entered it with nectar.
- Fixed pastured Combees not moving during the night or in rain.
- Fixed a case in which a Combee might try to path to a flower that no longer exists.
- Fixed Combees attempting to enter a full hive.
- Fixed a crash involving Combees and hives. 500 bee bugs. Bugged bees? We can be bees. Mark, this is good news.
- Fixed a crash related to NPC navigation.
- Fixed a crash when opening a PC box with certain wallpapers while using *VulkanMod*.
- Fixed a crash when you place a block in the way of hearty grains 2nd block.
- Fixed passengers hearing the shiny noise of a ridden shiny Pokémon.
- Ponigiri can no longer be eaten at full hunger.
- Fixed Poké Snack spawning sounds not coming from the block.
- Medicinal Brew's Campfire Pot recipe now correctly displays that it can be made using an empty glass bottle or a filled bottle.
- Fixed glass bottle not being returned when slathering honey on a saccharine leaf block.
- Fixed saccharine hanging signs sometimes dropping their oak wood counterpart when being broken.
- Fixed a bunch of incompatibilities with NeoForge mods.
- Fixed a bug where wind charges hitting pasture blocks would recall all Pokémon in it.
- Fixed the Home on the Range advancement triggering when opening the Pokémon interaction wheel.
- Fixed recipes that use concrete not working on NeoForge.
- Fixed Boltund's model.
- Fixed Cyclizar's textures.
### Developer
### Molang & Datapacks
- Removed automatic generation of PC wallpaper screen glow if no asset is provided; it is now optional.
- This is because there's no practical way to do this without blowing up things like *VulkanMod*.
### Particles
### Localization
- Updated translations for:
- French
- Japanese
- Korean
- Brazilian Portuguese
- Simplified Chinese
- Traditional Chinese
+137
View File
@@ -0,0 +1,137 @@
# Changelog
## [1.7.2 (January 25th, 2026)](#1-7-2)
### Additions
- Added Saccharine wood furniture for Adorn.
- Added the Partner Mark, which party Pokémon have a very small chance to earn as the player walks, provided they have enough friendship.
- Added decorative block models for existing items: Potion, Super Potion, Hyper Potion, Max Potion, Full Restore, Antidote, Awakening, Burn Heal, Ice Heal, Paralyze Heal, Full Heal, Ether, Elixir, Max Ether, Max Elixir, X Accuracy, X Attack, X Defence, X Special Attack, X Special Defence, X Speed, Dire Hit, Guard Spec, Weakness Policy, Blunder Policy, Cleanse Tag, and Spell Tag.
- Added decorative sign blocks called Plaques.
- Added ride style labels to ride stats in Pokédex, as well as ride style icons in the summary GUI.
- Added more seasonings for sinister tea:
- Mental Herb - Mental Restoration I for 10 seconds, which staves off Insomnia.
- White Herb - Removes negative effects.
- Milk, Moomoo Milk - Removes effects.
- Added dispenser support for:
- Applying a Honey Bottle to Saccharine Logs.
- Washing honey off of Saccharine Slathered Logs.
- Applying and removing honey on Saccharine Leaves.
- Added riding statistics: `Distance by Pokémon on Land`, `Distance by Pokémon in Air` and `Distance by Pokémon in Liquid`.
### New rideable Pokémon
- Honchkrow
- Mantine
### Pokémon Added
#### Gen 5
- Throh
- Sawk
#### Gen 6
- Litleo
- Pyroar
- Spritzee
- Aromatisse
- Swirlix
- Slurpuff
### Model updates for the following Pokémon
- Falinks
- Cottonee
- Whimsicott
- Ferroseed
- Ferrothorn
- Chingling
- Chimecho
### Animation updates for the following Pokémon
- Mantine (ride animations)
- Flygon (ride jump animation)
- Honchkrow (ride animations)
- Croagunk
- Toxicroak
### Changes
- Added a new config option, `Enable In-Flight Dismounting` (default: off), which lets you dismount while riding a Pokémon in the air. This is the textbook definition of caveat emptor.
- Ride sounds have been separated into stereo for passengers and mono for other players. Riding will now sound more spacious.
- Battle AI now uses a smarter threshold for switching, reducing unnecessary switches.
- AI will always use the most damaging move when at low HP and when it is not switching, improving endgame decision-making.
- Items given from interacting with Saccharine Leaves are placed in the active hotbar slot if possible.
- Added `label` as an alternate key to the `tag` property.
### Fixes
- Fixed crashing when viewing another player in spectator mode. Some said this was reason to release this update a month ago. They were probably right.
- Fixed crashing when sending a Pokémon out after editing its form.
- Fixed all Pokémon being saved to chunks and never despawning even when they should be.
- Fixed Poké Snacks crashing if there was no available spawn.
- Fixed Poké Snack / Bait effects so that EV Yield, Type, and Egg Group filters now all apply together when weighting spawns. And you thought you were going crazy.
- Fixed Furfrou not being trimmable on NeoForge specifically.
- Fixed honey from Saccharine Leaves being harvestable at less than the max age.
- Fixed possible error on world generation when Combee are placed in naturally generated bee nests.
- Fixed Galarian Weezing crashing the world if it decides to blink the wrong way. The same could happen to you!
- Fixed Galarian Mr. Mime incorrectly being rideable. Some would argue that regular Mr. Mime shouldn't be rideable, but that would make them wrong.
- Fixed missing apricorn textures for Adorn blocks.
- Fixed Apricorn block model rotation for counters/sinks/cupboards/drawers to match that of most recent version of Adorn.
- Fixed item interaction sometimes not working properly when playing on servers.
- Fixed Mint Leaves not being usable for filling the Resurrection Machine.
- Fixed Super Potion recipes incorrectly using Hondew Berry instead of Aguav Berry. They look similar, to be fair.
- Fixed Wishiwashi not schooling properly.
- Fixed battle item duplication issue. How did it work? Wouldn't you like to know, weather boy.
- Fixed the ordering of Aprijuice's riding stat boosts so they always have the same order.
- Fixed the movesets of certain Pokémon being incorrectly sanitized upon reload, causing some forms to keep losing moves.
- Fixed selected leading Pokémon in battle not being used when levels are set.
- Fixed the bottom half of pasture blocks having an incorrect hit-box when facing north or south.
- Fixed gimmicks not being usable in double and triple battles.
- Fixed gimmick buttons showing when already used in the same turn in double and triple battles.
- Fixed mochi items consuming two items at a time.
- Fixed Fresh Start Mochi's EV reset not syncing health changes properly.
- Fixed Pokémon spawn influences not being specific to regional forms.
- Fixed memory leak from battles not being cleaned up after ending.
- Fixed orientation not getting reset after crashing while flying and getting back on the Pokémon.
- Fixed shiny Pokémon not respecting the `silent` flag on spawn.
- Fixed 'Plain' prefix not being applied to all low-quality Aprijuice.
- Fixed Pokémon interactions not playing sound effects when the volume was not specified.
- Fixed Pokémon interaction cooldowns taking longer than intended when the Pokémon was in the player’s party.
- Fixed Pokémon interactions occasionally crashing the game when spamming an interaction with a 0 cooldown.
- Fixed Pokémon fullness decreasing more than intended when the Pokémon was pastured.
- Fixed Scraggy line, Milcery line, and Morpeko spawning on unnatural blocks.
- Fixed invulnerability-bypassed damage being resisted by invulnerable NPC entities.
- Fixed Fabric network packets not being handled immediately, fixing incompatibilities with Supplementaries, Prometheus, Sleep Tight, and others.
- Fixed killer not being set early enough on a wild Pokémon entity from `WinInstruction`.
- Fixed requirements such as `biomeCondition` crashing the game when used to define Pokémon interactions.
- Fixed an issue that prevented registering custom dispenser behaviours (no longer overrides vanilla behaviour).
- Fixed an issue navigation that prevented Combee from pathing into and out of Saccharine Leaves.
- Added Saccharine Boats and Saccharine Boat with Chests to relevant boat tags.
- Fixed Soothe Bell not being properly tagged as a held item.
- Fixed `/calculateseatpositions` expecting a locator format that even we don't use. It needs an underscore after "seat".
- Fixed the `run_script` Molang function to not fail if the environment's context is null.
- Fixed the Molang functions `date_local_time`, `date_of`, `date_is_after` to use the correct date format.
### Developer
- Changed the `owner` parameter in the `OwnerQueryRequirement` interface from `ServerPlayer` to `Player`. This method is now also called on the client to verify whether a Pokémon interaction succeeded, so make sure to update your implementations to handle both server and client contexts.
- Added the `pnx` to the `BattleFaintedEvent` and `FormeChangeEvent`.
- Added register methods for custom instructions to `ShowdownInterpreter`.
- Changed callback operations in `BattlePokemon` to allow multiple callbacks and be mutable.
- Added `display_name`, `description`, and `max_pp` functions to the `MoveTemplate` struct.
- Changed the implementations of `AIBattleActor` to be open classes to allow extension.
- Changed the resource location of Poké Ball icons in the GUI to use the balls namespace instead of Cobblemon's, allowing mods to properly use their own namespace for these textures.
### Molang & Datapacks
- Ride sounds can now be set as exclusive to passengers.
- Ride sounds no longer play when submerged unless specified with a new setting.
- Exception handling has been added to `run_molang`, resolving some crashes caused by malformed MoLang expressions.
- Added the `create_itemstack`, `has_inventory_space`, `set_inventory_slot`, and `give_item` MoLang functions for item and inventory utility.
- Added the `get_move_from_id` MoLang function for general move info queries without requiring a Moveset object to access.
- Added support for optional message variants in battle activate instructions for more context-specific battle text.
- Example: `this.add('-activate', pokemon, 'ability: example', '[msg]message1');` will parse to lang key `cobblemon.battle.activate.example.message1`.
### Localization
- Updated translations for:
- French
- Canadian French
- Simplified Chinese
- Ukrainian
- Brazilian Portuguese
- Spanish
- Korean
- Japanese
+22
View File
@@ -0,0 +1,22 @@
# Changelog
## [1.7.3 (January 31st, 2026)](#1-7-3)
### Fixes
- Fixed mounted Pokémon not playing sounds.
- Fixed players failing to join servers randomly.
- Fixed some Pokémon having no stamina for flying.
- Fixed `/pctake` not respecting the actual size of the PC.
### Developer
- Poké Ball GUI textures now respect the ball's namespace, enabling proper texture loading for custom balls from other mods.
### Molang & Datapacks
- Added a `chance` requirement type for Pokémon interactions.
### Localization
- Updated translations for:
- French
- Canadian French
- Korean
- Portuguese
- Simplified Chinese
- Spanish
+1 -1
View File
@@ -55,7 +55,7 @@ dependencies {
// modCompileOnly(libs.flywheelFabric)
// Showdown
modCompileOnly(libs.graal)
modCompileOnly(libs.graal.core)
// Data Storage
modCompileOnly(libs.bundles.mongo)
@@ -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.duck;
import com.mongodb.lang.Nullable;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import org.joml.Vector3f;
public interface CameraDuck {
BlockGetter cobblemon$getLevel();
@Nullable
Entity cobblemon$getEntity();
Vector3f cobblemon$getForwards();
Vector3f cobblemon$getUp();
Vector3f cobblemon$getLeft();
float cobblemon$getXRot();
void cobblemon$setXRot(float xRot);
float cobblemon$getYRot();
void cobblemon$setYRot(float yRot);
}
@@ -11,12 +11,15 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.CobblemonMemories;
import com.cobblemon.mod.common.api.ai.config.task.PathToBeeHiveTaskConfig;
import com.cobblemon.mod.common.api.pokemon.PokemonProperties;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.world.feature.SaccharineTreeFeature;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BeehiveBlock;
@@ -41,7 +44,21 @@ public abstract class BeeOccupantMixin {
if (cir.getReturnValue() == null) {
final BeehiveBlockEntity.Occupant occupant = (BeehiveBlockEntity.Occupant) (Object) this;
CompoundTag compoundTag = occupant.entityData().copyTag();
Entity entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
String id = compoundTag.getString("id");
Entity entity = null;
if (id.equals(SaccharineTreeFeature.Companion.getPOKEMON_PLACEHOLD_ID())) {
// Special case for Pokemon stuffed into a beenest upon world gen.
// For technical reasons we cannot create them as full entities during world gen.
// So we look for this special id tag and complete the entity when it attempts to exit a hive.
if (compoundTag.contains("pokemonProperties")) {
String properties = compoundTag.getString("pokemonProperties");
PokemonProperties pokemon = PokemonProperties.Companion.parse(properties);
entity = pokemon.createEntity(level);
}
} else {
entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
}
if (entity instanceof PokemonEntity pokemonEntity) {
var state = level.getBlockState(pos);
var newPos = Vec3.ZERO;
@@ -50,37 +67,45 @@ public abstract class BeeOccupantMixin {
if (state.is(BlockTags.BEEHIVES)) {
// position in front of the entrance, face away from the block
var facing = state.getValue(HorizontalDirectionalBlock.FACING);
newPos = pos.relative(facing).getCenter();
newPos = pos.relative(facing).getBottomCenter();
newYaw = facing.toYRot();
brain.setMemory(CobblemonMemories.INSTANCE.getHIVE_LOCATION(), pos); // This needs to be set in the case that the hive was picked up and moved.
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
}
} else {
// Block has likely been destroyed
var center = pos.getCenter();
var center = pos.getBottomCenter();
newPos = new Vec3(
center.x + level.random.nextFloat() * 0.6 - 0.3,
center.y + level.random.nextFloat() * 0.6 - 0.3,
center.z + level.random.nextFloat() * 0.6 - 0.3
);
newYaw = level.random.nextFloat() * 360F;
brain.eraseMemory(CobblemonMemories.INSTANCE.getHIVE_LOCATION());
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
}
}
entity.yRotO = newYaw;
entity.setPos(newPos);
// Do honey logic
var hasNectar = brain.getMemory(CobblemonMemories.INSTANCE.getHAS_NECTAR()).orElse(false);
if (hasNectar) {
// Remove nectar and reset got to hive cooldown
brain.eraseMemory(CobblemonMemories.INSTANCE.getHAS_NECTAR());
brain.setMemoryWithExpiry(CobblemonMemories.INSTANCE.getHIVE_COOLDOWN(), true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
// Increment honey level of the hive
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
if (i < 5) {
int j = level.random.nextInt(100) == 0 ? 2 : 1;
if (i + j > 5) {
--j;
if (brain.checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)) {
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
if (hasNectar) {
// Remove nectar and reset got to hive cooldown
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
}
// Increment honey level of the hive
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
if (i < 5) {
int j = level.random.nextInt(100) == 0 ? 2 : 1;
if (i + j > 5) {
--j;
}
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
}
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
}
}
}
@@ -92,16 +117,16 @@ public abstract class BeeOccupantMixin {
@Inject(method = "of", at = @At("HEAD"), cancellable = true)
private static void cobblemon$of(Entity entity, CallbackInfoReturnable<BeehiveBlockEntity.Occupant> cir) {
if (entity instanceof PokemonEntity pokemonEntity) {
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "Brain", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
CompoundTag compoundTag = new CompoundTag();
entity.save(compoundTag);
Objects.requireNonNull(compoundTag);
IGNORED_BEE_TAGS.forEach(compoundTag::remove);
Boolean hasNectar = pokemonEntity.getBrain().getMemory(CobblemonMemories.INSTANCE.getHAS_NECTAR()).orElse(false);
boolean hasNectar = pokemonEntity.getBrain().checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)
&& pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
cir.setReturnValue(new BeehiveBlockEntity.Occupant(CustomData.of(compoundTag), 0, hasNectar ? 2400 : 600));
cir.cancel();
}
}
}
}
@@ -1,38 +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.block.PreEmptsExplosion;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(value = Explosion.class)
public class ExplosionMixin {
@Redirect(
method = "finalizeExplosion",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
ordinal = 0
)
)
public BlockState cobblemon$whenExploded(Level world, BlockPos pos) {
BlockState blockState = world.getBlockState(pos);
if(blockState.getBlock() instanceof PreEmptsExplosion preExplosionBlock) {
preExplosionBlock.whenExploded(world, blockState, pos);
}
return blockState;
}
}
@@ -15,6 +15,8 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents;
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
import com.cobblemon.mod.common.api.riding.RidingStyle;
import com.cobblemon.mod.common.api.riding.behaviour.types.air.HoverBehaviour;
import com.cobblemon.mod.common.api.storage.party.PartyStore;
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
@@ -38,6 +40,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
@@ -58,6 +61,7 @@ import org.spongepowered.asm.mixin.Shadow;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -168,6 +172,32 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
}
}
@Redirect(
method = "getDestroySpeed",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/player/Player;onGround()Z"
)
)
private boolean cobblemon$considerHoverOnGround(Player player) {
// If riding a Hover Mount, return true to bypass the 5x slowdown
if (player.getVehicle() instanceof PokemonEntity vehicle) {
var ridingController = vehicle.getRidingController();
if (ridingController == null) player.onGround();
var activeContext = ridingController.getContext();
if (activeContext == null) player.onGround();
if (activeContext.getStyle() == RidingStyle.AIR &&
activeContext.getBehaviour().equals(HoverBehaviour.Companion.getKEY())) {
return true;
}
}
// Otherwise, return the actual value
return player.onGround();
}
@Inject(
method = "eat",
at = @At(
@@ -221,24 +251,25 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
@Nullable @Unique
private PokedexEntityData getDataFromShoulderPokemon(CompoundTag shoulderTag) {
CompoundTag pokemonTag = shoulderTag.getCompound(DataKeys.POKEMON);
if (pokemonTag.isEmpty()) return null;
Species species = PokemonSpecies.INSTANCE.getByIdentifier(ResourceLocation.parse(pokemonTag.getString(DataKeys.POKEMON_SPECIES_IDENTIFIER)));
if (species == null) return null;
String formId = pokemonTag.getString(DataKeys.POKEMON_FORM_ID);
FormData form = species.getStandardForm();
List<FormData> formList = species.getForms().stream().filter(it -> it.formOnlyShowdownId().equals(formId)).toList();
if (!formList.isEmpty()) form = formList.getFirst();
if (form == null) return null;
String genderString = pokemonTag.getString(DataKeys.POKEMON_GENDER);
if (genderString.isEmpty()) return null;
Gender gender = Gender.valueOf(genderString);
boolean shiny = pokemonTag.getBoolean(DataKeys.POKEMON_SHINY);
int level = pokemonTag.getInt(DataKeys.POKEMON_LEVEL);
Set<String> aspects = shoulderTag.getList(DataKeys.SHOULDER_ASPECTS, Tag.TAG_STRING).stream().map(Tag::getAsString).collect(Collectors.toSet());
Pokemon pokemon = new Pokemon();
Pokemon pokemon;
if (level().isClientSide) {
CompoundTag pokemonTag = shoulderTag.getCompound(DataKeys.POKEMON);
if (pokemonTag.isEmpty()) return null;
Species species = PokemonSpecies.getByIdentifier(ResourceLocation.parse(pokemonTag.getString(DataKeys.POKEMON_SPECIES_IDENTIFIER)));
if (species == null) return null;
String formId = pokemonTag.getString(DataKeys.POKEMON_FORM_ID);
FormData form = species.getStandardForm();
List<FormData> formList = species.getForms().stream().filter(it -> it.formOnlyShowdownId().equals(formId)).toList();
if (!formList.isEmpty()) form = formList.getFirst();
if (form == null) return null;
String genderString = pokemonTag.getString(DataKeys.POKEMON_GENDER);
if (genderString.isEmpty()) return null;
Gender gender = Gender.valueOf(genderString);
boolean shiny = pokemonTag.getBoolean(DataKeys.POKEMON_SHINY);
int level = pokemonTag.getInt(DataKeys.POKEMON_LEVEL);
Set<String> aspects = shoulderTag.getList(DataKeys.SHOULDER_ASPECTS, Tag.TAG_STRING).stream().map(Tag::getAsString).collect(Collectors.toSet());
pokemon = new Pokemon();
pokemon.setSpecies(species);
pokemon.setForm(form);
pokemon.setGender(gender);
@@ -249,7 +280,7 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
PlayerPartyStore party = Cobblemon.INSTANCE.getStorage().getParty(this.getUUID(), this.registryAccess());
pokemon = party.get(shoulderTag.getUUID(DataKeys.SHOULDER_UUID));
}
return new PokedexEntityData(pokemon, null);
return (pokemon == null) ? null : new PokedexEntityData(pokemon, null);
}
@Override
@@ -317,7 +348,7 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
@Override
public void cobblemon$setRideXRot(float rideXRot) {
this.cobblemon$rideXRot = rideXRot;
this.cobblemon$rideXRot = Mth.wrapDegrees(rideXRot);
}
@Override
@@ -327,7 +358,7 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
@Override
public void cobblemon$setRideYRot(float rideYRot) {
this.cobblemon$rideYRot = rideYRot;
this.cobblemon$rideYRot = Mth.wrapDegrees(rideYRot);
}
@Override
@@ -1,33 +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 net.minecraft.stats.RecipeBookSettings;
import net.minecraft.world.inventory.RecipeBookType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(RecipeBookSettings.class)
public class RecipeBookSettingsMixin {
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
@Inject(method = "<init>", at = @At("TAIL"))
private void cobblemon$init(CallbackInfo ci) {
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
}
}
@@ -11,11 +11,15 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.PlayerSpawnerAccessor;
import com.cobblemon.mod.common.api.riding.RidingStyle;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
import com.cobblemon.mod.common.api.stats.CobblemonStats;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -89,4 +93,32 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
private boolean cobblemon$cancelSavingPokemonMounts(boolean original, @Local(ordinal=0) Entity entity) {
return original && !(entity instanceof PokemonEntity);
}
@WrapOperation(method = "checkRidingStatistics", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getVehicle()Lnet/minecraft/world/entity/Entity;"))
public Entity cobblemon$checkRidingStatistics(ServerPlayer player, Operation<Entity> original, @Local int distance) {
var entity = original.call(player);
if (!(entity instanceof PokemonEntity pokemonEntity)) {
return entity;
}
var ridingController = pokemonEntity.getRidingController();
if (ridingController == null) return entity;
var activeContext = ridingController.getContext();
if (activeContext == null) return entity;
var ridingStyle = activeContext.getStyle();
CobblemonStats.CobblemonStat stat = switch (ridingStyle) {
case RidingStyle.LAND -> CobblemonStats.RIDING_LAND;
case RidingStyle.AIR -> CobblemonStats.RIDING_AIR;
case RidingStyle.LIQUID -> CobblemonStats.RIDING_LIQUID;
default -> null;
};
if (stat != null) {
player.awardStat(CobblemonStats.getStat(stat), distance);
}
return entity;
}
}
@@ -11,23 +11,19 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.block.HeartyGrainsBlock;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.DoublePlantBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.SimpleBlockFeature;
import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration;
import org.spongepowered.asm.mixin.Debug;
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;
@Mixin(SimpleBlockFeature.class)
@Debug(export = true, print = true)
public class SimpleBlockFeatureMixin {
//this mixin inserts the logic needed to ensure that when hearty grains are of a certain age, they place with the upper block too
//similarly to what the doubleblock logic is here
@@ -55,86 +55,6 @@ public abstract class SoundEngineMixin implements SoundEngineDuck {
@Shadow
public abstract boolean isActive(SoundInstance sound);
@Inject(method = "play",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/sounds/ChannelAccess$ChannelHandle;execute(Ljava/util/function/Consumer;)V"
),
cancellable = true
)
private void cobblemon$overrideChannelExecute(
SoundInstance sound,
CallbackInfo ci,
@Local(name = "h") float h,
@Local(name = "i") float i,
@Local(name = "g") float g,
@Local(name = "bl2") boolean bl2,
@Local(name = "bl3") boolean bl3,
@Local(name = "bl") boolean bl,
@Local(name = "vec3") Vec3 vec3,
@Local(name = "channelHandle") ChannelAccess.ChannelHandle handle
) {
if (!(sound instanceof RideLoopSound rideSound)) return;
if (handle == null) return;
handle.execute((channel) -> {
channel.setPitch(i);
channel.setVolume(h);
if (rideSound.getRideAttenuation() == RideAttenuationModel.LINEAR) {
channel.linearAttenuation(g);
} else if (rideSound.getRideAttenuation() == RideAttenuationModel.EXPONENTIAL){
((ChannelDuck) channel).cobblemon$inverseAttenuation(g);
} else {
channel.disableAttenuation();
}
// Apply low pass filter if the rideSound dictate that it should be muffled
if (rideSound.getShouldMuffle()) {
((ChannelDuck) channel).cobblemon$applyLowPassFilter(1.0f, rideSound.getMuffleAmount());
} else {
((ChannelDuck) channel).cobblemon$clearFilters();
}
channel.setLooping(bl2 && !bl3);
channel.setSelfPosition(vec3);
channel.setRelative(bl);
});
}
@Inject(
method = "tickNonPaused",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/sounds/ChannelAccess$ChannelHandle;execute(Ljava/util/function/Consumer;)V",
ordinal = 0
)
)
private void cobblemon$tickableSoundTick(
CallbackInfo ci,
@Local(name = "tickableSoundInstance") TickableSoundInstance instance,
@Local(name = "channelHandle", ordinal = 0) ChannelAccess.ChannelHandle handle,
@Local(name = "f", ordinal = 0) float volume,
@Local(name = "g", ordinal = 0) float pitch,
@Local(name = "vec3", ordinal = 0) Vec3 vec3
) {
if (!(instance instanceof RideLoopSound rideSound)) return;
handle.execute(channel -> {
channel.setVolume(volume);
channel.setPitch(pitch);
channel.setSelfPosition(vec3);
// Apply low pass filter if the rideSound dictate that it should be muffled
if (rideSound.getShouldMuffle()) {
((ChannelDuck) channel).cobblemon$applyLowPassFilter(1.0f, rideSound.getMuffleAmount());
} else {
((ChannelDuck) channel).cobblemon$clearFilters();
}
});
}
/** Resumes the Source belonging to the queried SoundInstance. */
private void resume(SoundInstance sound) {
ChannelAccess.ChannelHandle sourceManager = this.instanceToChannel.get(sound);
@@ -8,13 +8,19 @@
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.client.Camera;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.item.Item;
import net.minecraft.core.dispenser.DispenseItemBehavior;
import net.minecraft.world.level.block.DispenserBlock;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Camera.class)
public interface CameraAccessor {
@Accessor("level")
BlockGetter getLevel();
}
@Mixin(DispenserBlock.class)
public interface DispenserBlockAccessor {
@Accessor("DISPENSER_REGISTRY")
static Map<Item, DispenseItemBehavior> getItemBehaviors() {
throw new AssertionError();
}
}
@@ -27,7 +27,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(BrewingStandMenu.class)
public abstract class BrewingStandMenuMixin {
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;Lnet/minecraft/world/inventory/ContainerData;)V", at = @At("TAIL"))
private void captureLevel(int containerId, Inventory playerInventory, Container brewingStandContainer, ContainerData brewingStandData, CallbackInfo ci) {
var recipeManager = playerInventory.player.level().getRecipeManager();
@@ -37,9 +36,4 @@ public abstract class BrewingStandMenuMixin {
}
}
}
@WrapOperation(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/BrewingStandMenu$PotionSlot;mayPlaceItem(Lnet/minecraft/world/item/ItemStack;)Z"))
private boolean cobblemon$isPotionBottle(ItemStack stack, Operation<Boolean> original, @Local(argsOnly = true) Player player) {
return BrewingStandRecipe.Companion.isBottle(stack, player.level().getRecipeManager()) || original.call(stack);
}
}
@@ -33,7 +33,7 @@ public class AbstractClientPlayerMixin {
cir.setReturnValue(usageContext.getFovMultiplier());
} else {
// Only modify fov through riding if the pokedex is not open
LocalPlayer player = (LocalPlayer) (Object) this;
AbstractClientPlayer player = (AbstractClientPlayer) (Object) this;
// Only modify fov for the driver and not the passengers
if (player != null && player.isPassenger() && player.getVehicle() instanceof PokemonEntity && player.getVehicle().getControllingPassenger() == player) {
PokemonEntity ride = (PokemonEntity) player.getVehicle();
@@ -8,97 +8,58 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.riding.Rideable;
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController;
import com.cobblemon.mod.common.client.render.camera.MountedCameraRenderer;
import com.cobblemon.mod.common.duck.RidePassenger;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.duck.CameraDuck;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.Blaze3D;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix3f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.CallbackInfo;
@Mixin(Camera.class)
public abstract class CameraMixin {
@Shadow private Entity entity;
@Shadow @Final private Quaternionf rotation;
@Shadow @Final private Vector3f forwards;
@Shadow @Final private Vector3f up;
@Shadow @Final private Vector3f left;
@Shadow private float xRot;
@Shadow private float yRot;
public abstract class CameraMixin implements CameraDuck {
@Shadow private float eyeHeight;
@Shadow private float eyeHeightOld;
@Shadow private BlockGetter level;
@Shadow private Entity entity;
@Final @Shadow private Vector3f forwards;
@Final @Shadow private Vector3f up;
@Final @Shadow private Vector3f left;
@Shadow private float yRot;
@Shadow private float xRot;
@Shadow protected abstract void setPosition(Vec3 pos);
@Shadow private float partialTickTime;
// Used to help in camera rotation rendering when transitioning
// from rolled to unrolled.
@Unique private float cobblemon$returnTimer = 0;
@Unique private float cobblemon$rollAngleStart = 0;
@Unique private double cobblemon$lastHandledRotationTime = Double.MIN_VALUE;
@Unique private double cobblemon$frameTime = 0.0;
// Used to as the render rotation for the motion sick camera.
@Unique @Nullable private Quaternionf cobblemon$smoothRotation = null;
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
// Calculate the current frametime
double d = Blaze3D.getTime();
this.cobblemon$frameTime = (this.cobblemon$lastHandledRotationTime != Double.MIN_VALUE) ? d - this.cobblemon$lastHandledRotationTime : 0.0;
this.cobblemon$lastHandledRotationTime = d;
// Do no camera rotations if the game is paused
if(Minecraft.getInstance().isPaused()) return;
// Don't assume the camera to be attached to an entity. Ponder Scenes from create et.al. for example aren't.
if (this.entity == null) return;
var vehicle = this.entity.getVehicle();
if (!(vehicle instanceof OrientationControllable controllableVehicle)) return;
var instance = (Camera)(Object)this;
// If the current vehicle has no orientation then return and perform
// vanilla camera rotations
var vehicleController = controllableVehicle.getOrientationController();
if (vehicleController.getOrientation() == null) return;
// If the controller has been deactivated but the orientation isn't null yet
// then perform transition from rolled ride/camera to vanilla
if (!vehicleController.isActive() && vehicleController.getOrientation() != null) {
cobblemon$applyTransitionRotation(vehicleController, ci);
} else { // Otherwise perform cobblemon specific camera rotation and set transition helper variables
cobblemon$applyRotation();
this.cobblemon$returnTimer = 0;
this.cobblemon$rollAngleStart = instance.rotation().getEulerAnglesYXZ(new Vector3f()).z();
ci.cancel();
}
@Override public BlockGetter cobblemon$getLevel() {
return level;
}
@Override public Entity cobblemon$getEntity() {
return entity;
}
@Override public Vector3f cobblemon$getForwards() { return forwards; }
@Override public Vector3f cobblemon$getUp() { return up; }
@Override public Vector3f cobblemon$getLeft() { return left; }
@Override public float cobblemon$getXRot() { return xRot; }
@Override public void cobblemon$setXRot(float xRot) { this.xRot = xRot; }
@Override public float cobblemon$getYRot() { return yRot; }
@Override public void cobblemon$setYRot(float yRot) { this.yRot = yRot; }
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setPosition(DDD)V"))
public void cobblemon$positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
Entity entity = instance.getEntity();
@@ -107,177 +68,22 @@ public abstract class CameraMixin {
if(vehicle instanceof Rideable){
Vec3 position = MountedCameraRenderer.INSTANCE.getCameraPosition(
instance,
entity,
vehicle,
x,
y,
z,
thirdPersonReverse,
eyeHeightOld,
eyeHeight
instance,
entity,
vehicle,
thirdPersonReverse,
eyeHeight,
eyeHeightOld
);
if(position != null){
if(position != null) {
setPosition(position);
return;
}
}
// reset the rotation values if it is now not being ridden.
cobblemon$smoothRotation = null;
MountedCameraRenderer.INSTANCE.setSmoothRotation(null);
original.call(instance, x, y, z);
}
@Unique
private void cobblemon$applyRotation(){
var driver = this.entity;
if (!(driver.getVehicle() instanceof OrientationControllable controllableVehicle) ||
controllableVehicle.getOrientationController().getOrientation() == null ||
!controllableVehicle.getOrientationController().getActive()
) return;
// Grab the driver and vehicle orientation controllers.
var vehicleController = controllableVehicle.getOrientationController();
var isDriving = driver.getControlledVehicle() != null;
// Grab the ride orientation
var newRotation = new Quaternionf();
// If the player is driving then use the current orientation since the driver sets it.
// If not then use the smoothed render orientation for passengers otherwise the vehicle rotation will be jerky
if (isDriving) {
newRotation = vehicleController.getOrientation().normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
} else {
newRotation = vehicleController.getRenderOrientation(this.partialTickTime);
}
// Unroll the current rotation if no roll is requested and not currently freelooking.
if (Cobblemon.config.getDisableRoll()) {
// Init the smooth rotation if it has not been set yet.
if (cobblemon$smoothRotation == null) {
cobblemon$smoothRotation = new Quaternionf().set(this.rotation);
}
var rideAngs = newRotation.getEulerAnglesYXZ(new Vector3f());
var cameraAngs = cobblemon$smoothRotation.getEulerAnglesYXZ(new Vector3f());
// var vehicle = (PokemonEntity)driver.getVehicle();
// var vel = vehicle.getRidingAnimationData().getVelocitySpring().getInterpolated(this.partialTickTime, 0);
// // Grab the target yaw as the current rides yaw. If the horizontal velocity is high enough to be used to
// // derive a yaw then use it.
// var targetYaw = (double) rideAngs.y();
// if ( vel.horizontalDistance() > 0.01) {
// // lerp the new rotation towards this y rot at a rate proportional to the horizontal movement speed?
// targetYaw = Mth.wrapDegrees(Math.toDegrees(Mth.atan2(vel.x(), vel.z())) + 180.0f);
// }
var degDiff = Mth.degreesDifference((float)Math.toDegrees(cameraAngs.y()), (float)Math.toDegrees(rideAngs.y));
var pitchDeadzoneDeg = 15.0; // x degrees of deadzone about +-90 degrees of pitch.
var pitchDeg = vehicleController.getPitch();
// ConsiderPitch to be already 90 if within the deadzone around it.
var cutoffPitch = Math.min(1.0,(Mth.abs(pitchDeg) / (90.0f - pitchDeadzoneDeg))) * 90.0f * Math.signum(pitchDeg);
var lerpRateMod = Mth.cos((float)Math.toRadians(cutoffPitch));
// Apply smoothing from the cameras current yaw to the yaw of the velocity vector of the ride.
var k = 10.0f; // Some smoothing constant k
var smoothingFactor = lerpRateMod * cobblemon$frameTime * k;
var newYaw = cameraAngs.y() + (Math.toRadians(degDiff) * smoothingFactor);
var newPitch = (float)Mth.lerp(cobblemon$frameTime * k, cameraAngs.x(), rideAngs.x());
//var newYaw = (float)Mth.lerp(smoothingFactor, cameraAngs.y(), rideAngs.y());
var maxRoll = Math.toRadians(15.0f);
var newRoll = (float)Mth.lerp(cobblemon$frameTime * k / 2.0, cameraAngs.z(), Math.abs(lerpRateMod) * Math.sin(rideAngs.z()) * maxRoll);
// Set rotations
var smoothedRot = new Quaternionf().rotateYXZ((float)newYaw, newPitch, newRoll);
cobblemon$smoothRotation.set(smoothedRot);
newRotation.set(smoothedRot);
}
var rotationOffset = 0;
if (Minecraft.getInstance().options.getCameraType().isMirrored()) {
newRotation.rotateY((float)Math.toRadians(180));
rotationOffset = 180;
}
// Get the drivers local look angle in relation to the ride and apply it.
if (vehicleController.getActive()) {
var vehicleMatrix = new Matrix3f().set(newRotation);
var driverMatrix = new Matrix3f();// Base the driver
var playerRotater = (RidePassenger)driver;
newRotation = vehicleMatrix.mul(
driverMatrix.rotateYXZ(
-Mth.DEG_TO_RAD * (playerRotater.cobblemon$getRideYRot()),
-Mth.DEG_TO_RAD * playerRotater.cobblemon$getRideXRot(),
0.0f)
).normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
}
this.rotation.set(newRotation);
var eulerAngs = newRotation.getEulerAnglesXYZ(new Vector3f());
this.xRot = eulerAngs.x() * Mth.RAD_TO_DEG;
this.yRot = eulerAngs.y() * Mth.RAD_TO_DEG;
// Set the drivers rotations to match
var driverEulerAngs = new Quaternionf(this.rotation).getEulerAnglesYXZ(new Vector3f());
driver.setXRot(-driverEulerAngs.x() * Mth.RAD_TO_DEG + rotationOffset);
driver.setYRot(180.0f - (driverEulerAngs.y() * Mth.RAD_TO_DEG));
OrientationController.Companion.getFORWARDS().rotate(this.rotation, this.forwards);
OrientationController.Companion.getUP().rotate(this.rotation, this.up);
OrientationController.Companion.getLEFT().rotate(this.rotation, this.left);
}
@Unique
private void cobblemon$applyTransitionRotation(
OrientationController vehicleController,
CallbackInfo ci
) {
// If the transition has just started then
if (this.cobblemon$returnTimer == 0.0) {
MountedCameraRenderer.INSTANCE.resetDriverRotations((Camera)(Object)this, this.entity);
}
if(this.cobblemon$returnTimer < 1) {
//Rotation is taken from entity since we no longer handle mouse ourselves
//Stops a period of time when you can't input anything.
float interpolatedRoll = Mth.lerp(this.cobblemon$returnTimer, this.cobblemon$rollAngleStart, 0.0f);
float pitch = (float) Math.toRadians(-this.entity.getXRot());
float yaw = (float) Math.toRadians(180 - this.entity.getYRot());
Quaternionf interRot = new Quaternionf();
interRot.rotationYXZ(yaw, pitch, interpolatedRoll);
this.rotation.set(interRot);
var eulerAngs = interRot.getEulerAnglesXYZ(new Vector3f());
this.xRot = eulerAngs.x() * Mth.RAD_TO_DEG;
this.yRot = eulerAngs.y() * Mth.RAD_TO_DEG;
OrientationController.Companion.getFORWARDS().rotate(this.rotation, this.forwards);
OrientationController.Companion.getUP().rotate(this.rotation, this.up);
OrientationController.Companion.getLEFT().rotate(this.rotation, this.left);
if(cobblemon$rollAngleStart == 0){
this.cobblemon$returnTimer = 1;
vehicleController.reset();
MountedCameraRenderer.INSTANCE.resetDriverRotations((Camera)(Object)this, this.entity);
return;
}
this.cobblemon$returnTimer += (partialTickTime * (1.0f/20.0f));
ci.cancel();
} else {
this.cobblemon$returnTimer = 1;
vehicleController.reset();
MountedCameraRenderer.INSTANCE.resetDriverRotations((Camera)(Object)this, this.entity);
}
}
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(FFF)V", ordinal = 0))
public void stopMoveIfRolling(Camera instance, float zoom, float dy, float dx, Operation<Void> original) {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof PokemonEntity) || Cobblemon.config.getThirdPersonViewBobbing()) {
original.call(instance, zoom, dy, dx);
}
}
}
@@ -69,12 +69,17 @@ public class HumanoidModelMixin {
behaviour.shouldRotateRiderHead(settings, state, pokemonEntity)
);
if (entity instanceof RidePassenger playerRotater) {
//this.head.yRot = playerRotater.cobblemon$getRideYRot();
this.head.xRot = playerRotater.cobblemon$getRideXRot();
headPitch = playerRotater.cobblemon$getRideXRot();
}
// If the player is on a rollable ride then use the ride local rotations to rotate the head
// This is to allow the player head to face the correct direction when "freelooking"
// TODO: find a way for this to work on built jars without borking head rotations.
// if (entity instanceof RidePassenger playerRotater &&
// vehicle instanceof OrientationControllable controller &&
// controller.getOrientationController().isActive()) {
// this.head.xRot = playerRotater.cobblemon$getRideXRot();
// headPitch = playerRotater.cobblemon$getRideXRot();
// this.head.yRot = playerRotater.cobblemon$getRideYRot();
// netHeadYaw = playerRotater.cobblemon$getRideYRot();
// }
if (!shouldRotatePlayerHead) {
netHeadYaw = 0f;
@@ -36,9 +36,9 @@ public class ItemInHandRendererMixin {
}
}
@Redirect(method = "renderHandsWithItems", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;mulPose(Lorg/joml/Quaternionf;)V", ordinal = 1))
@Redirect(method = "renderHandsWithItems", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;mulPose(Lorg/joml/Quaternionf;)V"))
private void cobblemon$renderHandswithItems(PoseStack instance, Quaternionf quaternion) {
if (!(Minecraft.getInstance().player instanceof OrientationControllable controllable && controllable.getOrientationController().isActive())) {
if (!(Minecraft.getInstance().player != null && Minecraft.getInstance().player.getVehicle() instanceof OrientationControllable controllable && controllable.getOrientationController().isActive())) {
instance.mulPose(quaternion);
}
}
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
import com.cobblemon.mod.common.client.keybind.keybinds.RidingFreelookBinding;
import com.cobblemon.mod.common.duck.RidePassenger;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
@@ -34,6 +35,7 @@ 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.CallbackInfo;
import com.cobblemon.mod.common.client.gui.party.PartyTutorialToasts;
import static com.google.common.primitives.Floats.min;
import static net.minecraft.util.Mth.lerp;
@@ -84,11 +86,13 @@ public abstract class MouseHandlerMixin {
CobblemonClient.INSTANCE.getStorage().shiftSelected(false);
ci.cancel();
PartySendBinding.INSTANCE.actioned();
PartyTutorialToasts.INSTANCE.onHoldKeyScrollSwitchedSlot();
} else if (i < 0) {
accumulatedScrollY -= i;
CobblemonClient.INSTANCE.getStorage().shiftSelected(true);
ci.cancel();
PartySendBinding.INSTANCE.actioned();
PartyTutorialToasts.INSTANCE.onHoldKeyScrollSwitchedSlot();
}
}
}
@@ -122,8 +126,9 @@ public abstract class MouseHandlerMixin {
double cursorDeltaY,
@Local(argsOnly = true) double d,
@Local(argsOnly = true) double movementTime
) {
) {
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
boolean returnValue = true;
if (usageContext.getScanningGuiOpen()) {
this.smoothTurnY.reset();
this.smoothTurnX.reset();
@@ -133,10 +138,11 @@ public abstract class MouseHandlerMixin {
var sensitivity = lerp(usageContext.getFovMultiplier(), spyglassSensitivity, lookSensitivity);
var yRotationFlip = this.minecraft.options.invertYMouse().get() ? -1 : 1;
player.turn(this.accumulatedDX * sensitivity, (this.accumulatedDY * sensitivity * yRotationFlip));
returnValue = false;
}
var vehicle = player.getVehicle();
if (!(vehicle instanceof PokemonEntity)) return true;
if (!(vehicle instanceof PokemonEntity)) return returnValue;
// Clamp player rotation if riding and the vehicle demands it
if (player.isPassenger() && vehicle instanceof PokemonEntity pokeVehicle) {
@@ -150,11 +156,11 @@ public abstract class MouseHandlerMixin {
pitchSmoother.reset();
rollSmoother.reset();
yawSmoother.reset();
return true;
return returnValue;
}
var vehicleController = controllableVehicle.getOrientationController();
var lookaroundButtonPressed = Minecraft.getInstance().mouseHandler.isMiddlePressed();
var freeLooking = RidingFreelookBinding.INSTANCE.isDown();
Pair<Boolean, Boolean> mouseShouldModifyDriver = ((PokemonEntity) vehicle).ifRidingAvailableSupply(new Pair(false, false), (behaviour, settings, state) -> {
return behaviour.mouseModifiesDriverRotation(
settings,
@@ -168,7 +174,7 @@ public abstract class MouseHandlerMixin {
// affect the vehicle orientation when looking around.
// If the client is a passenger it will modify these rotations and return
//-------------------------------------------------------------------------
if (lookaroundButtonPressed || player.getControlledVehicle() == null) {
if (freeLooking || player.getControlledVehicle() == null) {
// Modify driver rotations
cobblemon$setDriverRotations(player, cursorDeltaX, cursorDeltaY);
@@ -190,10 +196,10 @@ public abstract class MouseHandlerMixin {
// Smoothly return driver rotations to zero when needed
//-------------------------------------------------------------------------
var playerRotater = (RidePassenger)player;
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getFirst()){
if( !freeLooking && !mouseShouldModifyDriver.getFirst()){
playerRotater.cobblemon$setRideYRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideYRot()), 0.0f));
}
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getSecond()) {
if( !freeLooking && !mouseShouldModifyDriver.getSecond()) {
playerRotater.cobblemon$setRideXRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideXRot()), 0.0f));
}
@@ -221,7 +227,7 @@ public abstract class MouseHandlerMixin {
vehicleController.rotate((float) (angRot.x * 10 * d), (float) (angRot.y * 10 * d), (float) (angRot.z * 10 * d));
}
return false;
return returnValue;
}
@Inject(method = "handleAccumulatedMovement", at = @At("HEAD"))
@@ -307,7 +313,8 @@ public abstract class MouseHandlerMixin {
var playerRotater = (RidePassenger)player;
playerRotater.cobblemon$setRideXRot(playerRotater.cobblemon$getRideXRot() + f);
playerRotater.cobblemon$setRideYRot(playerRotater.cobblemon$getRideYRot() + g);
playerRotater.cobblemon$setRideXRot(Mth.clamp(playerRotater.cobblemon$getRideXRot(), -90.0F, 90.0F));
playerRotater.cobblemon$setRideXRot(Mth.clamp(playerRotater.cobblemon$getRideXRot(), -89.0F, 89.0F));
playerRotater.cobblemon$setRideYRot(Mth.clamp(playerRotater.cobblemon$getRideYRot(), -105.0F, 105.0F));
if (player.getVehicle() != null) {
player.getVehicle().onPassengerTurned(player);
}
@@ -11,10 +11,17 @@ package com.cobblemon.mod.common.mixin.entity;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.duck.RidePassenger;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.Pokemon;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;
import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
@@ -22,6 +29,7 @@ import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.CallbackInfo;
@@ -47,16 +55,8 @@ public abstract class EntityMixin {
)
)
public boolean cobblemon$forceOnGroundForStepUp(Entity entity, Operation<Boolean> original) {
if (entity instanceof PokemonEntity && entity.hasControllingPassenger()) {
BlockPos below = entity.blockPosition().below();
Level level = entity.level();
var blockStateBelow = level.getBlockState(below);
boolean isAirOrLiquid = blockStateBelow.isAir() || !blockStateBelow.getFluidState().isEmpty();
boolean canSupportEntity = blockStateBelow.isFaceSturdy(level, below, Direction.UP);
boolean standingOnSolid = canSupportEntity && !isAirOrLiquid;
if (standingOnSolid) {
return true;
}
if (entity instanceof PokemonEntity vehicle && entity.hasControllingPassenger()) {
return true;
}
return original.call(entity);
}
@@ -67,18 +67,7 @@ public abstract class EntityMixin {
cancellable = true
)
private void cobblemon$modifyEyePosition_partial(float partialTicks, CallbackInfoReturnable<Vec3> cir) {
var entity = (Entity)(Object)this;
if (!(entity instanceof Player player)) return;
if (!(player instanceof RidePassenger ridePassenger)) return;
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
var vehicleController = vehicle.getOrientationController();
if (vehicleController == null) return;
// TODO: Determine if it needs partialtick involved.
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
cir.setReturnValue(customEyePos);
cobblemon$getCustomEyePos(cir);
}
@Inject(
@@ -87,16 +76,79 @@ public abstract class EntityMixin {
cancellable = true
)
private void cobblemon$modifyEyePosition_noPartial(CallbackInfoReturnable<Vec3> cir) {
cobblemon$getCustomEyePos(cir);
}
@Unique
private void cobblemon$getCustomEyePos(CallbackInfoReturnable<Vec3> cir) {
var entity = (Entity)(Object)this;
if (entity.level().isClientSide) return;
if (!(entity instanceof Player player)) return;
if (!(player instanceof RidePassenger ridePassenger)) return;
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
if (!(vehicle instanceof PokemonEntity)) return;
var vehicleController = vehicle.getOrientationController();
if (vehicleController == null) return;
// TODO: Determine if it needs partialtick involved.
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
cir.setReturnValue(customEyePos);
}
@WrapOperation(
method = "push(Lnet/minecraft/world/entity/Entity;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(DDD)V", ordinal = 0)
)
public void cobblemon$customPusherLogic(Entity pusher, double x, double y, double z,
Operation<Void> original,
@Local(argsOnly = true) Entity pushee,
@Local(name = "e") double e, @Local(name = "d") double d,
@Share("pusherIsPlayerOrPokemon") LocalBooleanRef pusherIsPlayerOrPokemon,
@Share("pusheeIsPlayerOrPokemon") LocalBooleanRef pusheeIsPlayerOrPokemon,
@Share("pusheeReceivedForce")LocalFloatRef pusheeReceivedForce) {
pusherIsPlayerOrPokemon.set(pusher instanceof PokemonEntity || pusher instanceof Player);
pusheeIsPlayerOrPokemon.set(pushee instanceof PokemonEntity || pushee instanceof Player);
if (!pusheeIsPlayerOrPokemon.get() || !pusherIsPlayerOrPokemon.get()) {
original.call(pusher, x, y, z);
return;
}
/**********************************************
* Custom portion of the code:
* Handle collisions with weight in mind. Use
* the weight value of pokemon to determine
* which side gets what portion of the total
* force.
*********************************************/
// Weights in hectograms
// Check to see if the pusher or pushee is a player. 200ish pounds. Steve's like a 6'6 miner
var pusherWeight = pusher instanceof PokemonEntity pusherPokemon ? pusherPokemon.getPokemon().getSpecies().getWeight() : 900F;
var pusheeWeight = pushee instanceof PokemonEntity pusheePokemon ? pusheePokemon.getPokemon().getSpecies().getWeight() : 900F;
// Calculate the portion of force received for both entities. Bigger receives less from the
// collision than the smaller one.
var totalWeight = pusherWeight + pusheeWeight;
var pusherReceivedForce = pusheeWeight / totalWeight * 2F;
pusheeReceivedForce.set((pusherWeight / totalWeight) * 2F);
original.call(pusher, -d * pusherReceivedForce, 0.0, -e * pusherReceivedForce);
}
@WrapOperation(
method = "push(Lnet/minecraft/world/entity/Entity;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(DDD)V", ordinal = 1)
)
public void cobblemon$customPusheeLogic(Entity pusher, double x, double y, double z, Operation<Void> original,
@Local(name = "e") double e, @Local(name = "d") double d,
@Share("pusherIsPlayerOrPokemon") LocalBooleanRef pusherIsPlayerOrPokemon,
@Share("pusheeIsPlayerOrPokemon") LocalBooleanRef pusheeIsPlayerOrPokemon,
@Share("pusheeReceivedForce")LocalFloatRef pusheeReceivedForce) {
if (!pusheeIsPlayerOrPokemon.get() || !pusherIsPlayerOrPokemon.get()) {
original.call(pusher, x, y, z);
return;
}
original.call(pusher, d * pusheeReceivedForce.get(), 0.0, e * pusheeReceivedForce.get());
}
}
@@ -19,7 +19,9 @@ import com.cobblemon.mod.common.api.drop.ItemDropEntry
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
import com.cobblemon.mod.common.api.interaction.RequestManager
import com.cobblemon.mod.common.api.molang.MoLangLoadedFilesCache
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.npc.premades.PremadeNPCs
import com.cobblemon.mod.common.api.permission.PermissionValidator
import com.cobblemon.mod.common.api.pokeball.catching.calculators.CaptureCalculator
import com.cobblemon.mod.common.api.pokeball.catching.calculators.CaptureCalculators
@@ -41,9 +43,10 @@ import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
import com.cobblemon.mod.common.api.spawning.BestSpawner
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningZoneGenerator
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePositionResolver
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePositionResolver
import com.cobblemon.mod.common.api.starter.StarterHandler
import com.cobblemon.mod.common.api.stats.CobblemonStats
import com.cobblemon.mod.common.api.storage.PokemonStoreManager
import com.cobblemon.mod.common.api.storage.adapter.conversions.ReforgedConversion
import com.cobblemon.mod.common.api.storage.adapter.database.MongoDBStoreAdapter
@@ -63,10 +66,14 @@ import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataMongoBacken
import com.cobblemon.mod.common.api.storage.player.factory.CachedPlayerDataStoreFactory
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.*
import com.cobblemon.mod.common.battles.BagItems
import com.cobblemon.mod.common.battles.BattleFormat
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.BattleSide
import com.cobblemon.mod.common.battles.ShowdownThread
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.block.DispenserBehaviorRegistry
import com.cobblemon.mod.common.block.dispenser.DispenserBehaviorRegistry
import com.cobblemon.mod.common.client.CobblemonPack
import com.cobblemon.mod.common.command.argument.*
import com.cobblemon.mod.common.config.CobblemonConfig
@@ -75,10 +82,11 @@ import com.cobblemon.mod.common.config.constraint.IntConstraint
import com.cobblemon.mod.common.config.starter.StarterConfig
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.events.AdvancementHandler
import com.cobblemon.mod.common.events.EntityCallbackHandler
import com.cobblemon.mod.common.events.CallbackHandler
import com.cobblemon.mod.common.events.EntityCallbackHandler
import com.cobblemon.mod.common.events.PokedexHandler
import com.cobblemon.mod.common.events.ServerTickHandler
import com.cobblemon.mod.common.events.StatHandler
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
import com.cobblemon.mod.common.permission.LaxPermissionValidator
import com.cobblemon.mod.common.platform.events.PlatformEvents
@@ -88,13 +96,27 @@ import com.cobblemon.mod.common.pokemon.aspects.COSMETIC_SLOT_ASPECT
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeature
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeatureProvider
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.properties.*
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
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.HiddenAbilityPropertyType
import com.cobblemon.mod.common.pokemon.properties.LabelProperty
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.ifDedicatedServer
import com.cobblemon.mod.common.util.isLaterVersion
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.requestWallpapers
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
import com.cobblemon.mod.common.world.feature.ore.CobblemonOrePlacedFeatures
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
@@ -102,6 +124,17 @@ import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.client.MongoClient
import com.mongodb.client.MongoClients
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
import net.minecraft.client.Minecraft
import net.minecraft.commands.synchronization.SingletonArgumentInfo
import net.minecraft.resources.ResourceKey
@@ -114,17 +147,6 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.storage.LevelResource
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
object Cobblemon {
const val MODID = CobblemonBuildDetails.MOD_ID
@@ -161,9 +183,13 @@ object Cobblemon {
var wallpapers = mutableMapOf<UUID, Set<ResourceLocation>>()
val serverPlayerStructs = mutableMapOf<UUID, ObjectValue<Player>>()
/** Player UUID to entity UUID that they're brain debuggin' */
val serverPlayerDebuggingPokemonBrainEntities = mutableMapOf<UUID, UUID>()
val statistics: CobblemonStats = CobblemonStats
@JvmStatic
val builtinPacks = listOf<CobblemonPack>(
val builtinPacks = listOf(
CobblemonPack(id = "adorncompatibility", name = "Adorn Compatibility", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.ALWAYS_ENABLED, neededMods = setOf("adorn")),
CobblemonPack(id = "gyaradosjump", name = "Gyarados Jump Patterns", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.DEFAULT_ENABLED),
CobblemonPack(id = "regionbiasforms", name = "Region Bias Forms", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.DEFAULT_ENABLED),
@@ -199,6 +225,7 @@ object Cobblemon {
implementation.registerEntityDataSerializers()
implementation.registerCriteria()
implementation.registerEntitySubPredicates()
implementation.registerMobEffects()
DispenserBehaviorRegistry.registerDispenserBehaviors()
DropEntry.register("command", CommandDropEntry::class.java)
@@ -232,6 +259,7 @@ object Cobblemon {
playerDataManager.onPlayerDisconnect(it.player)
RequestManager.onLogoff(it.player)
serverPlayerStructs.remove(it.player.uuid)
serverPlayerDebuggingPokemonBrainEntities.remove(it.player.uuid)
}
PlatformEvents.PLAYER_DEATH.subscribe {
PCLinkManager.removeLink(it.player.uuid)
@@ -302,11 +330,17 @@ object Cobblemon {
SpeciesFeatures.register(
DataKeys.HAS_BEEN_SHEARED,
FlagSpeciesFeatureProvider(keys = listOf(DataKeys.HAS_BEEN_SHEARED), default = false))
FlagSpeciesFeatureProvider(keys = listOf(DataKeys.HAS_BEEN_SHEARED), default = false)
)
SpeciesFeatures.register(
SlowpokeTailRegrowthSpeciesFeature.NAME,
SlowpokeTailRegrowthSpeciesFeatureProvider
)
CustomPokemonProperty.register(UncatchableProperty)
CustomPokemonProperty.register(BattleCloneProperty)
CustomPokemonProperty.register(PokemonFlagProperty)
CustomPokemonProperty.register(LabelProperty)
CustomPokemonProperty.register(HiddenAbilityPropertyType)
CustomPokemonProperty.register(AspectPropertyType)
CustomPokemonProperty.register(UnaspectPropertyType)
@@ -331,6 +365,8 @@ object Cobblemon {
}
PlatformEvents.SERVER_STARTING.subscribe { event ->
val server = event.server
PremadeNPCs.onServerLoading(server)
MoLangLoadedFilesCache.initialize(server)
playerDataManager = PlayerInstancedDataStoreManager().also { it.setup(server) }
val mongoClient: MongoClient?
@@ -433,6 +469,7 @@ object Cobblemon {
fun registerEventHandlers() {
AdvancementHandler.registerListeners()
PokedexHandler.registerListeners()
StatHandler.registerListeners()
}
fun getLevel(dimension: ResourceKey<Level>): Level? {
@@ -440,7 +477,7 @@ object Cobblemon {
server()?.getLevel(dimension)
} else {
val mc = Minecraft.getInstance()
return mc.singleplayerServer?.getLevel(dimension) ?: mc.level
mc.singleplayerServer?.getLevel(dimension) ?: mc.level
}
}
@@ -11,16 +11,26 @@ package com.cobblemon.mod.common
import net.minecraft.world.entity.schedule.Activity
object CobblemonActivities {
@JvmField
val activities = mutableListOf<Activity>()
@JvmField
val BATTLING = register(Activity("battling"))
@JvmField
val ACTION_EFFECT = register(Activity("action_effect"))
@JvmField
val NPC_CHATTING = register(Activity("npc_chatting"))
@JvmField
val POKEMON_SLEEPING_ACTIVITY = register(Activity("pokemon_sleeping"))
@JvmField
val POKEMON_GROW_CROP = register(Activity("pokemon_grow_crop"))
@JvmField
val POKEMON_SLEEP_ON_TRAINER_BED = register(Activity("pokemon_sleep_on_trainer_bed"))
@JvmField
val POKEMON_HERD = register(Activity("pokemon_herd"))
@JvmField
val POKEMON_POLLINATION = register(Activity("pokemon_pollination"))
@JvmStatic
fun register(activity: Activity): Activity {
activities.add(activity)
return activity
@@ -9,9 +9,12 @@
package com.cobblemon.mod.common
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonBehaviours.autoPokemonBehaviours
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.ai.CobblemonBehaviour
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.config.sense.SenseConfig
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.data.JsonDataRegistry.Companion.JSON_EXTENSION
@@ -19,16 +22,7 @@ import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.BehaviourSyncPacket
import com.cobblemon.mod.common.util.adapters.ActivityAdapter
import com.cobblemon.mod.common.util.adapters.BehaviourConfigAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionOrEntityVariableAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.MemoryModuleTypeAdapter
import com.cobblemon.mod.common.util.adapters.SensorTypeAdapter
import com.cobblemon.mod.common.util.adapters.TaskConfigAdapter
import com.cobblemon.mod.common.util.adapters.TranslatedTextAdapter
import com.cobblemon.mod.common.util.adapters.*
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.endsWith
import com.google.gson.Gson
@@ -55,6 +49,8 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
.registerTypeAdapter(SensorType::class.java, SensorTypeAdapter)
.registerTypeAdapter(BehaviourConfig::class.java, BehaviourConfigAdapter)
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
.registerTypeAdapter(ObjectiveConfig::class.java, ObjectiveConfigAdapter)
.registerTypeAdapter(SenseConfig::class.java, SenseConfigAdapter)
.registerTypeAdapter(
TypeToken.getParameterized(Either::class.java, Expression::class.java, MoLangConfigVariable::class.java).type,
ExpressionOrEntityVariableAdapter
@@ -102,6 +98,7 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
autoNPCBehaviours.add(behaviour)
}
data[resolvedIdentifier] = behaviour
behaviour.id = resolvedIdentifier
}
}
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.block.*
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
import com.cobblemon.mod.common.block.LecternBlock
@@ -41,11 +42,11 @@ import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockSetType
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument
import net.minecraft.world.level.block.state.properties.WoodType
import net.minecraft.world.level.material.MapColor
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.phys.shapes.Shapes
@Suppress("SameParameterValue", "HasPlatformType", "MemberVisibilityCanBePrivate", "unused")
object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<Block>>, Block>() {
@@ -60,13 +61,13 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
// Evolution Ores
@JvmField
val DAWN_STONE_ORE = evolutionStoneOre("dawn_stone_ore")
val DAWN_STONE_ORE = evolutionStoneOre("dawn_stone_ore", 7)
@JvmField
val DUSK_STONE_ORE = evolutionStoneOre("dusk_stone_ore")
@JvmField
val FIRE_STONE_ORE = evolutionStoneOre("fire_stone_ore")
val FIRE_STONE_ORE = evolutionStoneOre("fire_stone_ore", 10)
@JvmField
val NETHER_FIRE_STONE_ORE = evolutionStoneOre("nether_fire_stone_ore")
val NETHER_FIRE_STONE_ORE = this.create("nether_fire_stone_ore", DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.of().mapColor(MapColor.NETHER).instrument(NoteBlockInstrument.BASEDRUM).requiresCorrectToolForDrops().strength(3.0F, 3.0F).sound(SoundType.NETHER_ORE).lightLevel{10}))
@JvmField
val ICE_STONE_ORE = evolutionStoneOre("ice_stone_ore")
@JvmField
@@ -74,24 +75,24 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val MOON_STONE_ORE = evolutionStoneOre("moon_stone_ore")
@JvmField
val DRIPSTONE_MOON_STONE_ORE = evolutionStoneOre("dripstone_moon_stone_ore")
val DRIPSTONE_MOON_STONE_ORE = this.create("dripstone_moon_stone_ore", DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.of().mapColor(MapColor.TERRACOTTA_BROWN).instrument(NoteBlockInstrument.BASEDRUM).requiresCorrectToolForDrops().strength(3.0F, 3.0F).sound(SoundType.DRIPSTONE_BLOCK)))
@JvmField
val SHINY_STONE_ORE = evolutionStoneOre("shiny_stone_ore")
val SHINY_STONE_ORE = evolutionStoneOre("shiny_stone_ore", 12)
@JvmField
val SUN_STONE_ORE = evolutionStoneOre("sun_stone_ore")
val SUN_STONE_ORE = evolutionStoneOre("sun_stone_ore", 2)
@JvmField
val TERRACOTTA_SUN_STONE_ORE = evolutionStoneOre("terracotta_sun_stone_ore")
val TERRACOTTA_SUN_STONE_ORE = this.create("terracotta_sun_stone_ore", DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).instrument(NoteBlockInstrument.BASEDRUM).requiresCorrectToolForDrops().strength(3.0F, 3.0F).lightLevel{2}))
@JvmField
val THUNDER_STONE_ORE = evolutionStoneOre("thunder_stone_ore")
val THUNDER_STONE_ORE = evolutionStoneOre("thunder_stone_ore", 6)
@JvmField
val WATER_STONE_ORE = evolutionStoneOre("water_stone_ore")
@JvmField
val DEEPSLATE_DAWN_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_dawn_stone_ore")
val DEEPSLATE_DAWN_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_dawn_stone_ore", 7)
@JvmField
val DEEPSLATE_DUSK_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_dusk_stone_ore")
@JvmField
val DEEPSLATE_FIRE_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_fire_stone_ore")
val DEEPSLATE_FIRE_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_fire_stone_ore", 10)
@JvmField
val DEEPSLATE_ICE_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_ice_stone_ore")
@JvmField
@@ -99,11 +100,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val DEEPSLATE_MOON_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_moon_stone_ore")
@JvmField
val DEEPSLATE_SHINY_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_shiny_stone_ore")
val DEEPSLATE_SHINY_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_shiny_stone_ore", 12)
@JvmField
val DEEPSLATE_SUN_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_sun_stone_ore")
val DEEPSLATE_SUN_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_sun_stone_ore", 2)
@JvmField
val DEEPSLATE_THUNDER_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_thunder_stone_ore")
val DEEPSLATE_THUNDER_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_thunder_stone_ore", 6)
@JvmField
val DEEPSLATE_WATER_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_water_stone_ore")
@@ -215,7 +216,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
@@ -243,9 +244,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.PLANT).ignitedByLava().noCollission().instabreak().sound(CobblemonSounds.REVIVAL_HERB_SOUNDS)))
@JvmField
val POKE_CAKE = this.create("poke_cake", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(LIT)) 3 else 0 }, false))
val POKE_CAKE = this.create("poke_cake", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(BlockStateProperties.LIT)) 3 else 0 }, false))
@JvmField
val POKE_SNACK = this.create("poke_snack", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(LIT)) 3 else 0 }, true))
val POKE_SNACK = this.create("poke_snack", PokeSnackBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY).lightLevel { if (it.getValue(BlockStateProperties.LIT)) 3 else 0 }, true))
@JvmField
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
@@ -454,7 +455,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SOUL_CAMPFIRE = create("soul_campfire", CampfireBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.PODZOL).strength(2.0F).lightLevel{9}, true))
@JvmField
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
@JvmField
@@ -477,6 +478,99 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val GIMMIGHOUL_CHEST = create("gimmighoul_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.FAKE))
@JvmField
val WHITE_PLAQUE = create("white_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val LIGHT_GRAY_PLAQUE = create("light_gray_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val GRAY_PLAQUE = create("gray_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val BLACK_PLAQUE = create("black_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val BROWN_PLAQUE = create("brown_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val RED_PLAQUE = create("red_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val ORANGE_PLAQUE = create("orange_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val YELLOW_PLAQUE = create("yellow_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val LIME_PLAQUE = create("lime_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val GREEN_PLAQUE = create("green_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val CYAN_PLAQUE = create("cyan_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val LIGHT_BLUE_PLAQUE = create("light_blue_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val BLUE_PLAQUE = create("blue_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val PURPLE_PLAQUE = create("purple_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val MAGENTA_PLAQUE = create("magenta_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val PINK_PLAQUE = create("pink_plaque", PlaqueBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.METAL).noOcclusion().pushReaction(PushReaction.DESTROY).strength(5.0F)))
@JvmField
val CLEANSE_TAG = create("cleanse_tag", WallAttachedStackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).mapColor(MapColor.NONE).pushReaction(PushReaction.DESTROY).noOcclusion().noCollission(), WallAttachedStackableItemBlock.WallStackableItemBlockType.TAG))
@JvmField
val SPELL_TAG = create("spell_tag", WallAttachedStackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).mapColor(MapColor.NONE).pushReaction(PushReaction.DESTROY).noOcclusion().noCollission(), WallAttachedStackableItemBlock.WallStackableItemBlockType.TAG))
@JvmField
val BLUNDER_POLICY = create("blunder_policy", WallAttachedDirectionalShapeBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion().noCollission(), 14, 12, 1))
@JvmField
val WEAKNESS_POLICY = create("weakness_policy", WallAttachedDirectionalShapeBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion().noCollission(), 14, 12, 1))
@JvmField
val FULL_HEAL = create("full_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val ANTIDOTE = create("antidote", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val AWAKENING = create("awakening", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val BURN_HEAL = create("burn_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val ICE_HEAL = create("ice_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val PARALYZE_HEAL = create("paralyze_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val ETHER = create("ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val MAX_ETHER = create("max_ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val ELIXIR = create("elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val MAX_ELIXIR = create("max_elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val POTION = create("potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
@JvmField
val SUPER_POTION = create("super_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
@JvmField
val HYPER_POTION = create("hyper_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
@JvmField
val MAX_POTION = create("max_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
@JvmField
val FULL_RESTORE = create("full_restore", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
@JvmField
val DIRE_HIT = create("dire_hit", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val GUARD_SPEC = create("guard_spec", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val X_SPEED = create("x_${Stats.SPEED.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val MONITOR = create("monitor", MonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 13 else 0 }))
@JvmField
@@ -577,75 +671,145 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
private val berries = mutableMapOf<ResourceLocation, BerryBlock>()
@JvmField
val AGUAV_BERRY = this.berryBlock("aguav")
@JvmField
val APICOT_BERRY = this.berryBlock("apicot")
@JvmField
val ASPEAR_BERRY = this.berryBlock("aspear")
@JvmField
val BABIRI_BERRY = this.berryBlock("babiri")
@JvmField
val BELUE_BERRY = this.berryBlock("belue")
@JvmField
val BLUK_BERRY = this.berryBlock("bluk")
@JvmField
val CHARTI_BERRY = this.berryBlock("charti")
@JvmField
val CHERI_BERRY = this.berryBlock("cheri")
@JvmField
val CHESTO_BERRY = this.berryBlock("chesto")
@JvmField
val CHILAN_BERRY = this.berryBlock("chilan")
@JvmField
val CHOPLE_BERRY = this.berryBlock("chople")
@JvmField
val COBA_BERRY = this.berryBlock("coba")
@JvmField
val COLBUR_BERRY = this.berryBlock("colbur")
@JvmField
val CORNN_BERRY = this.berryBlock("cornn")
@JvmField
val CUSTAP_BERRY = this.berryBlock("custap")
@JvmField
val DURIN_BERRY = this.berryBlock("durin")
@JvmField
val EGGANT_BERRY = this.berryBlock("eggant")
@JvmField
val ENIGMA_BERRY = this.berryBlock("enigma")
@JvmField
val FIGY_BERRY = this.berryBlock("figy")
@JvmField
val GANLON_BERRY = this.berryBlock("ganlon")
@JvmField
val GREPA_BERRY = this.berryBlock("grepa")
@JvmField
val HABAN_BERRY = this.berryBlock("haban")
@JvmField
val HONDEW_BERRY = this.berryBlock("hondew")
@JvmField
val HOPO_BERRY = this.berryBlock("hopo")
@JvmField
val IAPAPA_BERRY = this.berryBlock("iapapa")
@JvmField
val JABOCA_BERRY = this.berryBlock("jaboca")
@JvmField
val KASIB_BERRY = this.berryBlock("kasib")
@JvmField
val KEBIA_BERRY = this.berryBlock("kebia")
@JvmField
val KEE_BERRY = this.berryBlock("kee")
@JvmField
val KELPSY_BERRY = this.berryBlock("kelpsy")
@JvmField
val LANSAT_BERRY = this.berryBlock("lansat")
@JvmField
val LEPPA_BERRY = this.berryBlock("leppa")
@JvmField
val LIECHI_BERRY = this.berryBlock("liechi")
@JvmField
val LUM_BERRY = this.berryBlock("lum")
@JvmField
val MAGO_BERRY = this.berryBlock("mago")
@JvmField
val MAGOST_BERRY = this.berryBlock("magost")
@JvmField
val MARANGA_BERRY = this.berryBlock("maranga")
@JvmField
val MICLE_BERRY = this.berryBlock("micle")
@JvmField
val NANAB_BERRY = this.berryBlock("nanab")
@JvmField
val NOMEL_BERRY = this.berryBlock("nomel")
@JvmField
val OCCA_BERRY = this.berryBlock("occa")
@JvmField
val ORAN_BERRY = this.berryBlock("oran")
@JvmField
val PAMTRE_BERRY = this.berryBlock("pamtre")
@JvmField
val PASSHO_BERRY = this.berryBlock("passho")
@JvmField
val PAYAPA_BERRY = this.berryBlock("payapa")
@JvmField
val PECHA_BERRY = this.berryBlock("pecha")
@JvmField
val PERSIM_BERRY = this.berryBlock("persim")
@JvmField
val PETAYA_BERRY = this.berryBlock("petaya")
@JvmField
val PINAP_BERRY = this.berryBlock("pinap")
@JvmField
val POMEG_BERRY = this.berryBlock("pomeg")
@JvmField
val QUALOT_BERRY = this.berryBlock("qualot")
@JvmField
val RABUTA_BERRY = this.berryBlock("rabuta")
@JvmField
val RAWST_BERRY = this.berryBlock("rawst")
@JvmField
val RAZZ_BERRY = this.berryBlock("razz")
@JvmField
val RINDO_BERRY = this.berryBlock("rindo")
@JvmField
val ROSELI_BERRY = this.berryBlock("roseli")
@JvmField
val ROWAP_BERRY = this.berryBlock("rowap")
@JvmField
val SALAC_BERRY = this.berryBlock("salac")
@JvmField
val SHUCA_BERRY = this.berryBlock("shuca")
@JvmField
val SITRUS_BERRY = this.berryBlock("sitrus")
@JvmField
val SPELON_BERRY = this.berryBlock("spelon")
@JvmField
val STARF_BERRY = this.berryBlock("starf")
@JvmField
val TAMATO_BERRY = this.berryBlock("tamato")
@JvmField
val TANGA_BERRY = this.berryBlock("tanga")
@JvmField
val TOUGA_BERRY = this.berryBlock("touga")
@JvmField
val WACAN_BERRY = this.berryBlock("wacan")
@JvmField
val WATMEL_BERRY = this.berryBlock("watmel")
@JvmField
val WEPEAR_BERRY = this.berryBlock("wepear")
@JvmField
val WIKI_BERRY = this.berryBlock("wiki")
@JvmField
val YACHE_BERRY = this.berryBlock("yache")
//val BINDING_SOIL = this.create("binding_soil", BindingSoilBlock(BlockBehaviour.Properties.of()))
@@ -713,8 +877,10 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
}
private fun evolutionStoneOre(name: String) = this.create(name, DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_ORE)))
private fun evolutionStoneOre(name: String, lightLevel: Int) = this.create(name, DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_ORE).lightLevel { lightLevel }))
private fun deepslateEvolutionStoneOre(name: String) = this.create(name, DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.ofFullCopy(Blocks.DEEPSLATE_IRON_ORE)))
private fun deepslateEvolutionStoneOre(name: String, lightLevel: Int) = this.create(name, DropExperienceBlock(UniformInt.of(1, 2), BlockBehaviour.Properties.ofFullCopy(Blocks.DEEPSLATE_IRON_ORE).lightLevel { lightLevel }))
/**
* Helper method for creating leaves
@@ -76,5 +76,6 @@ object CobblemonCommands {
// with a certain system environment variable set
CobblemonInfoCommand.register(dispatcher)
CalculateSeatPositionCommand.register(dispatcher)
DebugCobblemonAICommand.register(dispatcher)
}
}
@@ -43,6 +43,7 @@ object CobblemonCosmeticItems : JsonDataRegistry<CosmeticItemAssignment> {
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.create()
@JvmField
val cosmeticItems = mutableListOf<CosmeticItemAssignment>()
override fun reload(data: Map<ResourceLocation, CosmeticItemAssignment>) {
@@ -55,7 +56,9 @@ object CobblemonCosmeticItems : JsonDataRegistry<CosmeticItemAssignment> {
CosmeticItemAssignmentSyncPacket(cosmeticItems).sendToPlayer(player)
}
@JvmStatic
fun findValidForPokemon(pokemon: Pokemon) = cosmeticItems.filter { it.pokemon.any { it.matches(pokemon) } }
@JvmStatic
fun findValidCosmeticForPokemonAndItem(registryAccess: RegistryAccess, pokemon: Pokemon, itemStack: ItemStack) = cosmeticItems
.filter { it.pokemon.any { it.matches(pokemon) } }
.flatMap { it.cosmeticItems }
@@ -117,6 +117,11 @@ interface CobblemonImplementation {
fun registerEntitySubPredicates()
/**
* TODO
*/
fun registerMobEffects()
/**
* Add a feature to the current platform implementation.
@@ -21,61 +21,73 @@ import net.minecraft.resources.ResourceLocation
object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>, ResourceKey<Registry<DataComponentType<*>>>, DataComponentType<*>>() {
@JvmField
val POKEMON_ITEM: DataComponentType<PokemonItemComponent> = create("pokemon_item", DataComponentType.builder<PokemonItemComponent>()
.persistent(PokemonItemComponent.CODEC)
.networkSynchronized(PokemonItemComponent.PACKET_CODEC)
.build())
@JvmField
val HELD_ITEM_EFFECT: DataComponentType<HeldItemEffectComponent> = create("held_item_effect", DataComponentType.builder<HeldItemEffectComponent>()
.persistent(HeldItemEffectComponent.CODEC)
.networkSynchronized(HeldItemEffectComponent.PACKET_CODEC)
.build())
@JvmField
val BAIT: DataComponentType<RodBaitComponent> = create("bait", DataComponentType.builder<RodBaitComponent>()
.persistent(RodBaitComponent.CODEC)
.networkSynchronized(RodBaitComponent.PACKET_CODEC)
.build())
@JvmField
val POT_DATA: DataComponentType<PotComponent> = create("cooking_pot_item", DataComponentType.builder<PotComponent>()
.persistent(PotComponent.CODEC)
.networkSynchronized(PotComponent.PACKET_CODEC)
.build())
@JvmField
val BAIT_EFFECTS: DataComponentType<BaitEffectsComponent> = create("bait_effects", DataComponentType.builder<BaitEffectsComponent>()
.persistent(BaitEffectsComponent.CODEC)
.networkSynchronized(BaitEffectsComponent.PACKET_CODEC)
.build())
@JvmField
val FLAVOUR: DataComponentType<FlavourComponent> = create("flavour", DataComponentType.builder<FlavourComponent>()
.persistent(FlavourComponent.CODEC)
.networkSynchronized(FlavourComponent.PACKET_CODEC)
.build())
@JvmField
val RIDE_BOOST: DataComponentType<RideBoostsComponent> = create("ride_boosts", DataComponentType.builder<RideBoostsComponent>()
.persistent(RideBoostsComponent.CODEC)
.networkSynchronized(RideBoostsComponent.PACKET_CODEC)
.build())
@JvmField
val FOOD_COLOUR: DataComponentType<FoodColourComponent> = create("food_colour", DataComponentType.builder<FoodColourComponent>()
.persistent(FoodColourComponent.CODEC)
.networkSynchronized(FoodColourComponent.PACKET_CODEC)
.build())
@JvmField
val INGREDIENT: DataComponentType<IngredientComponent> = create("ingredient", DataComponentType.builder<IngredientComponent>()
.persistent(IngredientComponent.CODEC)
.networkSynchronized(IngredientComponent.PACKET_CODEC)
.build())
@JvmField
val FOOD: DataComponentType<FoodComponent> = create("food", DataComponentType.builder<FoodComponent>()
.persistent(FoodComponent.CODEC)
.networkSynchronized(FoodComponent.PACKET_CODEC)
.build())
@JvmField
val MOB_EFFECTS: DataComponentType<MobEffectsComponent> = create("mob_effects", DataComponentType.builder<MobEffectsComponent>()
.persistent(MobEffectsComponent.CODEC)
.networkSynchronized(MobEffectsComponent.PACKET_CODEC)
.build())
@JvmField
val CRAFTED: DataComponentType<Boolean> = create("crafted", DataComponentType.builder<Boolean>()
.persistent(Codec.BOOL)
.networkSynchronized(ByteBufCodecs.BOOL)
@@ -35,7 +35,6 @@ import com.cobblemon.mod.common.item.berry.HealingBerryItem
import com.cobblemon.mod.common.item.berry.PPRestoringBerryItem
import com.cobblemon.mod.common.item.berry.PortionHealingBerryItem
import com.cobblemon.mod.common.item.berry.StatusCuringBerryItem
import com.cobblemon.mod.common.item.berry.VolatileCuringBerryItem
import com.cobblemon.mod.common.item.interactive.PonigiriItem
import com.cobblemon.mod.common.item.food.SinisterTeaItem
import com.cobblemon.mod.common.item.interactive.*
@@ -382,8 +381,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SINISTER_TEA = create("sinister_tea", SinisterTeaItem())
@JvmField
val POKE_PUFF = pokepuffItem("poke_puff")
// @JvmField
// val POKE_PUFF = pokepuffItem("poke_puff")
// FOODS
@JvmField
@@ -393,23 +392,23 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val TASTY_TAIL = create("tasty_tail", foodItem(3, 0.3f))
@JvmField
val PEWTER_CRUNCHIES = regionalFoodItem("pewter_crunchies", 64, 7, 0.343f, false)
val PEWTER_CRUNCHIES = regionalFoodItem("pewter_crunchies", 64, 7, 0.3f, false)
@JvmField
val RAGE_CANDY_BAR = regionalFoodItem("rage_candy_bar", 64, 8, 0.2f, false)
@JvmField
val LAVA_COOKIE = regionalFoodItem("lava_cookie", 64, 2, 0.3f, false)
@JvmField
val OLD_GATEAU = regionalFoodItem("old_gateau", 64, 9, 0.1335f, false)
val OLD_GATEAU = regionalFoodItem("old_gateau", 64, 9, 0.1f, false)
@JvmField
val CASTELIACONE = regionalFoodItem("casteliacone", 64, 5, 0.28f, false)
val CASTELIACONE = regionalFoodItem("casteliacone", 64, 5, 0.3f, false)
@JvmField
val LUMIOSE_GALETTE = regionalFoodItem("lumiose_galette", 64, 4, 0.4f, false)
@JvmField
val BIG_MALASADA = regionalFoodItem("big_malasada", 64, 7, 0.343f, false)
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))
@JvmField
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 64, 8, 0.2f, false)
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 64, 7, 0.3f, false)
@JvmField
val OPEN_FACED_SANDWICH = regionalFoodItem("open_faced_sandwich", 64, 13, 0.5f, false)
@@ -431,7 +430,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val CANDIED_APPLE = create("candied_apple", CobblemonItem(Properties().stacksTo(64)
.food(FoodProperties.Builder()
.nutrition(6)
.saturationModifier(0.2335F)
.saturationModifier(0.2F)
.usingConvertsTo(Items.STICK)
.build())))
@JvmField
@@ -508,21 +507,62 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val SCROLL_OF_DARKNESS = noSettingsItem("scroll_of_darkness")
@JvmField val SCROLL_OF_WATERS = noSettingsItem("scroll_of_waters")
@JvmField val WHITE_PLAQUE = blockItem("white_plaque", CobblemonBlocks.WHITE_PLAQUE)
@JvmField val LIGHT_GRAY_PLAQUE = blockItem("light_gray_plaque", CobblemonBlocks.LIGHT_GRAY_PLAQUE)
@JvmField val GRAY_PLAQUE = blockItem("gray_plaque", CobblemonBlocks.GRAY_PLAQUE)
@JvmField val BLACK_PLAQUE = blockItem("black_plaque", CobblemonBlocks.BLACK_PLAQUE)
@JvmField val BROWN_PLAQUE = blockItem("brown_plaque", CobblemonBlocks.BROWN_PLAQUE)
@JvmField val RED_PLAQUE = blockItem("red_plaque", CobblemonBlocks.RED_PLAQUE)
@JvmField val ORANGE_PLAQUE = blockItem("orange_plaque", CobblemonBlocks.ORANGE_PLAQUE)
@JvmField val YELLOW_PLAQUE = blockItem("yellow_plaque", CobblemonBlocks.YELLOW_PLAQUE)
@JvmField val LIME_PLAQUE = blockItem("lime_plaque", CobblemonBlocks.LIME_PLAQUE)
@JvmField val GREEN_PLAQUE = blockItem("green_plaque", CobblemonBlocks.GREEN_PLAQUE)
@JvmField val CYAN_PLAQUE = blockItem("cyan_plaque", CobblemonBlocks.CYAN_PLAQUE)
@JvmField val LIGHT_BLUE_PLAQUE = blockItem("light_blue_plaque", CobblemonBlocks.LIGHT_BLUE_PLAQUE)
@JvmField val BLUE_PLAQUE = blockItem("blue_plaque", CobblemonBlocks.BLUE_PLAQUE)
@JvmField val PURPLE_PLAQUE = blockItem("purple_plaque", CobblemonBlocks.PURPLE_PLAQUE)
@JvmField val MAGENTA_PLAQUE = blockItem("magenta_plaque", CobblemonBlocks.MAGENTA_PLAQUE)
@JvmField val PINK_PLAQUE = blockItem("pink_plaque", CobblemonBlocks.PINK_PLAQUE)
private val berries = mutableMapOf<ResourceLocation, BerryItem>()
// Plants
@JvmField val ORAN_BERRY = berryItem("oran", HealingBerryItem(CobblemonBlocks.ORAN_BERRY) { CobblemonMechanics.berries.oranRestoreAmount })
@JvmField val CHERI_BERRY = berryItem("cheri", StatusCuringBerryItem(CobblemonBlocks.CHERI_BERRY, Statuses.PARALYSIS))
@JvmField val CHESTO_BERRY = berryItem("chesto", StatusCuringBerryItem(CobblemonBlocks.CHESTO_BERRY, Statuses.SLEEP))
@JvmField val PECHA_BERRY = berryItem("pecha", StatusCuringBerryItem(CobblemonBlocks.PECHA_BERRY, Statuses.POISON, Statuses.POISON_BADLY))
@JvmField val RAWST_BERRY = berryItem("rawst", StatusCuringBerryItem(CobblemonBlocks.RAWST_BERRY, Statuses.BURN))
@JvmField val ASPEAR_BERRY = berryItem("aspear", StatusCuringBerryItem(CobblemonBlocks.ASPEAR_BERRY, Statuses.FROZEN))
@JvmField val PERSIM_BERRY = berryItem("persim", VolatileCuringBerryItem(CobblemonBlocks.PERSIM_BERRY, "confusion"))
@JvmField val EGGANT_BERRY = berryItem("eggant", VolatileCuringBerryItem(CobblemonBlocks.EGGANT_BERRY, "attract"))
@JvmField val LEPPA_BERRY = berryItem("leppa", PPRestoringBerryItem(CobblemonBlocks.LEPPA_BERRY) { CobblemonMechanics.berries.ppRestoreAmount })
@JvmField val ORAN_BERRY = berryItem("oran", HealingBerryItem(CobblemonBlocks.ORAN_BERRY) { CobblemonMechanics.berries.oranRestoreAmount })
@JvmField val PERSIM_BERRY = berryItem("persim", StatusCuringBerryItem(CobblemonBlocks.PERSIM_BERRY, Statuses.CONFUSE))
@JvmField val LUM_BERRY = berryItem("lum", StatusCuringBerryItem(CobblemonBlocks.LUM_BERRY, *(Statuses.getPersistentStatuses().toTypedArray() + Statuses.CONFUSE)))
@JvmField val SITRUS_BERRY = berryItem("sitrus", HealingBerryItem(CobblemonBlocks.SITRUS_BERRY) { CobblemonMechanics.berries.sitrusHealAmount })
@JvmField val EGGANT_BERRY = berryItem("eggant", StatusCuringBerryItem(CobblemonBlocks.EGGANT_BERRY, Statuses.ATTRACT))
@JvmField val FIGY_BERRY = berryItem("figy", PortionHealingBerryItem(CobblemonBlocks.FIGY_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val WIKI_BERRY = berryItem("wiki", PortionHealingBerryItem(CobblemonBlocks.WIKI_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val MAGO_BERRY = berryItem("mago", PortionHealingBerryItem(CobblemonBlocks.MAGO_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val AGUAV_BERRY = berryItem("aguav", PortionHealingBerryItem(CobblemonBlocks.AGUAV_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val IAPAPA_BERRY = berryItem("iapapa", PortionHealingBerryItem(CobblemonBlocks.IAPAPA_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val RAZZ_BERRY = berryItem("razz", CobblemonBlocks.RAZZ_BERRY)
@JvmField val BLUK_BERRY = berryItem("bluk", CobblemonBlocks.BLUK_BERRY)
@JvmField val NANAB_BERRY = berryItem("nanab", CobblemonBlocks.NANAB_BERRY)
@JvmField val WEPEAR_BERRY = berryItem("wepear", CobblemonBlocks.WEPEAR_BERRY)
@JvmField val PINAP_BERRY = berryItem("pinap", CobblemonBlocks.PINAP_BERRY)
@JvmField val POMEG_BERRY = berryItem("pomeg", FriendshipRaisingBerryItem(CobblemonBlocks.POMEG_BERRY, Stats.HP))
@JvmField val KELPSY_BERRY = berryItem("kelpsy", FriendshipRaisingBerryItem(CobblemonBlocks.KELPSY_BERRY, Stats.ATTACK))
@JvmField val QUALOT_BERRY = berryItem("qualot", FriendshipRaisingBerryItem(CobblemonBlocks.QUALOT_BERRY, Stats.DEFENCE))
@JvmField val HONDEW_BERRY = berryItem("hondew", FriendshipRaisingBerryItem(CobblemonBlocks.HONDEW_BERRY, Stats.SPECIAL_ATTACK))
@JvmField val GREPA_BERRY = berryItem("grepa", FriendshipRaisingBerryItem(CobblemonBlocks.GREPA_BERRY, Stats.SPECIAL_DEFENCE))
@JvmField val TAMATO_BERRY = berryItem("tamato", FriendshipRaisingBerryItem(CobblemonBlocks.TAMATO_BERRY, Stats.SPEED))
@JvmField val TOUGA_BERRY = berryItem("touga", CobblemonBlocks.TOUGA_BERRY)
@JvmField val CORNN_BERRY = berryItem("cornn", CobblemonBlocks.CORNN_BERRY)
@JvmField val MAGOST_BERRY = berryItem("magost", CobblemonBlocks.MAGOST_BERRY)
@JvmField val RABUTA_BERRY = berryItem("rabuta", CobblemonBlocks.RABUTA_BERRY)
@JvmField val NOMEL_BERRY = berryItem("nomel", CobblemonBlocks.NOMEL_BERRY)
@JvmField val SPELON_BERRY = berryItem("spelon", CobblemonBlocks.SPELON_BERRY)
@JvmField val PAMTRE_BERRY = berryItem("pamtre", CobblemonBlocks.PAMTRE_BERRY)
@JvmField val WATMEL_BERRY = berryItem("watmel", CobblemonBlocks.WATMEL_BERRY)
@JvmField val DURIN_BERRY = berryItem("durin", CobblemonBlocks.DURIN_BERRY)
@JvmField val BELUE_BERRY = berryItem("belue", CobblemonBlocks.BELUE_BERRY)
@JvmField val OCCA_BERRY = berryItem("occa", CobblemonBlocks.OCCA_BERRY)
@JvmField val PASSHO_BERRY = berryItem("passho", CobblemonBlocks.PASSHO_BERRY)
@JvmField val WACAN_BERRY = berryItem("wacan", CobblemonBlocks.WACAN_BERRY)
@@ -540,35 +580,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val COLBUR_BERRY = berryItem("colbur", CobblemonBlocks.COLBUR_BERRY)
@JvmField val BABIRI_BERRY = berryItem("babiri", CobblemonBlocks.BABIRI_BERRY)
@JvmField val CHILAN_BERRY = berryItem("chilan", CobblemonBlocks.CHILAN_BERRY)
@JvmField val ROSELI_BERRY = berryItem("roseli", CobblemonBlocks.ROSELI_BERRY)
@JvmField val LEPPA_BERRY = berryItem("leppa", PPRestoringBerryItem(CobblemonBlocks.LEPPA_BERRY) { CobblemonMechanics.berries.ppRestoreAmount })
@JvmField val LUM_BERRY = berryItem("lum", StatusCuringBerryItem(CobblemonBlocks.LUM_BERRY))
@JvmField val FIGY_BERRY = berryItem("figy", PortionHealingBerryItem(CobblemonBlocks.FIGY_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val WIKI_BERRY = berryItem("wiki", PortionHealingBerryItem(CobblemonBlocks.WIKI_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val MAGO_BERRY = berryItem("mago", PortionHealingBerryItem(CobblemonBlocks.MAGO_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val AGUAV_BERRY = berryItem("aguav", PortionHealingBerryItem(CobblemonBlocks.AGUAV_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val IAPAPA_BERRY = berryItem("iapapa", PortionHealingBerryItem(CobblemonBlocks.IAPAPA_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
@JvmField val SITRUS_BERRY = berryItem("sitrus", HealingBerryItem(CobblemonBlocks.SITRUS_BERRY) { CobblemonMechanics.berries.sitrusHealAmount })
@JvmField val TOUGA_BERRY = berryItem("touga", CobblemonBlocks.TOUGA_BERRY)
@JvmField val CORNN_BERRY = berryItem("cornn", CobblemonBlocks.CORNN_BERRY)
@JvmField val MAGOST_BERRY = berryItem("magost", CobblemonBlocks.MAGOST_BERRY)
@JvmField val RABUTA_BERRY = berryItem("rabuta", CobblemonBlocks.RABUTA_BERRY)
@JvmField val NOMEL_BERRY = berryItem("nomel", CobblemonBlocks.NOMEL_BERRY)
@JvmField val ENIGMA_BERRY = berryItem("enigma", CobblemonBlocks.ENIGMA_BERRY)
@JvmField val POMEG_BERRY = berryItem("pomeg", FriendshipRaisingBerryItem(CobblemonBlocks.POMEG_BERRY, Stats.HP))
@JvmField val KELPSY_BERRY = berryItem("kelpsy", FriendshipRaisingBerryItem(CobblemonBlocks.KELPSY_BERRY, Stats.ATTACK))
@JvmField val QUALOT_BERRY = berryItem("qualot", FriendshipRaisingBerryItem(CobblemonBlocks.QUALOT_BERRY, Stats.DEFENCE))
@JvmField val HONDEW_BERRY = berryItem("hondew", FriendshipRaisingBerryItem(CobblemonBlocks.HONDEW_BERRY, Stats.SPECIAL_ATTACK))
@JvmField val GREPA_BERRY = berryItem("grepa", FriendshipRaisingBerryItem(CobblemonBlocks.GREPA_BERRY, Stats.SPECIAL_DEFENCE))
@JvmField val TAMATO_BERRY = berryItem("tamato", FriendshipRaisingBerryItem(CobblemonBlocks.TAMATO_BERRY, Stats.SPEED))
@JvmField val SPELON_BERRY = berryItem("spelon", CobblemonBlocks.SPELON_BERRY)
@JvmField val PAMTRE_BERRY = berryItem("pamtre", CobblemonBlocks.PAMTRE_BERRY)
@JvmField val WATMEL_BERRY = berryItem("watmel", CobblemonBlocks.WATMEL_BERRY)
@JvmField val DURIN_BERRY = berryItem("durin", CobblemonBlocks.DURIN_BERRY)
@JvmField val BELUE_BERRY = berryItem("belue", CobblemonBlocks.BELUE_BERRY)
@JvmField val KEE_BERRY = berryItem("kee", CobblemonBlocks.KEE_BERRY)
@JvmField val MARANGA_BERRY = berryItem("maranga", CobblemonBlocks.MARANGA_BERRY)
@JvmField val HOPO_BERRY = berryItem("hopo", PPRestoringBerryItem(CobblemonBlocks.HOPO_BERRY) { CobblemonMechanics.berries.ppRestoreAmount })
@JvmField val LIECHI_BERRY = berryItem("liechi", CobblemonBlocks.LIECHI_BERRY)
@JvmField val GANLON_BERRY = berryItem("ganlon", CobblemonBlocks.GANLON_BERRY)
@JvmField val SALAC_BERRY = berryItem("salac", CobblemonBlocks.SALAC_BERRY)
@@ -576,10 +587,15 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val APICOT_BERRY = berryItem("apicot", CobblemonBlocks.APICOT_BERRY)
@JvmField val LANSAT_BERRY = berryItem("lansat", CobblemonBlocks.LANSAT_BERRY)
@JvmField val STARF_BERRY = berryItem("starf", CobblemonBlocks.STARF_BERRY)
@JvmField val ENIGMA_BERRY = berryItem("enigma", CobblemonBlocks.ENIGMA_BERRY)
@JvmField val MICLE_BERRY = berryItem("micle", CobblemonBlocks.MICLE_BERRY)
@JvmField val CUSTAP_BERRY = berryItem("custap", CobblemonBlocks.CUSTAP_BERRY)
@JvmField val JABOCA_BERRY = berryItem("jaboca", CobblemonBlocks.JABOCA_BERRY)
@JvmField val ROWAP_BERRY = berryItem("rowap", CobblemonBlocks.ROWAP_BERRY)
@JvmField val ROSELI_BERRY = berryItem("roseli", CobblemonBlocks.ROSELI_BERRY)
@JvmField val KEE_BERRY = berryItem("kee", CobblemonBlocks.KEE_BERRY)
@JvmField val MARANGA_BERRY = berryItem("maranga", CobblemonBlocks.MARANGA_BERRY)
@JvmField val HOPO_BERRY = berryItem("hopo", PPRestoringBerryItem(CobblemonBlocks.HOPO_BERRY) { CobblemonMechanics.berries.ppRestoreAmount })
@JvmField val BERRY_JUICE = this.create("berry_juice", BerryJuiceItem())
@@ -683,7 +699,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
})
@JvmField
val ENERGY_ROOT = compostableItem("energy_root", EnergyRootItem(CobblemonBlocks.ENERGY_ROOT, Properties()), 0.60f)
val ENERGY_ROOT = compostableItem("energy_root", EnergyRootItem(CobblemonBlocks.ENERGY_ROOT, Properties()), 0.65f)
@JvmField
val REVIVAL_HERB = compostableItem("revival_herb", RevivalHerbItem(CobblemonBlocks.REVIVAL_HERB))
@JvmField
@@ -693,22 +709,22 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val REMEDY = compostableItem("remedy", RemedyItem(RemedyItem.NORMAL), 0.65f)
@JvmField
val FINE_REMEDY = compostableItem("fine_remedy", RemedyItem(RemedyItem.FINE), 0.75f)
val FINE_REMEDY = compostableItem("fine_remedy", RemedyItem(RemedyItem.FINE), 0.85f)
@JvmField
val SUPERB_REMEDY = compostableItem("superb_remedy", RemedyItem(RemedyItem.SUPERB), 0.85f)
val SUPERB_REMEDY = compostableItem("superb_remedy", RemedyItem(RemedyItem.SUPERB), 1f)
@JvmField
val MOOMOO_MILK = create("moomoo_milk", MoomooMilk(Item.Properties().craftRemainder(Items.GLASS_BOTTLE).stacksTo((16))))
@JvmField
val POTION = create("potion", PotionItem(PotionType.POTION))
val POTION = create("potion", PotionItem(PotionType.POTION, CobblemonBlocks.POTION))
@JvmField
val SUPER_POTION = create("super_potion", PotionItem(PotionType.SUPER_POTION))
val SUPER_POTION = create("super_potion", PotionItem(PotionType.SUPER_POTION, CobblemonBlocks.SUPER_POTION))
@JvmField
val HYPER_POTION = create("hyper_potion", PotionItem(PotionType.HYPER_POTION))
val HYPER_POTION = create("hyper_potion", PotionItem(PotionType.HYPER_POTION, CobblemonBlocks.HYPER_POTION))
@JvmField
val MAX_POTION = create("max_potion", PotionItem(PotionType.MAX_POTION))
val MAX_POTION = create("max_potion", PotionItem(PotionType.MAX_POTION, CobblemonBlocks.MAX_POTION))
@JvmField
val FULL_RESTORE = create("full_restore", PotionItem(PotionType.FULL_RESTORE))
val FULL_RESTORE = create("full_restore", PotionItem(PotionType.FULL_RESTORE, CobblemonBlocks.FULL_RESTORE))
@JvmField
val HEAL_POWDER = create("heal_powder", HealPowderItem())
@@ -793,28 +809,27 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SERIOUS_MINT = mintItem("serious_mint", MintItem(Natures.SERIOUS))
@JvmField val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", XStatItem(Stats.ACCURACY))
@JvmField val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", XStatItem(Stats.ATTACK))
@JvmField val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", XStatItem(Stats.DEFENCE))
@JvmField val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", XStatItem(Stats.SPECIAL_ATTACK))
@JvmField val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", XStatItem(Stats.SPECIAL_DEFENCE))
@JvmField val X_SPEED = create("x_${Stats.SPEED.identifier.path}", XStatItem(Stats.SPEED))
@JvmField val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", XStatItem(Stats.ACCURACY, block = CobblemonBlocks.X_ACCURACY))
@JvmField val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", XStatItem(Stats.ATTACK, block = CobblemonBlocks.X_ATTACK))
@JvmField val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", XStatItem(Stats.DEFENCE, block = CobblemonBlocks.X_DEFENSE))
@JvmField val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", XStatItem(Stats.SPECIAL_ATTACK, block = CobblemonBlocks.X_SP_ATK))
@JvmField val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", XStatItem(Stats.SPECIAL_DEFENCE, block = CobblemonBlocks.X_SP_DEF))
@JvmField val X_SPEED = create("x_${Stats.SPEED.identifier.path}", XStatItem(Stats.SPEED, block = CobblemonBlocks.X_SPEED))
@JvmField val DIRE_HIT = create("dire_hit", DireHitItem())
@JvmField val GUARD_SPEC = create("guard_spec", GuardSpecItem())
@JvmField val DIRE_HIT = create("dire_hit", DireHitItem(CobblemonBlocks.DIRE_HIT))
@JvmField val GUARD_SPEC = create("guard_spec", GuardSpecItem(CobblemonBlocks.GUARD_SPEC))
@JvmField val BURN_HEAL = create("burn_heal", StatusCureItem("item.cobblemon.burn_heal", Statuses.BURN))
@JvmField val PARALYZE_HEAL = create("paralyze_heal", StatusCureItem("item.cobblemon.paralyze_heal", Statuses.PARALYSIS))
@JvmField val ICE_HEAL = create("ice_heal", StatusCureItem("item.cobblemon.ice_heal", Statuses.FROZEN))
@JvmField val ANTIDOTE = create("antidote", StatusCureItem("item.cobblemon.antidote", Statuses.POISON, Statuses.POISON_BADLY))
@JvmField val AWAKENING = create("awakening", StatusCureItem("item.cobblemon.awakening", Statuses.SLEEP))
@JvmField val FULL_HEAL = create("full_heal", StatusCureItem("item.cobblemon.full_heal", block = CobblemonBlocks.FULL_HEAL))
@JvmField val ANTIDOTE = create("antidote", StatusCureItem("item.cobblemon.antidote", Statuses.POISON, Statuses.POISON_BADLY, block = CobblemonBlocks.ANTIDOTE))
@JvmField val AWAKENING = create("awakening", StatusCureItem("item.cobblemon.awakening", Statuses.SLEEP, block = CobblemonBlocks.AWAKENING))
@JvmField val BURN_HEAL = create("burn_heal", StatusCureItem("item.cobblemon.burn_heal", Statuses.BURN, block = CobblemonBlocks.BURN_HEAL))
@JvmField val ICE_HEAL = create("ice_heal", StatusCureItem("item.cobblemon.ice_heal", Statuses.FROZEN, block = CobblemonBlocks.ICE_HEAL))
@JvmField val PARALYZE_HEAL = create("paralyze_heal", StatusCureItem("item.cobblemon.paralyze_heal", Statuses.PARALYSIS, block = CobblemonBlocks.PARALYZE_HEAL))
@JvmField val FULL_HEAL = create("full_heal", StatusCureItem("item.cobblemon.full_heal"))
@JvmField val ETHER = create("ether", EtherItem(max = false))
@JvmField val MAX_ETHER = create("max_ether", EtherItem(max = true))
@JvmField val ELIXIR = create("elixir", ElixirItem(max = false))
@JvmField val MAX_ELIXIR = create("max_elixir", ElixirItem(max = true))
@JvmField val ETHER = create("ether", EtherItem(max = false, CobblemonBlocks.ETHER))
@JvmField val MAX_ETHER = create("max_ether", EtherItem(max = true, CobblemonBlocks.MAX_ETHER))
@JvmField val ELIXIR = create("elixir", ElixirItem(max = false, CobblemonBlocks.ELIXIR))
@JvmField val MAX_ELIXIR = create("max_elixir", ElixirItem(max = true, CobblemonBlocks.MAX_ELIXIR))
@JvmField
val ABILITY_CAPSULE = this.create("ability_capsule", AbilityChangeItem(AbilityChanger.COMMON_ABILITY))
@@ -915,7 +930,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val ASSAULT_VEST = heldItem("assault_vest")
@JvmField
val BIG_ROOT = compostableBlockItem("big_root", CobblemonBlocks.BIG_ROOT, 0.40f)
val BIG_ROOT = compostableBlockItem("big_root", CobblemonBlocks.BIG_ROOT, 0.30f)
@JvmField
val BINDING_BAND = heldItem("binding_band")
@JvmField
@@ -923,7 +938,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val BLACK_SLUDGE = heldItem("black_sludge")
@JvmField
val BLUNDER_POLICY = heldItem("blunder_policy")
val BLUNDER_POLICY = itemNameBlockItem("blunder_policy", CobblemonBlocks.BLUNDER_POLICY)
@JvmField
val CELL_BATTERY = heldItem("cell_battery")
@JvmField
@@ -931,7 +946,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHOICE_SCARF = heldItem("choice_scarf")
@JvmField
val CLEANSE_TAG = heldItem("cleanse_tag")
val CLEANSE_TAG = itemNameBlockItem("cleanse_tag", CobblemonBlocks.CLEANSE_TAG)
@JvmField
val CLEAR_AMULET = heldItem("clear_amulet")
@JvmField
@@ -1039,7 +1054,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SOFT_SAND = heldItem("soft_sand")
@JvmField
val SPELL_TAG = heldItem("spell_tag")
val SPELL_TAG = itemNameBlockItem("spell_tag", CobblemonBlocks.SPELL_TAG)
@JvmField
val SMOKE_BALL = heldItem("smoke_ball")
@JvmField
@@ -1057,21 +1072,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val UTILITY_UMBRELLA = heldItem("utility_umbrella")
@JvmField
val WEAKNESS_POLICY = heldItem("weakness_policy")
val WEAKNESS_POLICY = itemNameBlockItem("weakness_policy", CobblemonBlocks.WEAKNESS_POLICY)
@JvmField
val WIDE_LENS = heldItem("wide_lens")
@JvmField
val ZOOM_LENS = heldItem("zoom_lens")
@JvmField
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 1F)
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 0.85F)
@JvmField
val MIRROR_HERB = compostableHeldItem("mirror_herb", null, 1F)
val MIRROR_HERB = compostableHeldItem("mirror_herb", null, 0.85F)
@JvmField
val MISTY_SEED = heldItem("misty_seed")
@JvmField
val POWER_HERB = compostableHeldItem("power_herb", null, 1F)
val POWER_HERB = compostableHeldItem("power_herb", null, 0.85F)
@JvmField
val WHITE_HERB = compostableHeldItem("white_herb", null, 1F)
val WHITE_HERB = compostableHeldItem("white_herb", null, 0.85F)
@JvmField
val BRIGHT_POWDER = heldItem("bright_powder")
@JvmField
@@ -1554,6 +1569,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
}
)
private fun heldItem(name: String, item: Item, remappedName: String? = null) = create(
name = name,
entry = item.also {
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.mechanics.AprijuicesMechanic
import com.cobblemon.mod.common.mechanics.BerriesMechanic
import com.cobblemon.mod.common.mechanics.PotionsMechanic
import com.cobblemon.mod.common.mechanics.RemediesMechanic
import com.cobblemon.mod.common.mechanics.SlowpokeTailsMechanic
import com.cobblemon.mod.common.net.messages.client.data.CobblemonMechanicsSyncPacket
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.cobblemonResource
@@ -39,14 +41,24 @@ object CobblemonMechanics : DataRegistry {
var berries = BerriesMechanic()
var potions = PotionsMechanic()
var aprijuices = AprijuicesMechanic()
var slowpokeTails = SlowpokeTailsMechanic()
override fun sync(player: ServerPlayer) {}
override fun sync(player: ServerPlayer) {
CobblemonMechanicsSyncPacket(
this.remedies,
this.berries,
this.potions,
this.aprijuices,
this.slowpokeTails
).sendToPlayer(player)
}
override fun reload(manager: ResourceManager) {
remedies = loadMechanic(manager, "remedies", RemediesMechanic::class.java)
berries = loadMechanic(manager, "berries", BerriesMechanic::class.java)
potions = loadMechanic(manager, "potions", PotionsMechanic::class.java)
aprijuices = loadMechanic(manager, "aprijuices", AprijuicesMechanic::class.java)
slowpokeTails = loadMechanic(manager, "slowpoke_tails", SlowpokeTailsMechanic::class.java)
}
private fun <T> loadMechanic(manager: ResourceManager, name: String, clazz: Class<T>): T {
@@ -15,12 +15,12 @@ import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.ListCodec
import com.mojang.serialization.codecs.PrimitiveCodec
import java.util.Optional
import java.util.UUID
import net.minecraft.core.BlockPos
import net.minecraft.core.GlobalPos
import net.minecraft.core.UUIDUtil
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import java.util.*
object CobblemonMemories {
val memories = mutableMapOf<String, MemoryModuleType<*>>()
@@ -30,49 +30,76 @@ object CobblemonMemories {
* get serialized during relogs. This makes sense for things like battles which
* do not survive a relog therefore any memory of it should be temporary.
*/
@JvmField
val BATTLING_POKEMON = register("battling_pokemon", ListCodec(UUIDUtil.CODEC, 0, 31))
@JvmField
val NPC_BATTLING = register("npc_battling", PrimitiveCodec.BOOL)
@JvmField
val DIALOGUES = register<List<ActiveDialogue>>("npc_dialogues")
@JvmField
val ACTIVE_ACTION_EFFECT = register<ActionEffectContext>("active_action_effect")
@JvmField
val POKEMON_FLYING = register("pokemon_flying", PrimitiveCodec.BOOL)
@JvmField
val POKEMON_DROWSY = register("pokemon_drowsy", PrimitiveCodec.BOOL)
@JvmField
val POKEMON_SLEEPING = register("pokemon_sleeping", PrimitiveCodec.BOOL)
@JvmField
val POKEMON_BATTLE = register<UUID>("pokemon_battle")
@JvmField
val PATH_COOLDOWN = register<Boolean>("path_cooldown")
@JvmField
val TARGETED_BATTLE_POKEMON = register<UUID>("targeted_battle_pokemon")
@JvmField
val NEAREST_VISIBLE_ATTACKER = register<LivingEntity>("nearest_visible_attacker")
@JvmField
val NEARBY_GROWABLE_CROPS = register<BlockPos>("nearby_growable_crops")
@JvmField
val NEARBY_SWEET_BERRY_BUSH = register<BlockPos>("nearest_sweet_berry_bush")
@JvmField
val DISABLE_WALK_TO_BERRY_BUSH = register<Boolean>("disable_walk_to_berry_bush")
val TIME_TRYING_TO_REACH_BERRY_BUSH = register<Int>("time_trying_to_reach_berry_bush")
@JvmField
val IS_CONSUMING_ITEM = register<Boolean>("is_consuming_item")
val RECENTLY_ATE_GRASS = register<Boolean>("recently_ate_grass")
@JvmField
val HIVE_LOCATION = register<BlockPos>("hive_location", BlockPos.CODEC)
@JvmField
val HIVE_BLACKLIST = register<List<BlockPos>>("hive_blacklist")
@JvmField
val HIVE_COOLDOWN = register<Boolean>("hive_cooldown")
@JvmField
val NEARBY_FLOWER = register<BlockPos>("nearby_flower", BlockPos.CODEC)
@JvmField
val PATH_TO_NEARBY_FLOWER_COOLDOWN = register<Boolean>("path_to_nearby_flower_cooldown")
@JvmField
val HAS_NECTAR = register<Boolean>("has_nectar", PrimitiveCodec.BOOL)
@JvmField
val NEARBY_SACC_LEAVES = register<BlockPos>("nearby_sacc_leaves", BlockPos.CODEC)
/** who am i following rn? */
@JvmField
val HERD_LEADER = register<String>("herd_leader", PrimitiveCodec.STRING)
/** how many are following me rn? */
@JvmField
val HERD_SIZE = register<Int>("herd_size") // Don't bother saving it, we'll try to keep count roughly.
@JvmField
val ATTACK_TARGET_DATA = register<CobblemonAttackTargetData>("attack_target_data") // This is used to store additional information about the attack target, such as when to give up pursuit.
@JvmField
val WANDER_CONTROL = register<CobblemonWanderControl>("wander_control")
@JvmField
val DISABLE_WALK_TO_WANTED_ITEM = register<Boolean>("disable_walk_to_wanted_item")
@JvmField
val TIME_TRYING_TO_REACH_WANTED_ITEM = register<Int>("time_trying_to_wanted_item")
@JvmStatic
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
val memoryModule = MemoryModuleType(Optional.of(codec))
memories[id] = memoryModule
return memoryModule
}
@JvmStatic
fun <U> register(id: String): MemoryModuleType<U> {
val memoryModule = MemoryModuleType<U>(Optional.empty())
memories[id] = memoryModule
return memoryModule
}
}
}
@@ -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
import com.cobblemon.mod.common.api.cooking.effects.CleanseAllEffect
import com.cobblemon.mod.common.api.cooking.effects.CleanseNegativeEffect
import com.cobblemon.mod.common.api.cooking.effects.MentalRestorationEffect
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.world.effect.MobEffect
object CobblemonMobEffects : PlatformRegistry<Registry<MobEffect>, ResourceKey<Registry<MobEffect>>, MobEffect>() {
override val registry: Registry<MobEffect> = BuiltInRegistries.MOB_EFFECT
override val resourceKey: ResourceKey<Registry<MobEffect>> = Registries.MOB_EFFECT
@JvmField
val CLEANSE_NEGATIVE = create("cleanse_negative", CleanseNegativeEffect())
@JvmField
val MENTAL_RESTORATION = create("mental_restoration", MentalRestorationEffect())
@JvmField
val CLEANSE_ALL = create("cleanse_all", CleanseAllEffect())
}
@@ -19,8 +19,11 @@ import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
import com.cobblemon.mod.common.client.net.cooking.ToggleCookingPotLidHandler
import com.cobblemon.mod.common.client.net.data.CobblemonMechanicsSyncHandler
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
import com.cobblemon.mod.common.client.net.data.RideSettingsSyncHandler
import com.cobblemon.mod.common.client.net.debug.OpenRidingStatsDebugGUIHandler
import com.cobblemon.mod.common.client.net.debug.UpdateTrackedBrainDataHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
import com.cobblemon.mod.common.client.net.effect.PokeSnackBlockParticlesHandler
@@ -78,6 +81,8 @@ import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyMoveCallba
import com.cobblemon.mod.common.net.messages.client.cooking.SeasoningRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.cooking.ToggleCookingPotLidPacket
import com.cobblemon.mod.common.net.messages.client.data.*
import com.cobblemon.mod.common.net.messages.client.debug.RequestOpenRidingStatsDebugGUIPacket
import com.cobblemon.mod.common.net.messages.client.debug.UpdateTrackedBrainDataPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
import com.cobblemon.mod.common.net.messages.client.effect.PokeSnackBlockParticlesPacket
@@ -159,12 +164,16 @@ import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonS
import com.cobblemon.mod.common.net.messages.server.callback.party.PartySelectCancelledPacket
import com.cobblemon.mod.common.net.messages.server.callback.partymove.PartyMoveSelectCancelledPacket
import com.cobblemon.mod.common.net.messages.server.callback.partymove.PartyPokemonMoveSelectedPacket
import com.cobblemon.mod.common.net.messages.server.debug.OpenRidingStatsDebugGUIPacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingSettingsPacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatRangePacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatsPacket
import com.cobblemon.mod.common.net.messages.server.dialogue.EscapeDialoguePacket
import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePacket
import com.cobblemon.mod.common.net.messages.server.npc.ApplyPremadeNPCPacket
import com.cobblemon.mod.common.net.messages.server.npc.DeletePremadePacket
import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
import com.cobblemon.mod.common.net.messages.server.npc.SavePremadeFromNPCPacket
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket
import com.cobblemon.mod.common.net.messages.server.pasture.PasturePokemonPacket
import com.cobblemon.mod.common.net.messages.server.pasture.SetPastureConflictPacket
@@ -185,6 +194,7 @@ import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateRide
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
import com.cobblemon.mod.common.net.messages.server.storage.SwapPCPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.PartyTutorialPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.ReleasePartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.pc.*
@@ -212,13 +222,17 @@ import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSe
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartySelectCancelledHandler
import com.cobblemon.mod.common.net.serverhandling.callback.partymove.PartyMoveSelectCancelledHandler
import com.cobblemon.mod.common.net.serverhandling.callback.partymove.PartyPokemonMoveSelectedHandler
import com.cobblemon.mod.common.net.serverhandling.debug.RequestOpenRidingStatsDebugGUIHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingSettingsHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatRangeHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatsHandler
import com.cobblemon.mod.common.net.serverhandling.dialogue.EscapeDialogueHandler
import com.cobblemon.mod.common.net.serverhandling.dialogue.InputToDialogueHandler
import com.cobblemon.mod.common.net.serverhandling.evolution.AcceptEvolutionHandler
import com.cobblemon.mod.common.net.serverhandling.npc.ApplyPremadeNPCHandler
import com.cobblemon.mod.common.net.serverhandling.npc.DeletePremadeHandler
import com.cobblemon.mod.common.net.serverhandling.npc.SaveNPCHandler
import com.cobblemon.mod.common.net.serverhandling.npc.SavePremadeFromNPCHandler
import com.cobblemon.mod.common.net.serverhandling.orientation.ServerboundUpdateOrientationHandler
import com.cobblemon.mod.common.net.serverhandling.pasture.PasturePokemonHandler
import com.cobblemon.mod.common.net.serverhandling.pasture.SetPastureConflictHandler
@@ -242,6 +256,7 @@ import com.cobblemon.mod.common.net.serverhandling.storage.RequestMoveSwapHandle
import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.SwapPCPartyPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.party.MovePartyPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.party.PartyTutorialPacketHandler
import com.cobblemon.mod.common.net.serverhandling.storage.party.ReleasePCPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.party.SwapPartyPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.pc.*
@@ -267,10 +282,13 @@ object CobblemonNetwork {
fun ServerPlayer.sendPacket(packet: NetworkPacket<*>) {
sendPacketToPlayer(this, packet)
}
@JvmStatic
fun sendToServer(packet: NetworkPacket<*>) {
Cobblemon.implementation.networkManager.sendToServer(packet)
}
@JvmStatic
fun sendToAllPlayers(packet: NetworkPacket<*>) = sendPacketToPlayers(server()!!.playerList.players, packet)
@JvmStatic
fun sendPacketToPlayers(players: Iterable<ServerPlayer>, packet: NetworkPacket<*>) = players.forEach { sendPacketToPlayer(it, packet) }
val s2cPayloads = generateS2CPacketInfoList()
@@ -392,6 +410,8 @@ object CobblemonNetwork {
// Data registries
list.add(PacketRegisterInfo(AbilityRegistrySyncPacket.ID, AbilityRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(CobblemonMechanicsSyncPacket.ID, CobblemonMechanicsSyncPacket::decode, CobblemonMechanicsSyncHandler))
list.add(PacketRegisterInfo(PokemonInteractionsSyncPacket.ID, PokemonInteractionsSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
@@ -413,6 +433,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(RideSettingsSyncPacket.ID, RideSettingsSyncPacket::decode, RideSettingsSyncHandler))
list.add(PacketRegisterInfo(PremadeNPCRegistrySyncPacket.ID, PremadeNPCRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
// Effects
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
@@ -482,6 +503,10 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(ClientboundUpdateRidingStatePacket.ID, ClientboundUpdateRidingStatePacket::decode, ClientboundUpdateRidingStateHandler))
list.add(PacketRegisterInfo(ClientboundUpdateDriverInputPacket.ID, ClientboundUpdateDriverInputPacket::decode, ClientboundUpdateDriverInputHandler))
// Debug
list.add(PacketRegisterInfo(OpenRidingStatsDebugGUIPacket.ID, OpenRidingStatsDebugGUIPacket::decode, OpenRidingStatsDebugGUIHandler))
list.add(PacketRegisterInfo(UpdateTrackedBrainDataPacket.ID, UpdateTrackedBrainDataPacket::decode, UpdateTrackedBrainDataHandler))
return list
}
@@ -516,7 +541,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(ReleasePCPokemonPacket.ID, ReleasePCPokemonPacket::decode, ReleasePCPokemonHandler))
list.add(PacketRegisterInfo(UnlinkPlayerFromPCPacket.ID, UnlinkPlayerFromPCPacket::decode, UnlinkPlayerFromPCHandler))
list.add(PacketRegisterInfo(RequestRenamePCBoxPacket.Companion.ID, RequestRenamePCBoxPacket.Companion::decode, RequestRenamePCBoxHandler))
list.add(PacketRegisterInfo(RequestRenamePCBoxPacket.ID, RequestRenamePCBoxPacket::decode, RequestRenamePCBoxHandler))
list.add(PacketRegisterInfo(PCBoxWallpapersPacket.ID, PCBoxWallpapersPacket::decode, PCBoxWallpapersHandler))
list.add(PacketRegisterInfo(RequestChangePCBoxWallpaperPacket.ID, RequestChangePCBoxWallpaperPacket::decode, RequestChangePCBoxWallpaperHandler))
list.add(PacketRegisterInfo(MarkPCBoxWallpapersSeenPacket.ID, MarkPCBoxWallpapersSeenPacket::decode, MarkPCBoxWallpapersSeenHandler))
@@ -574,12 +599,18 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(PartyPokemonMoveSelectedPacket.ID, PartyPokemonMoveSelectedPacket::decode, PartyPokemonMoveSelectedHandler))
list.add(PacketRegisterInfo(PartyMoveSelectCancelledPacket.ID, PartyMoveSelectCancelledPacket::decode, PartyMoveSelectCancelledHandler))
//Party move tutorial toasts packets
list.add(PacketRegisterInfo(PartyTutorialPacket.ID, PartyTutorialPacket::decode, PartyTutorialPacketHandler))
// Dialogue packets
list.add(PacketRegisterInfo(EscapeDialoguePacket.ID, EscapeDialoguePacket::decode, EscapeDialogueHandler))
list.add(PacketRegisterInfo(InputToDialoguePacket.ID, InputToDialoguePacket::decode, InputToDialogueHandler))
// NPC packets
list.add(PacketRegisterInfo(SaveNPCPacket.ID, SaveNPCPacket::decode, SaveNPCHandler))
list.add(PacketRegisterInfo(SavePremadeFromNPCPacket.ID, SavePremadeFromNPCPacket::decode, SavePremadeFromNPCHandler))
list.add(PacketRegisterInfo(DeletePremadePacket.ID, DeletePremadePacket::decode, DeletePremadeHandler))
list.add(PacketRegisterInfo(ApplyPremadeNPCPacket.ID, ApplyPremadeNPCPacket::decode, ApplyPremadeNPCHandler))
// Riding packet(s)
list.add(PacketRegisterInfo(ServerboundUpdateOrientationPacket.ID, ServerboundUpdateOrientationPacket::decode, ServerboundUpdateOrientationHandler))
@@ -598,10 +629,13 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
list.add(PacketRegisterInfo(DamageOnCollisionPacket.ID, DamageOnCollisionPacket::decode, DamageOnCollisionPacketHandler))
// Debug
list.add(PacketRegisterInfo(RequestOpenRidingStatsDebugGUIPacket.ID, RequestOpenRidingStatsDebugGUIPacket::decode, RequestOpenRidingStatsDebugGUIHandler))
return list
}
fun sendPacketToPlayer(player: ServerPlayer, packet: NetworkPacket<*>) {
Cobblemon.implementation.networkManager.sendPacketToPlayer(player, packet)
}
}
}
@@ -18,6 +18,7 @@ import net.minecraft.resources.ResourceKey
import net.minecraft.world.entity.ai.village.poi.PoiType
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.Blocks
object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Registry<PoiType>>, PoiType>() {
override val registry: Registry<PoiType> = BuiltInRegistries.POINT_OF_INTEREST_TYPE
@@ -30,6 +31,8 @@ object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Regist
// TODO after 1.7
// @JvmField
// val INCENSE_SWEET_KEY = createKey("incense_sweet", CobblemonBlocks.INCENSE_SWEET, 0, 1)
@JvmField
val JUKEBOX_KEY = createKey("vanilla_jukebox", Blocks.JUKEBOX, 0, 1)
private fun createKey(string: String, block: Block, maxTickets: Int, validRange: Int ): ResourceKey<PoiType> =
ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string)).also { resourceKey ->
@@ -9,14 +9,15 @@
package com.cobblemon.mod.common
import net.minecraft.client.RecipeBookCategories
import net.minecraft.world.inventory.RecipeBookType
enum class CobblemonRecipeCategories {
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
COOKING_POT_FOODS("COOKING_POT_FOODS"),
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
COOKING_POT_COMPLEX_DISHES("COOKING_POT_COMPLEX_DISHES"),
COOKING_POT_MISC("COOKING_POT_MISC");
COOKING_POT_SEARCH("COBBLEMON_COOKING_POT_SEARCH"),
COOKING_POT_FOODS("COBBLEMON_COOKING_POT_FOODS"),
COOKING_POT_MEDICINES("COBBLEMON_COOKING_POT_MEDICINES"),
COOKING_POT_COMPLEX_DISHES("COBBLEMON_COOKING_POT_COMPLEX_DISHES"),
COOKING_POT_MISC("COBBLEMON_COOKING_POT_MISC");
companion object {
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
@@ -35,6 +36,9 @@ enum class CobblemonRecipeCategories {
fun toVanillaCategory(): RecipeBookCategories {
return RecipeBookCategories.valueOf(this.id)
}
}
object CobblemonRecipeBookTypes {
const val COOKING_POT_NAME = "COBBLEMON_COOKING_POT"
val COOKING_POT: RecipeBookType = RecipeBookType.valueOf(COOKING_POT_NAME)
}
@@ -20,32 +20,42 @@ import net.minecraft.world.entity.ai.sensing.SensorType
object CobblemonSensors {
val sensors = mutableMapOf<String, SensorType<*>>()
@JvmField
val NPC_BATTLING = register("npc_battling", ::NPCBattlingSensor)
@JvmField
val BATTLING_POKEMON = register("battling_pokemon", ::BattlingPokemonSensor)
// val NPC_BATTLING = register("npc_battling", ::NPCBattlingSensor)
@JvmField
val POKEMON_DROWSY = register("pokemon_drowsy", ::DrowsySensor)
@JvmField
val POKEMON_ADULT = register("pokemon_adult_sensor", ::PokemonAdultSensor)
@JvmField
val POKEMON_DISTURBANCE = register("pokemon_disturbance_sensor", ::PokemonDisturbancesSensor)
@JvmField
val POKEMON_DEFEND_OWNER = register("pokemon_owner_under_attack", ::DefendOwnerSensor)
@JvmField
val NEARBY_GROWABLE_CROPS = register("nearby_growable_crops", ::PokemonGrowableCropSensor)
@JvmField
val NEARBY_BEE_HIVE = register("nearby_bee_hive", ::BeeHiveSensor)
@JvmField
val NEARBY_FLOWER = register("nearby_flower", ::FlowerSensor)
val NEARBY_SWEET_BERRY_BUSH = register("nearby_sweet_berry_bush", ::SweetBerryBushSensor)
@JvmField
val POKEMON_NEARBY_WANTED_ITEM = register("pokemon_nearby_wanted_item", ::PokemonItemSensor)
@JvmField
val NEARBY_SACC_LEAVES = register("nearby_sacc_leaves", ::SacLeavesSensor)
@JvmStatic
fun <E : Entity, U : Sensor<E>> register(id: String, supplier: Supplier<U>): SensorType<U> {
val sensor = SensorType(supplier)
sensors[id] = sensor
return sensor
}
}
}
@@ -89,7 +89,14 @@ object CobblemonTradeOffers {
* @return The resulting list.
*/
fun resolveWanderingTradeOffers(): List<WandererTradeOffer> = listOf(
WandererTradeOffer(false, listOf(VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6)))
WandererTradeOffer(false, listOf(
VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 6, 1, 1, 6),
VillagerTrades.ItemsForEmeralds(CobblemonItems.SACCHARINE_SAPLING, 5, 1, 4, 1),
VillagerTrades.ItemsForEmeralds(CobblemonItems.HEARTY_GRAINS, 1, 1, 12, 1),
VillagerTrades.ItemsForEmeralds(CobblemonItems.CHIPPED_POT, 5, 1, 1, 2),
VillagerTrades.ItemsForEmeralds(CobblemonItems.MASTERPIECE_TEACUP, 5, 1, 1, 2)
))
)
/**
@@ -23,43 +23,63 @@ import net.minecraft.resources.ResourceKey
* @since October 26th, 2022
*/
object CobblemonCriteria : PlatformRegistry<Registry<CriterionTrigger<*>>, ResourceKey<Registry<CriterionTrigger<*>>>, CriterionTrigger<*>>(){
@JvmField
val PICK_STARTER = this.create("pick_starter", SimpleCriterionTrigger(PokemonCriterion.CODEC))
@JvmField
val CATCH_POKEMON = this.create("catch_pokemon", SimpleCriterionTrigger(CaughtPokemonCriterion.CODEC))
@JvmField
val CATCH_SHINY_POKEMON = this.create("catch_shiny_pokemon", SimpleCriterionTrigger(CountableCriterion.CODEC))
@JvmField
val EGG_COLLECT = this.create("eggs_collected", SimpleCriterionTrigger(CountableCriterion.CODEC))
@JvmField
val EGG_HATCH = this.create("eggs_hatched", SimpleCriterionTrigger(CountableCriterion.CODEC))
@JvmField
val EVOLVE_POKEMON = this.create("pokemon_evolved", SimpleCriterionTrigger(EvolvePokemonCriterion.CODEC))
@JvmField
val WIN_BATTLE = this.create("battles_won", SimpleCriterionTrigger(BattleCountableCriterion.CODEC))
@JvmField
val DEFEAT_POKEMON = this.create("pokemon_defeated", SimpleCriterionTrigger(CountableCriterion.CODEC))
@JvmField
val COLLECT_ASPECT = this.create("aspects_collected", SimpleCriterionTrigger(AspectCriterion.CODEC))
@JvmField
val POKEMON_INTERACT = this.create("pokemon_interact", SimpleCriterionTrigger(PokemonInteractCriterion.CODEC))
@JvmField
val PARTY_CHECK = this.create("party", SimpleCriterionTrigger(PartyCheckCriterion.CODEC))
@JvmField
val LEVEL_UP = this.create("level_up", SimpleCriterionTrigger(LevelUpCriterion.CODEC))
@JvmField
val PASTURE_USE = this.create("pasture_use", SimpleCriterionTrigger(PokemonCriterion.CODEC))
@JvmField
val RESURRECT_POKEMON = this.create("resurrect_pokemon", SimpleCriterionTrigger(PokemonCriterion.CODEC))
@JvmField
val TRADE_POKEMON = this.create("trade_pokemon", SimpleCriterionTrigger(TradePokemonCriterion.CODEC))
@JvmField
val CAST_POKE_ROD = this.create("cast_poke_rod", SimpleCriterionTrigger(CastPokeRodCriterionCondition.CODEC))
@JvmField
val REEL_IN_POKEMON = this.create("reel_in_pokemon", SimpleCriterionTrigger(ReelInPokemonCriterionCondition.CODEC))
// Advancement criteria for [grow_tumblestone.json]
@JvmField
val PLANT_TUMBLESTONE = this.create("plant_tumblestone", SimpleCriterionTrigger(PlantTumblestoneCriterion.CODEC))
val RIDING_STAT_BOOST = this.create("riding_stat_boost", SimpleCriterionTrigger(RidingStatBoostCriterion.CODEC))
override val registry = BuiltInRegistries.TRIGGER_TYPES
override val resourceKey = Registries.TRIGGER_TYPE
}
}
@@ -32,6 +32,6 @@ class CastPokeRodCriterionCondition(
}
override fun matches(player: ServerPlayer, context: CastPokeRodContext): Boolean {
return (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId.equals("empty_bait"))
return (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "empty_bait")
}
}
@@ -21,23 +21,25 @@ import java.util.Optional
* @author Hiroku
* @since November 4th, 2022
*/
open class CountablePokemonTypeContext(times: Int, var species: String) : CountableContext(times)
open class CountablePokemonTypeContext(times: Int, var type: String/*, var species: String*/) : CountableContext(times)
class CaughtPokemonCriterion(
playerCtx: Optional<ContextAwarePredicate>,
val species: String,
val type : String,
//val species: String,
count: Int
): CountableCriterion<CountablePokemonTypeContext>(playerCtx, count) {
companion object {
val CODEC: Codec<CaughtPokemonCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(CaughtPokemonCriterion::playerCtx),
Codec.STRING.optionalFieldOf("species", "any").forGetter(CaughtPokemonCriterion::species),
Codec.STRING.optionalFieldOf("type", "any").forGetter(CaughtPokemonCriterion::type),
//Codec.STRING.optionalFieldOf("species", "any").forGetter(CaughtPokemonCriterion::species),
Codec.INT.optionalFieldOf("count", 0).forGetter(CaughtPokemonCriterion::count)
).apply(it, ::CaughtPokemonCriterion) }
}
override fun matches(player: ServerPlayer, context: CountablePokemonTypeContext): Boolean {
return super.matches(player, context) && (context.species == species || species == "any")
return super.matches(player, context) && (context.type == type || type == "any")// && (context.species == species || species == "any")
}
}
@@ -28,7 +28,7 @@ class LevelUpCriterion(
val CODEC: Codec<LevelUpCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(LevelUpCriterion::playerCtx),
Codec.INT.optionalFieldOf("level", 0).forGetter(LevelUpCriterion::level),
Codec.BOOL.optionalFieldOf("evolved", true).forGetter(LevelUpCriterion::evolved)
Codec.BOOL.optionalFieldOf("has_evolved", true).forGetter(LevelUpCriterion::evolved)
).apply(it, ::LevelUpCriterion) }
}
@@ -35,6 +35,6 @@ class ReelInPokemonCriterionCondition(
override fun matches(player: ServerPlayer, context: ReelInPokemonContext): Boolean {
return (context.species == this.species.asIdentifierDefaultingNamespace() || this.species == "any")
&& (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "any")
&& (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "any" || this.baitId == "empty_bait")
}
}
@@ -0,0 +1,62 @@
/*
* 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.advancement.criterion
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.advancements.critereon.ContextAwarePredicate
import net.minecraft.advancements.critereon.EntityPredicate
import net.minecraft.server.level.ServerPlayer
import java.util.Optional
class RidingStatBoostContext(val pokemon: PokemonEntity)
class RidingStatBoostCriterion(
playerCtx: Optional<ContextAwarePredicate>,
val requiresOwner: Boolean = true,
val rideStat: String,
val statValue : Double,
val isMax : Boolean
) : SimpleCriterionCondition<RidingStatBoostContext>(playerCtx) {
companion object {
val CODEC: Codec<RidingStatBoostCriterion> by lazy {RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter { it.playerCtx },
Codec.BOOL.optionalFieldOf("requires_owner", true).forGetter { it.requiresOwner },
Codec.STRING.optionalFieldOf("ride_stat", "any").forGetter { it.rideStat },
Codec.DOUBLE.optionalFieldOf("stat_value", 0.0).forGetter { it.statValue },
Codec.BOOL.optionalFieldOf("is_max", false).forGetter { it.isMax }
).apply(it, ::RidingStatBoostCriterion) } }
}
override fun matches(player: ServerPlayer, context: RidingStatBoostContext) : Boolean {
if (requiresOwner && context.pokemon.ownerUUID != player.uuid) {
return false
}
RidingStyle.entries.forEach { ridingStyle ->
RidingStat.entries.forEach { rideStat ->
if (rideStat.name.equals(this.rideStat, true) || this.rideStat == "any" || this.rideStat == "all") {
val max = context.pokemon.pokemon.getMaxRideBoost(rideStat).toDouble()
val min = context.pokemon.pokemon.getBaseRideStat(rideStat).toDouble()
val value = context.pokemon.getRideStat(rideStat, ridingStyle, min, max)
val isSufficient = (value >= this.statValue && this.statValue > 0.0) || !context.pokemon.pokemon.canAddRideBoost(rideStat)
if (isSufficient && this.rideStat == "any") {
return true
} else if (!isSufficient && this.rideStat == "all") {
return false
}
}
}
}
return this.rideStat == "all"
}
}
@@ -70,16 +70,23 @@ object Abilities : DataRegistry {
AbilityRegistrySyncPacket(all()).sendToPlayer(player)
}
@JvmStatic
fun register(ability: AbilityTemplate): AbilityTemplate {
this.abilityMap[ability.name.lowercase()] = ability
return ability
}
@JvmStatic
fun all() = this.abilityMap.values.toList()
@JvmStatic
fun first() = this.abilityMap.values.first()
@JvmStatic
fun get(name: String) = abilityMap[name.lowercase()]
@JvmStatic
fun getOrDummy(name: String) = get(name) ?: DUMMY
@JvmStatic
fun getOrException(name: String) = get(name) ?: throw IllegalArgumentException("Unable to find ability of name: $name")
@JvmStatic
fun count() = this.abilityMap.size
internal fun receiveSyncPacket(abilities: Collection<AbilityTemplate>) {
@@ -0,0 +1,25 @@
package com.cobblemon.mod.common.api.ai
/**
* A classification of what a behaviour is related to, used for organisational purposes. It doesn't have any technical
* implications beyond how they are displayed to players modifying an entity's Behaviours.
*
* @author Hiroku
* @since April 25th, 2026
*/
enum class BehaviourCategory {
/** Relates to movement, reactions, general entity behaviour. */
AI,
/** Relates to how the entity appears. */
APPEARANCE,
/** Relates to the entity's interactions with players or other entities. */
INTERACTION,
/** Relates to the entity's role in gameplay. */
ROLE,
/** Relates to the entity's ability to do Pokémon battles. */
BATTLE,
/** Relates to invisible, technical configuration. */
TECHNICAL,
/** Doesn't fit other categories. */
OTHER,
}
@@ -12,13 +12,15 @@ import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.objective.Objective
import com.cobblemon.mod.common.api.ai.biggerbrain.sense.Sense
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
import com.cobblemon.mod.common.util.activityRegistry
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
@@ -46,6 +48,9 @@ class BehaviourConfigurationContext {
val memories = mutableSetOf<MemoryModuleType<*>>()
val sensors = mutableSetOf<SensorType<*>>()
val objectives = mutableMapOf<Int, MutableList<Objective>>()
val senses = mutableSetOf<Sense>()
val onAdd = mutableListOf<ExpressionLike>()
fun getOrCreateActivity(activity: Activity): ActivityConfigurationContext {
@@ -68,6 +73,22 @@ class BehaviourConfigurationContext {
this.sensors.addAll(sensors)
}
fun addSenses(vararg senses: Sense) {
addSenses(senses.toList())
}
fun addSenses(senses: Collection<Sense>) {
outer@for (sense in senses) {
for (existingSense in this.senses) {
if (existingSense.merge(sense)) {
continue@outer
}
}
this.senses.add(sense)
this.addMemories(sense.memories)
}
}
fun addOnAddScript(script: ExpressionLike) {
onAdd.add(script)
}
@@ -88,8 +109,23 @@ class BehaviourConfigurationContext {
var brain = entity.brain
// Apply the brain config
if (entity is MoLangScriptingEntity) {
brain = entity.assignNewBrainWithMemoriesAndSensors(dynamic, memories, sensors)
val useBiggerBrain = objectives.isNotEmpty() || senses.isNotEmpty()
brain = entity.assignNewBrainWithMemoriesAndSensors(dynamic, memories, if (useBiggerBrain) emptySet() else sensors)
onAdd.forEach { runtime.resolve(it) }
if (useBiggerBrain) {
val wereDebugging = entity.biggerBrain.debuggingPlayers ?: emptySet()
val biggerBrain = BiggerBrain(entity)
entity.biggerBrain = biggerBrain
addSenses(biggerBrain.senses)
val orderedObjectives = objectives.entries.sortedBy { it.key }.flatMap { it.value }
orderedObjectives.forEach(biggerBrain::registerObjective)
biggerBrain.senses.addAll(senses)
biggerBrain.debuggingPlayers.addAll(wereDebugging)
return
} else {
val biggerBrain = BiggerBrain(entity)
entity.biggerBrain = biggerBrain
}
}
activities.forEach { it.apply(entity) }
brain.setCoreActivities(coreActivities)
@@ -13,8 +13,8 @@ import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.util.asTranslated
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.withQueryValue
import com.google.gson.annotations.SerializedName
@@ -23,14 +23,15 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.LivingEntity
class CobblemonBehaviour(
@Transient
var id: ResourceLocation = cobblemonResource("a"),
val name: Component = "".asTranslated(),
val category: BehaviourCategory = BehaviourCategory.OTHER,
val description: Component = "".asTranslated(),
/** Some behaviours aren't really worth showing on the client, namely ones that are simply conditional bundles of other behaviours. */
val visible: Boolean = true,
val entityType: ResourceLocation? = null,
val configurations: List<BehaviourConfig> = mutableListOf(),
// I feel like the onAdd+onAddScript etc could be merged using some interface and a clever deserializer,
// detect if it's a ResourceLocation and failing that, Expression. The on[..]Script fields are kinda fringe though.
@SerializedName("onRemove", alternate = ["undo"])
val onRemove: ExpressionLike? = null,
val onAdd: ExpressionLike? = null,
@@ -9,44 +9,40 @@
package com.cobblemon.mod.common.api.ai
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.util.getBooleanOrNull
import com.cobblemon.mod.common.util.getDoubleOrNull
import kotlin.math.sqrt
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.PathfinderMob
/**
* Used to maintain some settings around how the entity should wander this tick. The idea is you
* reset this with some script task at priority 0 then some number of steps before it gets to the wander
* tasks you can have other conditional tasks jump in to configure parts of this.
* Used to maintain some settings around how the entity should wander this tick. Anything left null
* will fall back to defaults specified by the logic of the WanderAround objective.
*
* @author Hiroku
* @since July 18, 2025
*/
class CobblemonWanderControl(
var center: WanderCenter? = null,
var maxAttempts: Int = 4, // How many times to try to find a suitable point before giving up on that tick.
var allowLand: Boolean = true,
var allowWater: Boolean = false,
var allowAir: Boolean = false,
var pathCooldownTicks: Int = 20 * 5, // Used to mitigate the cost of pathfinding.
var wanderSpeed: Float = 0.35F,
var maxAttempts: Int? = null, // How many times to try to find a suitable point before giving up on that tick.
var allowLand: Boolean? = null,
var allowWater: Boolean? = null,
var allowAir: Boolean? = null,
var wanderSpeed: Float? = null,
var wanderChanceMultiplier: Float? = null
) {
class WanderCenter(val x: Number, val y: Number, val z: Number, val minRange: Float, val maxRange: Float)
@Transient
val struct: QueryStruct = QueryStruct(hashMapOf())
.addFunction("center_x") { center?.x ?: 0.0 }
.addFunction("center_y") { center?.y ?: 0.0 }
.addFunction("center_z") { center?.z ?: 0.0 }
.addFunction("max_attempts") { maxAttempts.toDouble() }
.addFunction("min_range") { center?.minRange ?: 0.0 }
.addFunction("max_range") { center?.maxRange ?: 0.0 }
.addFunction("allow_land") { if (allowLand) 1.0 else 0.0 }
.addFunction("allow_water") { if (allowWater) 1.0 else 0.0 }
.addFunction("allow_air") { if (allowAir) 1.0 else 0.0 }
.addFunction("path_cooldown_ticks") { pathCooldownTicks.toDouble() }
.addFunction("wander_speed") { wanderSpeed }
.addFunction("center_x") { DoubleValue(center?.x ?: 0.0) }
.addFunction("center_y") { DoubleValue(center?.y ?: 0.0) }
.addFunction("center_z") { DoubleValue(center?.z ?: 0.0) }
.addFunction("max_attempts") { DoubleValue(maxAttempts?.toDouble() ?: 0.0) }
.addFunction("min_range") { DoubleValue(center?.minRange ?: 0.0) }
.addFunction("max_range") { DoubleValue(center?.maxRange ?: 0.0) }
.addFunction("allow_land") { DoubleValue(if (allowLand == true) 1.0 else 0.0) }
.addFunction("allow_water") { DoubleValue(if (allowWater == true) 1.0 else 0.0) }
.addFunction("allow_air") { DoubleValue(if (allowAir == true) 1.0 else 0.0) }
.addFunction("wander_speed") { DoubleValue(wanderSpeed ?: 0.0) }
.addFunction("set_center") { params ->
if (params.params.size < 3) {
throw IllegalArgumentException("set_center requires at least 3 parameters: x, y, z")
@@ -68,24 +64,6 @@ class CobblemonWanderControl(
.addFunction("set_allow_land") { params -> allowLand = params.getBooleanOrNull(0) ?: true }
.addFunction("set_allow_water") { params -> allowWater = params.getBooleanOrNull(0) ?: false }
.addFunction("set_allow_air") { params -> allowAir = params.getBooleanOrNull(0) ?: false }
.addFunction("set_path_cooldown_ticks") { params -> pathCooldownTicks = params.getDoubleOrNull(0)?.toInt() ?: (20 * 5) }
.addFunction("set_wander_speed") { params -> wanderSpeed = params.getDoubleOrNull(0)?.toFloat() ?: 0.35F }
.addFunction("reset") {
center = null
allowLand = false
allowWater = false
allowAir = false
pathCooldownTicks = 20 * 5
wanderSpeed = 0.35F
maxAttempts = 4
}
fun isSuitable(position: BlockPos): Boolean {
val center = center ?: return true
val centerPos = BlockPos(center.x.toInt(), center.y.toInt(), center.z.toInt())
val distance = sqrt(centerPos.distSqr(position))
val suitable = distance >= center.minRange && distance <= center.maxRange
return suitable
}
}
@@ -9,9 +9,23 @@
package com.cobblemon.mod.common.api.ai
import com.bedrockk.molang.Expression
import com.bedrockk.molang.ast.NumberExpression
import com.bedrockk.molang.ast.StringExpression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveDouble
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.resolveString
import com.mojang.datafixers.util.Either
import kotlin.jvm.optionals.getOrNull
import net.minecraft.world.entity.LivingEntity
/**
* The issue in a lot of the behaviour datapacking is that there are times when a property should be exposed to
@@ -31,6 +45,50 @@ import kotlin.jvm.optionals.getOrNull
*/
typealias ExpressionOrEntityVariable = Either<Expression, MoLangConfigVariable>
fun ExpressionOrEntityVariable.asExpression() = map({ it }, { "q.entity.config.${it.variableName}".asExpression() })
fun ExpressionOrEntityVariable.resolveString(runtime: MoLangRuntime) = runtime.resolveString(asExpression())
fun ExpressionOrEntityVariable.resolveBoolean(runtime: MoLangRuntime) = runtime.resolveBoolean(asExpression())
fun ExpressionOrEntityVariable.resolveInt(runtime: MoLangRuntime) = runtime.resolveInt(asExpression())
fun ExpressionOrEntityVariable.resolveDouble(runtime: MoLangRuntime) = runtime.resolveDouble(asExpression())
fun ExpressionOrEntityVariable.resolveFloat(runtime: MoLangRuntime) = runtime.resolveFloat(asExpression())
private fun variable(category: String, name: String, type: MoLangConfigVariable.MoLangVariableType, default: String) = MoLangConfigVariable(
variableName = name,
category = lang("entity.variable.category.$category"),
displayName = lang("entity.variable.$name.name"),
description = lang("entity.variable.$name.desc"),
type = type,
defaultValue = default
)
fun stringVariable(category: String, name: String, default: String) = variable(category = category, name = name, type = MoLangConfigVariable.MoLangVariableType.TEXT, default = default)
fun numberVariable(category: String, name: String, default: Number) = variable(category = category, name = name, type = MoLangConfigVariable.MoLangVariableType.NUMBER, default = default.toString())
fun booleanVariable(category: String, name: String, default: Boolean) = variable(category = category, name = name, type = MoLangConfigVariable.MoLangVariableType.BOOLEAN, default = default.toString())
fun getVariableExpression(name: String) = "q.entity.config.$name".asExpression()
fun resolveBooleanVariable(name: String, runtime: MoLangRuntime) = runtime.resolveBoolean(getVariableExpression(name))
fun checkCondition(runtime: MoLangRuntime, expressionOrEntityVariable: ExpressionOrEntityVariable): Boolean {
return expressionOrEntityVariable.resolveBoolean(runtime)
}
fun ExpressionOrEntityVariable.asSimplifiedExpression(entity: LivingEntity): Expression {
return map(
{ it },
{
if (entity is MoLangScriptingEntity) {
val variable = entity.config.map[it.variableName]
if (variable is DoubleValue) {
return@map NumberExpression(variable.value)
} else if (variable is StringValue) {
return@map StringExpression(variable)
}
}
return@map "q.entity.config.${it.variableName}".asExpression()
}
)
}
/**
* In the case of [ExpressionOrEntityVariable] the right side is the only one that requires visibility for a user,
* this function is a shorthand for finding all of the values in the list that have something to show the user to
@@ -0,0 +1,182 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.objective.Objective
import com.cobblemon.mod.common.api.ai.biggerbrain.objective.ObjectiveStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.sense.Sense
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.net.messages.client.debug.UpdateTrackedBrainDataPacket
import com.cobblemon.mod.common.util.getMemorySafely
import com.cobblemon.mod.common.util.getPlayer
import com.cobblemon.mod.common.util.withQueryValue
import java.util.UUID
import kotlin.collections.mutableListOf
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
/**
* A better* version of Minecraft's [net.minecraft.world.entity.ai.Brain] system that makes development more
* straightforward and allows easier debugging.
*
* We could name this thing better.
*
* There are three main principles inside this system:
*
* 1: Senses
*
* Senses are simple ticking objects that are instantiated per entity and are expected to just update memories based
* on properties about the entity or its surroundings. This is an analogue of SensorType from Brains.
*
* 2: Objectives
*
* Objectives are also ticking objects that are instantiated per entity. They represent a goal for the entity and
* run in a fixed order.
*
* 3: Fixations
*
* Fixations are a task that can be set on the brain that represents a more total commitment to a certain task. Only
* a single fixation can be active at a time, and they can be 'distracted' by other objectives or potentially external
* factors.
*
* These can also be debugged using the /debugcobblemonai command while looking at a Pokémon or NPC entity.
*
* *that remains to be seen
*
* @author Hiroku
* @since December 29th, 2025
*/
class BiggerBrain(val entity: LivingEntity) {
val runtime = MoLangRuntime().setup().withQueryValue("entity", entity.asMostSpecificMoLangValue())
val senses = mutableListOf<Sense>()
val objectives = mutableListOf<Objective>()
val observedMemories = mutableMapOf<MemoryModuleType<*>, MutableList<Objective>>()
var fixation: EntityFixation? = null
var debuggingPlayers = mutableSetOf<UUID>()
fun registerObjective(objective: Objective) {
objectives.add(objective)
for (memory in objective.observedMemories) {
val list = this.observedMemories.getOrPut(memory, ::ArrayList)
list.add(objective)
}
}
fun isFixation(fixation: EntityFixation?): Boolean {
return fixation != null && this.fixation == fixation
}
fun sendDebugMessage(message: String) {
debuggingPlayers.forEach {
it.getPlayer()?.sendSystemMessage(message.text())
}
}
fun tick() {
senses.forEach {
it.ticksUntilNextExecution--
if (it.ticksUntilNextExecution <= 0) {
it.tick(entity, this)
}
}
if (fixation?.tick(entity, this) == false) {
fixation = null
}
val objectiveStatuses = mutableMapOf<Objective, ObjectiveStatus>()
val activeObjectiveTags = mutableSetOf<String>()
for (objective in objectives) {
val status = objective.perform(entity, this, activeObjectiveTags)
objectiveStatuses[objective] = status
}
if (debuggingPlayers.isNotEmpty()) {
val state = BiggerBrainState(entity = entity, brain = this, objectiveStatuses = objectiveStatuses)
val packet = UpdateTrackedBrainDataPacket(entity.id, state)
debuggingPlayers.removeIf { uuid ->
val player = uuid.getPlayer()
if (player != null && Cobblemon.serverPlayerDebuggingPokemonBrainEntities[player.uuid] != entity.uuid) {
return@removeIf true
} else {
player?.sendPacket(packet)
}
return@removeIf player == null
}
}
}
fun fixate(fixation: EntityFixation): EntityFixation {
this.fixation = fixation
return fixation
}
fun distract(distraction: Distraction): Boolean {
if (fixation?.canDistract(distraction, entity) != false) {
fixation?.onDistract(distraction, entity)
this.fixation = null
return true
}
return false
}
fun canDistract(distraction: Distraction): Boolean {
return fixation?.canDistract(distraction, entity) != false
}
fun <T> setMemory(memory: MemoryModuleType<T>, value: T, expiry: Long? = null) {
if (expiry != null) {
entity.brain.setMemoryWithExpiry(memory, value, expiry)
} else {
entity.brain.setMemory(memory, value)
}
observedMemories[memory]?.forEach { objective ->
objective.onMemoryChanged(entity, this, memory, value)
}
}
fun <T> setMemoryIfChanged(memory: MemoryModuleType<T>, value: T, expiry: Long? = null) {
if (entity.brain.getMemorySafely(memory).orElse(null) != value) {
setMemory(memory, value, expiry)
}
}
fun <T> eraseMemory(memory: MemoryModuleType<T>) {
entity.brain.eraseMemory(memory)
observedMemories[memory]?.forEach { objective ->
objective.onMemoryChanged(entity, this, memory, null)
}
}
fun <T> eraseMemoryIfPresent(memory: MemoryModuleType<T>) {
if (entity.brain.hasMemoryValue(memory)) {
eraseMemory(memory)
}
}
fun hasMemoryValue(memory: MemoryModuleType<*>): Boolean {
return entity.brain.checkMemory(memory, MemoryStatus.VALUE_PRESENT)
}
fun <T> getMemory(memory: MemoryModuleType<T>): T? {
return entity.brain.getMemorySafely(memory).orElse(null)
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
import com.cobblemon.mod.common.api.ai.biggerbrain.objective.Objective
import com.cobblemon.mod.common.api.ai.biggerbrain.objective.ObjectiveStatus
import kotlin.reflect.jvm.jvmName
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.entity.LivingEntity
/**
* A DTO of sorts that is sent to debugging players to keep them informed about the state of an entity's Cobblemon AI.
*
* @author Hiroku
* @since December 29th, 2025
*/
class BiggerBrainState(
val senses: List<SenseState>,
val objectives: List<ObjectiveState>,
val fixation: String? = null
) {
class SenseState(val className: String, val ticksUntilNextExecution: Int) {
fun encode(buffer: FriendlyByteBuf) {
buffer.writeUtf(className)
buffer.writeInt(ticksUntilNextExecution)
}
companion object {
fun decode(buffer: FriendlyByteBuf): SenseState {
return SenseState(buffer.readUtf(), buffer.readInt())
}
}
}
class ObjectiveState(val description: String, val status: ObjectiveStatus) {
fun encode(buffer: FriendlyByteBuf) {
buffer.writeUtf(description)
buffer.writeEnum(status)
}
companion object {
fun decode(buffer: FriendlyByteBuf): ObjectiveState {
return ObjectiveState(buffer.readUtf(), buffer.readEnum(ObjectiveStatus::class.java))
}
}
}
constructor(entity: LivingEntity, brain: BiggerBrain, objectiveStatuses: Map<Objective, ObjectiveStatus>): this(
senses = brain.senses.map { SenseState(className = it::class.simpleName ?: it::class.jvmName, it.ticksUntilNextExecution) },
objectives = objectiveStatuses.entries.map { ObjectiveState(it.key.getDescription(entity), it.value) },
fixation = brain.fixation?.getDescription(entity)
)
fun encode(buffer: FriendlyByteBuf) {
buffer.writeCollection(senses) { _, sense -> sense.encode(buffer) }
buffer.writeCollection(objectives) { _, objective -> objective.encode(buffer) }
buffer.writeNullable(fixation) { _, fixation -> buffer.writeUtf(fixation) }
}
companion object {
fun decode(buffer: FriendlyByteBuf): BiggerBrainState {
val senses = buffer.readList { SenseState.decode(it) }
val objectives = buffer.readList { ObjectiveState.decode(it) }
val fixation = buffer.readNullable { buffer.readUtf() }
return BiggerBrainState(senses, objectives, fixation)
}
}
}
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
import net.minecraft.world.entity.ai.behavior.EntityTracker
import net.minecraft.world.entity.ai.behavior.PositionTracker
import net.minecraft.world.entity.ai.memory.WalkTarget
/**
* A trivial wrapper around an entity and a position tracker to make the entity look at the position each tick.
*
* @author Hiroku
* @since December 29th, 2025
*/
class LookingTracker(val entity: PathfinderMob, val lookTarget: PositionTracker) {
companion object {
fun forTargetEntity(entity: PathfinderMob, target: LivingEntity, trackEyeHeight: Boolean = true): LookingTracker {
return LookingTracker(entity, EntityTracker(target, trackEyeHeight))
}
fun fromNavigationPathOrWalkTarget(entity: PathfinderMob, walkTarget: WalkTarget): LookingTracker {
val destinationPoint = entity.navigation.path?.endNode?.asVec3() ?: walkTarget.target.currentPosition()
return LookingTracker(entity, BlockPosTracker(destinationPoint.add(0.0, entity.eyeHeight.toDouble(), 0.0)))
}
}
fun tick() {
entity.lookControl.setLookAt(lookTarget.currentPosition())
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
/**
* A simple enum representing the status of a movement action.
*
* @author Hiroku
* @since December 29th, 2025
*/
enum class MovementStatus {
/** Represents when the entity is still en route to the destination. */
PENDING,
/** Represents when the entity has successfully reached the destination. */
COMPLETED,
/**
* Represents when the entity has failed to reach the destination. This can be due to
* a change in surroundings or taking too long or all sorts of things.
*/
FAILED
}
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
import net.minecraft.world.entity.ai.memory.WalkTarget
/**
* A wrapping around logic that maintains an entity's journey towards a specific destination. Mainly used by fixations
* to keep track of when pathing is done, and whether it failed or succeeded. Can also be told to stop to do any
* necessary clean up. Implemented only by [RegularMovementTracker] which has me questioning if it should be an interface
* or just a simple class like the [LookingTracker].
*
* @author Hiroku
* @since December 29th, 2025
*/
interface MovementTracker {
val walkTarget: WalkTarget
/** The last known status of this movement tracker. */
var lastStatus: MovementStatus
/** Performs a tick of movement tracking logic. Returns the current [MovementStatus]. */
fun tick(): MovementStatus
/** Stops the movement and does any necessary clean up. */
fun stop()
}
@@ -0,0 +1,209 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
import com.cobblemon.mod.common.pokemon.ai.OmniPathNodeMaker
import com.cobblemon.mod.common.util.deleteNode
import java.util.function.Predicate
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.EntityTracker
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.entity.ai.util.DefaultRandomPos
import net.minecraft.world.level.pathfinder.Path
import net.minecraft.world.level.pathfinder.PathType
import net.minecraft.world.phys.Vec3
/**
* The default movement tracker used for tracking movement towards a [WalkTarget]. This is pretty much entirely
* just the code for FollowWalkTargetTask from Minecraft brain stuff.
*
* @author Hiroku
* @since December 29th, 2025
*/
class RegularMovementTracker(
val entity: PathfinderMob,
override val walkTarget: WalkTarget
) : MovementTracker {
companion object {
/**
* Attempts to create a tracker for the given entity and target. Returns null if the path
* couldn't be created.
*/
fun attempt(entity: PathfinderMob, walkTarget: WalkTarget): RegularMovementTracker? {
return RegularMovementTracker(entity, walkTarget).takeIf { it.isValid }
}
}
var isValid = false
private set
var started = false
override var lastStatus: MovementStatus = MovementStatus.PENDING
private var path: Path? = null
private var lastKnownTargetPos: BlockPos? = null
init {
val hasReached = hasReached(entity, walkTarget)
if (!hasReached && hasFinishedPath(entity, walkTarget)) {
this.lastKnownTargetPos = walkTarget.target.currentBlockPosition()
isValid = true
} else {
lastStatus = MovementStatus.FAILED
}
}
override fun tick(): MovementStatus {
val path = path
val status = if (path == null || isTargetSpectator(walkTarget)) {
stop(entity)
MovementStatus.FAILED
} else if (hasReached(entity, walkTarget)) {
stop(entity)
MovementStatus.COMPLETED
} else if (started && entity.navigation.isDone) {
stop(entity)
MovementStatus.FAILED
} else {
if (!started) {
startOnPath(entity)
started = true
}
tick(entity)
MovementStatus.PENDING
}
this.lastStatus = status
return status
}
fun startOnPath(entity: PathfinderMob) {
entity.brain.setMemory(MemoryModuleType.PATH, this.path)
entity.navigation.moveTo(this.path, walkTarget.speedModifier.toDouble())
}
override fun stop() {
stop(entity)
}
fun stop(entity: PathfinderMob) {
entity.navigation.stop()
entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET)
entity.brain.eraseMemory(MemoryModuleType.PATH)
}
private fun tick(entity: PathfinderMob) {
val path = entity.navigation.path
if (this.path !== path) {
this.path = path
this.startOnPath(entity)
}
if (path != null && lastKnownTargetPos != null) {
if (walkTarget.target.currentBlockPosition().distSqr(lastKnownTargetPos!!) > 4.0) {
// The target has moved away from where we are pathing, try pathing to its new location
if (hasFinishedPath(entity, walkTarget)) {
lastKnownTargetPos = walkTarget.target.currentBlockPosition()
startOnPath(entity)
} else {
// Uh oh, we can't get closer? Maybe next tick will be better?
}
}
}
}
private fun withNodeFilter(
entity: PathfinderMob,
nodeFilter: Predicate<PathType>,
block: () -> Unit) {
val nodeEvaluator = entity.navigation.nodeEvaluator
if (nodeEvaluator is OmniPathNodeMaker) {
nodeEvaluator.nodeFilter = nodeFilter
block()
nodeEvaluator.nodeFilter = Predicate { true }
} else {
block()
}
}
private fun hasFinishedPath(entity: PathfinderMob, walkTarget: WalkTarget): Boolean {
val blockPos = walkTarget.target.currentBlockPosition()
this.path = generatePath(entity, walkTarget, blockPos)
val hasReached = hasReached(entity, walkTarget)
if (!hasReached && path == null) {
// Desperate attempt to still path to the destination by going somewhere in the vicinity
val vec3d = DefaultRandomPos.getPosTowards(
entity,
10,
7,
Vec3.atBottomCenterOf(blockPos),
Math.PI / 2F
)
if (vec3d != null) {
this.path = generatePath(entity, walkTarget, BlockPos.containing(vec3d))
return this.path != null
}
} else if (!hasReached) {
return true
}
return false
}
private fun generatePath(
entity: PathfinderMob,
walkTarget: WalkTarget,
target: BlockPos
): Path? {
var path: Path? = null
if (walkTarget is CobblemonWalkTarget) {
withNodeFilter(
entity = entity,
nodeFilter = walkTarget.nodeTypeFilter,
) {
var resolvedPath = entity.navigation.createPath(
walkTarget.target.currentBlockPosition(),
0
)
if (resolvedPath != null) {
// A CobblemonWalkTarget may have a destinationNodeTypeFilter, which is used to filter the end node of the path.
// Mainly useful for when the thing setting the target did it a bit crudely or didn't know how far the navigator
// was going to get, and might land on something that is technically traversable by the entity but it doesn't
// fit the intention of the task. Example, a little bird wandering might end up finishing on a flight node,
// but it doesn't really want to fly in place so it'd prefer not ending there.
while (resolvedPath.endNode?.type?.let { walkTarget.destinationNodeTypeFilter(it) } == false) {
resolvedPath.deleteNode(resolvedPath.nodeCount - 1)
}
if (resolvedPath.nodeCount == 0) {
resolvedPath = null
}
}
path = resolvedPath
}
} else {
path = entity.navigation.createPath(target, 0)
}
return path
}
private fun hasReached(entity: PathfinderMob, walkTarget: WalkTarget): Boolean {
return walkTarget.target.currentBlockPosition().distManhattan(entity.blockPosition()) <= walkTarget.closeEnoughDist
}
fun isTargetSpectator(target: WalkTarget): Boolean {
val lookTarget = target.target
return if (lookTarget is EntityTracker) {
lookTarget.entity.isSpectator
} else {
false
}
}
}
@@ -0,0 +1,223 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain
import com.cobblemon.mod.common.api.ai.CobblemonWanderControl.WanderCenter
import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.MAX_LOOK_DOWN_DISTANCE
import com.cobblemon.mod.common.entity.OmniPathingEntity
import com.cobblemon.mod.common.entity.ai.CobblemonRandomSurfacePos
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
import kotlin.math.ceil
import kotlin.math.sqrt
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BehaviorUtils
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.entity.ai.util.HoverRandomPos
import net.minecraft.world.entity.ai.util.LandRandomPos
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathType
/**
* A type of wandering behaviour for an entity. I'm not sure if we keep this.
*
* @author Hiroku
* @since December 29th, 2025
*/
enum class WanderType(
val isValid: (PathfinderMob) -> Boolean,
val choosePosition: (PathfinderMob, minimumHeight: Int, maximumHeight: Int, horizontalRange: Int, verticalRange: Int) -> BlockPos?,
val createWalkTarget: (PathfinderMob, position: BlockPos, avoidsTargetingAir: Boolean, speedMultiplier: Float) -> WalkTarget?,
) {
WATER(
isValid = { it.isInWater },
choosePosition = choosePosition@{ entity, _, _, horizontalRange, verticalRange ->
var pos = BehaviorUtils.getRandomSwimmablePos(entity, horizontalRange, verticalRange)?.let(BlockPos::containing)
?: return@choosePosition null
// Move target pos down so that we don't move out of water too much
val requiredDepth = ceil(0.5 + entity.eyeHeight)
// Get the current depth of the block
var depth = 1
var testPos = pos.above()
var blockState = entity.level().getBlockState(testPos)
while (blockState.fluidState.type == Fluids.WATER) {
depth++
testPos = testPos!!.above()
blockState = entity.level().getBlockState(testPos)
}
if (depth < requiredDepth) {
// Iterate down until we reach the desired min depth or we reach a non water block
pos = pos.below()
blockState = entity.level().getBlockState(pos)
while (blockState.fluidState.type == Fluids.WATER && depth < requiredDepth && pos.y > entity.level().minBuildHeight) {
depth++
pos = pos.below()
blockState = entity.level().getBlockState(pos)
}
}
return@choosePosition if (depth < requiredDepth) null else pos
},
createWalkTarget = { _, pos, _, speedMultiplier ->
CobblemonWalkTarget(
pos = pos,
nodeTypeFilter = { it == PathType.WATER || it == PathType.WATER_BORDER },
speedModifier = speedMultiplier,
completionRange = 0
)
}
),
LAND(
isValid = { entity -> !entity.isInWater && !entity.isInLava },
choosePosition = choosePosition@{ entity, minimumHeight, maximumHeight, horizontalRange, verticalRange ->
val targetVec = when {
maximumHeight != -1 -> {
HoverRandomPos.getPos(
entity,
horizontalRange,
verticalRange,
entity.random.nextFloat() - 0.5,
entity.random.nextFloat() - 0.5,
Math.PI.toFloat(),
maximumHeight,
minimumHeight
)
}
entity.isUnderWater && entity.canBreatheUnderwater() && !((entity as OmniPathingEntity).canSwimInWater()) -> {
BehaviorUtils.getRandomSwimmablePos(
entity,
horizontalRange,
verticalRange
)
}
entity is OmniPathingEntity && (entity.canWalkOnWater() || entity.canWalkOnLava()) -> {
CobblemonRandomSurfacePos.getPos(
entity,
horizontalRange,
verticalRange
)
}
else -> {
LandRandomPos.getPos(
entity,
horizontalRange,
verticalRange
)
}
}
val pos = targetVec?.let(BlockPos::containing) ?: return@choosePosition null
LAND.applyHeightConstraints(pos, minimumHeight, maximumHeight, entity.level() as ServerLevel)
},
createWalkTarget = { entity, pos, avoidsTargetingAir, speedMultiplier ->
CobblemonWalkTarget(
pos = pos,
speedModifier = speedMultiplier,
completionRange = 0,
nodeTypeFilter = { nodeType ->
entity.canBreatheUnderwater() || nodeType !in listOf(
PathType.WATER,
PathType.WATER_BORDER
)
},
destinationNodeTypeFilter = { nodeType ->
!avoidsTargetingAir || nodeType !in listOf(
PathType.OPEN
)
}
)
}
)
;
fun generateWalkTarget(
entity: PathfinderMob,
maxAttempts: Int,
center: WanderCenter?,
minimumHeight: Int,
maximumHeight: Int,
horizontalRange: Int,
verticalRange: Int,
avoidTargetingAir: Boolean,
speedMultiplier: Float
): WalkTarget? {
var attempts = 0
var pos: BlockPos? = null
while (attempts++ < maxAttempts && pos == null) {
pos = choosePosition(entity, minimumHeight, maximumHeight, horizontalRange, verticalRange)
?: return null
if (!isSuitable(center, pos)) {
pos = null
}
}
if (pos == null) {
return null
}
return createWalkTarget(entity, pos, avoidTargetingAir, speedMultiplier)
}
private fun isSuitable(center: WanderCenter?, position: BlockPos): Boolean {
val center = center ?: return true
val centerPos = BlockPos(center.x.toInt(), center.y.toInt(), center.z.toInt())
val distance = sqrt(centerPos.distSqr(position))
val suitable = distance >= center.minRange && distance <= center.maxRange
return suitable
}
private fun applyHeightConstraints(
pos: BlockPos,
minimumHeight: Int,
maximumHeight: Int,
world: ServerLevel
): BlockPos {
if (minimumHeight <= 0 && maximumHeight == -1) {
return pos // It ain't a hoverer
}
val block = world.getBlockState(pos)
val altitude = if (!block.isAir) {
0
} else {
(1..MAX_LOOK_DOWN_DISTANCE).firstOrNull {
val newPos = pos.below(it)
if (!world.getBlockState(newPos).isAir) {
return@firstOrNull true
} else if (newPos.y <= world.minBuildHeight) {
// Don't adjust downward into the void (Mostly if we're in the end)
// This doesn't stop fliers from wandering off end islands,
// but it does stop them from diving directly into the void.
return pos
}
return@firstOrNull false
} ?: MAX_LOOK_DOWN_DISTANCE
}
if (altitude > maximumHeight && maximumHeight >= 0) {
val excess = altitude - maximumHeight
val excessFromMinimum = altitude - minimumHeight
val correction = world.random.nextIntBetweenInclusive(excess, excessFromMinimum)
return pos.atY(pos.y - correction)
} else if (altitude < minimumHeight && minimumHeight >= 0) {
val deficit = minimumHeight - altitude
val deficitFromMaximum = maximumHeight - altitude
val correction = world.random.nextIntBetweenInclusive(deficit, deficitFromMaximum)
return pos.atY(pos.y + correction)
} else {
return pos
}
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.distraction
import net.minecraft.world.damagesource.DamageSource
/**
* Something that may distract an entity from its current fixation. The majority of fixations
* will rely on the types of distraction to determine if they should be distracted.
*
* @author Hiroku
* @since December 29th, 2025
*/
open class Distraction(val types: Set<DistractionType>) {
constructor(vararg types: DistractionType) : this(types.toSet())
val isIdleBoredom = DistractionType.IDLE_BOREDOM in types
val isForce = DistractionType.FORCE in types
val isComfort = DistractionType.COMFORT in types
val isDamage = DistractionType.DAMAGE in types
fun hasAnyOf(vararg distractionTypes: DistractionType): Boolean {
return distractionTypes.any { it in types }
}
companion object {
val FORCE = Distraction(DistractionType.FORCE)
}
}
/** Reusable basic distraction for a COMFORT type of distraction. */
val comfortDistraction = Distraction(DistractionType.COMFORT)
/** Reusable basic distraction for an IDLE_BOREDOM type of distraction. */
val idleBoredomDistraction = Distraction(DistractionType.IDLE_BOREDOM)
open class HurtDistraction(val damageSource: DamageSource) : Distraction(DistractionType.DAMAGE)
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
/**
* A categorisation of distractions that can be attempted on an [EntityFixation].
*
* @author Hiroku
* @since December 29th, 2025
*/
enum class DistractionType {
/** Represents a distraction that the entity is not particularly motivated by but would consider doing out of boredom. */
IDLE_BOREDOM,
/** Represents a distraction that is for the sake of the entity's comfort because it isn't comfortable where it is. */
COMFORT,
/** Represents a distraction motivated by being hurt. */
DAMAGE,
/** A forceful distraction. Just about everything should respect this but it's conceivable that something not. */
FORCE,
}
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import net.minecraft.world.entity.LivingEntity
/**
* A fixation that rejects all non-force distractions and does nothing, lasting until
* the provided [condition] is no longer true.
*
* @author Hiroku
* @since January 16th, 2026
*/
open class ConditionalLockFixation(
val description: String,
val condition: () -> Boolean
): EntityFixation, LockFixation {
override fun canDistract(distraction: Distraction, entity: LivingEntity) = distraction.isForce
override fun getDescription(entity: LivingEntity) = description
override fun tick(entity: LivingEntity, brain: BiggerBrain) = condition()
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import net.minecraft.world.entity.LivingEntity
/**
* A fixation that rejects all non-force distractions and does nothing for some
* number of ticks.
*
* @author Hiroku
* @since January 16th, 2026
*/
open class DurationLockFixation(
val description: String,
var durationTicks: Int
) : EntityFixation, LockFixation {
override fun canDistract(distraction: Distraction, entity: LivingEntity) = distraction.isForce
override fun getDescription(entity: LivingEntity) = description.replace("{ticks}", durationTicks.toString())
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
return --durationTicks > 0
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import net.minecraft.world.entity.LivingEntity
/**
* An entity's fixation, representing a task that takes a central role in the entity's behaviour
* and excludes all other possible fixations.
*
* The role of the fixation is to do an action which is the primary focus of the entity at that time,
* and which may be distracted from under some circumstances. An entity may be fixated on moving from
* A to B, and then be distracted upon being hurt. Or maybe it's an attack fixation, in which case
* damage doesn't distract it at all.
*
* The difference between a fixation and an objective is that objectives are capable of running in parallel,
* and a fixation may even be in the pursuit of an objective, but the fixation is central.
*
* @author Hiroku
* @since December 28th, 2025
*/
interface EntityFixation {
/** Returns true if the given distraction can stop this fixation. */
fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean
/** Notifies the fixation that it has been distracted by the given distraction so it can do clean up. */
fun onDistract(distraction: Distraction, entity: LivingEntity) {}
/** Continues doing whatever the fixation does. Returns true if the fixation should continue. */
fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean
/** Gets a current description of the fixation for the debug screen. */
fun getDescription(entity: LivingEntity): String
}
@@ -0,0 +1,18 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
/**
* Represents a fixation that blocks battling, capture, etc. for Pokémon. This is
* used to control the isBusy property on Pokémon.
*
* @author Hiroku
* @since January 16th, 2026
*/
interface LockFixation
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.DistractionType
import net.minecraft.world.entity.LivingEntity
/**
* A simple fixation that uses both a looking tracker and a movement tracker.
*
* @author Hiroku
* @since December 29th, 2025
*/
open class LookAndMoveFixation(
/** Distraction types that will be respected. */
val distractionTypes: Set<DistractionType>,
/** How to describe the fixation in the debug overlay. */
val description: String,
override val lookingTracker: LookingTracker,
override val movementTracker: MovementTracker,
val onMovementComplete: ((entity: LivingEntity, brain: BiggerBrain) -> Unit)? = null
): EntityFixation, LookingTrackerFixation, MovementTrackerFixation {
override fun getDescription(entity: LivingEntity) = description
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
return distraction.types.any(distractionTypes::contains)
}
override fun onDistract(distraction: Distraction, entity: LivingEntity) {
movementTracker.stop()
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
lookingTracker.tick()
val continueFixation = tickMovementFixation() == MovementStatus.PENDING
if (!continueFixation && onMovementComplete != null) {
onMovementComplete.invoke(entity, brain)
}
return continueFixation
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
/**
* Applied to fixations which may have looking associated with them. This is useful
* in the case that an objective needs to know if the current fixation intends on (or is)
* controlling their looking direction.
*
* Example: An objective that makes Pokémon bob their heads up and down while music is playing.
* Said objective would not warrant a full fixation, but would still like to ensure that the
* current fixation does not intend on using a looking tracker.
*
* @author Hiroku
* @since December 29th, 2025
*/
interface LookingTrackerFixation {
val lookingTracker: LookingTracker?
}
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.fixation
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementTracker
/**
* Applied to fixations which may have movement associated with them. This is useful
* in the case that an objective needs to know if the current fixation intends on (or is)
* controlling their movement.
*
* @author Hiroku
* @since December 29th, 2025
*/
interface MovementTrackerFixation {
/** The movement tracker at the moment. */
val movementTracker: MovementTracker?
/** Ticks the movement tracker in a way that skips finalized movement trackers. */
fun tickMovementFixation(): MovementStatus? {
val movementTracker = this.movementTracker ?: return null
return if (movementTracker.lastStatus != MovementStatus.PENDING) {
movementTracker.lastStatus
} else {
movementTracker.tick()
}
}
}
@@ -0,0 +1,158 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.idleBoredomDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveFloat
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.getMemorySafely
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
/**
* Stops movement and plays a Pokemon's dance animation, if available.
*
*/
class Dance(
val minDuration: Int,
val danceChance: Float
) : Objective {
var fixation: EntityFixation? = null
var remainingCooldownTicks = 0
override fun getDescription(entity: LivingEntity) = "Dancing"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (brain.isFixation(fixation)) {
remainingCooldownTicks = ticksBetweenAttempts
return ObjectiveStatus.FIXATED
} else if (brain.fixation != null) {
fixation = null
}
if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
return ObjectiveStatus.INACTIVE
}
// Only dance if we feel like it
val danceMemory = brain.getMemory(MemoryModuleType.DANCING) ?: false
if (!danceMemory || entity.random.nextFloat() > danceChance || entity.ticksLived < 4 * 20) {
return ObjectiveStatus.INACTIVE
}
if (!brain.distract(idleBoredomDistraction)) {
return ObjectiveStatus.BLOCKED
}
entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET)
entity.navigation.stop()
// Become fixated
fixation = brain.fixate(
DanceFixation(
this,
null,
minDuration
)
)
return ObjectiveStatus.ACTIVE
}
class DanceFixation(
val objective: Dance,
override val movementTracker: MovementTracker?,
val minDuration: Int
) : EntityFixation, MovementTrackerFixation {
var ticksSinceStarted = 0
override fun getDescription(entity: LivingEntity) = "Dancing"
override fun tickMovementFixation() = MovementStatus.PENDING
override fun onDistract(distraction: Distraction, entity: LivingEntity) {
super.onDistract(distraction, entity)
stopDancing(entity)
}
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
if (distraction.isIdleBoredom) {
return false
}
return true
}
fun stopDancing(entity: LivingEntity) {
val pokemon = entity as? PokemonEntity ?: return
pokemon.setBehaviourFlag(PokemonBehaviourFlag.DANCING, false)
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (ticksSinceStarted == 0) { // Makes make me want a Start() for fixations
val pokemon = entity as? PokemonEntity ?: return false
RunPosableMoLangPacket(entity.id, setOf("v.bpm = 100;")).sendToPlayersAround(entity, 64.0)
pokemon.setBehaviourFlag(PokemonBehaviourFlag.DANCING, true)
}
ticksSinceStarted++
if (ticksSinceStarted > minDuration && !entity.brain.getMemorySafely(MemoryModuleType.DANCING).orElse(false)) {
stopDancing(entity)
return false
}
return true
}
}
class Config : ObjectiveConfig {
var danceChance: ExpressionOrEntityVariable = Either.left("1/2".asExpression())
var minDuration: ExpressionOrEntityVariable = Either.left("60".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
minDuration,
danceChance
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
val minDuration = minDuration.resolveInt(behaviourConfigurationContext.runtime)
val danceChance = danceChance.resolveFloat(behaviourConfigurationContext.runtime)
return Dance(
minDuration,
danceChance)
}
}
companion object {
private const val ticksBetweenAttempts = 20
}
}
@@ -0,0 +1,146 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveFloat
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.api.pokemon.feature.FlagSpeciesFeature
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.level.GameRules
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.state.predicate.BlockStatePredicate
/**
* The baa's eat the graa's
*
* @author Hiroku
* @since January 9th, 2025
*/
class EatGrass(
val cooldownTicks: Int,
val eatGrassChance: Float
) : Objective {
var fixation: EntityFixation? = null
val grassPredicate = BlockStatePredicate.forBlock(Blocks.GRASS_BLOCK)
var remainingCooldownTicks = cooldownTicks
override fun getDescription(entity: LivingEntity) = "Eat grass"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (brain.isFixation(fixation)) {
return ObjectiveStatus.FIXATED
} else if (brain.fixation != null) {
return ObjectiveStatus.BLOCKED
} else if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
return ObjectiveStatus.ACTIVE
}
val world = entity.level() as ServerLevel
entity.pokemon.getFeature<FlagSpeciesFeature>(DataKeys.HAS_BEEN_SHEARED)?.enabled?.takeIf { it } ?: run {
return ObjectiveStatus.INACTIVE
}
if (world.random.nextFloat() > eatGrassChance) {
return ObjectiveStatus.ACTIVE
} else {
val blockPos = entity.blockPosition()
// Are we not even on a grass block? Alright don't bother
if (!grassPredicate.test(world.getBlockState(blockPos)) && !world.getBlockState(blockPos.below()).`is`(Blocks.GRASS_BLOCK)) {
return ObjectiveStatus.ACTIVE
}
fixation = brain.fixate(EatGrassFixation(this))
entity.playAnimation("eat")
world.broadcastEntityEvent(entity, 10.toByte())
return ObjectiveStatus.FIXATED
}
}
class EatGrassFixation(val objective: EatGrass) : EntityFixation {
var timer = 40
override fun getDescription(entity: LivingEntity) = "Eating grass"
override fun canDistract(distraction: Distraction, entity: LivingEntity) = distraction.isComfort || distraction.isDamage || distraction.isForce
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
timer--
if (timer <= 0) {
entity as PokemonEntity
val world = entity.level() as ServerLevel
val blockPos = entity.blockPosition()
if (objective.grassPredicate.test(world.getBlockState(blockPos)) ) {
if (world.gameRules.getBoolean(GameRules.RULE_MOBGRIEFING)) {
world.destroyBlock(blockPos, false)
}
entity.ate()
objective.remainingCooldownTicks = objective.cooldownTicks
} else if (world.getBlockState(blockPos.below()).`is`(Blocks.GRASS_BLOCK)) {
val below = blockPos.below()
if (world.gameRules.getBoolean(GameRules.RULE_MOBGRIEFING)) {
world.levelEvent(2001, below, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()))
world.setBlock(below, Blocks.DIRT.defaultBlockState(), 2)
}
entity.ate()
objective.remainingCooldownTicks = objective.cooldownTicks
}
}
return timer > 0
}
}
class Config : ObjectiveConfig {
var cooldownTicks: ExpressionOrEntityVariable = Either.left("400".asExpression())
var eatGrassChance: ExpressionOrEntityVariable = Either.left("1/400".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
cooldownTicks,
eatGrassChance
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective? {
val cooldownTicks = cooldownTicks.resolveInt(behaviourConfigurationContext.runtime)
val eatGrassChance = eatGrassChance.resolveFloat(behaviourConfigurationContext.runtime)
return if (eatGrassChance == 0F) {
null
} else {
EatGrass(
cooldownTicks = cooldownTicks,
eatGrassChance = eatGrassChance
)
}
}
}
}
@@ -0,0 +1,170 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.objective.PickupItem.Companion.dropItem
import com.cobblemon.mod.common.api.ai.biggerbrain.sense.PokemonItemSense.Companion.PICKUP_ITEMS
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.ai.ObtainableItem
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.findMatchingEntry
import com.cobblemon.mod.common.util.getObjectList
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import net.minecraft.core.component.DataComponents
import net.minecraft.core.particles.ItemParticleOption
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.server.level.ServerLevel
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack
/**
* Eat the currently held item, apply the effect, and drop if it's an undesired item
*
* @author JazzMcNade
* @since February 16th, 2026
*/
class EatHeldItem(
val cooldownTicks: Int,
val pickupItems: List<ObtainableItem>
) : Objective {
var fixation: EntityFixation? = null
var remainingCooldownTicks = cooldownTicks
override fun getDescription(entity: LivingEntity) = "Eat Held Item"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (brain.isFixation(fixation)) {
return ObjectiveStatus.FIXATED
} else if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
return ObjectiveStatus.INACTIVE
}
val itemStack: ItemStack = entity.pokemon.heldItem()
if (canEat(itemStack, entity)) {
fixation = brain.fixate(EatHeldItemFixation(this))
remainingCooldownTicks = 120
return ObjectiveStatus.FIXATED
}
return ObjectiveStatus.INACTIVE
}
fun canEat(item: ItemStack, entity: PokemonEntity): Boolean {
return item.has(DataComponents.FOOD) || pickupItems.findMatchingEntry(entity.registryAccess(), item)?.onUseEffect != null
}
class EatHeldItemFixation(val objective: EatHeldItem) : EntityFixation {
var ticksRemaining = 40
override fun getDescription(entity: LivingEntity) = "Eating held item"
override fun canDistract(distraction: Distraction, entity: LivingEntity) = distraction.isComfort || distraction.isDamage || distraction.isForce
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
val world = entity.level()
if (entity is PokemonEntity && entity.isAlive) {
val itemStack: ItemStack = entity.pokemon.heldItem()
val itemConfig = objective.pickupItems.findMatchingEntry(entity.registryAccess(), itemStack)
if (objective.canEat(itemStack, entity)) {
if (ticksRemaining < 0) {
var resultItemStack = itemStack.finishUsingItem(world, entity)
val configuredReturnItem = itemConfig?.returnItem
resultItemStack = if (configuredReturnItem != ItemStack.EMPTY) ItemStack(BuiltInRegistries.ITEM.get(configuredReturnItem))
else if (resultItemStack.item == itemStack.item)
ItemStack.EMPTY // Items that aren't normally edible return themselves
else
resultItemStack
entity.pokemon.swapHeldItem(resultItemStack)
val onUseEffect = itemConfig?.onUseEffect
if (onUseEffect != null) {
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
mainThreadRuntime.resolve(onUseEffect)
}
if (itemConfig != null && itemConfig.fullnessValue > 0) {
entity.pokemon.feedPokemon(itemConfig.fullnessValue, false)
}
// Check if the result item is something that should be dropped
resultItemStack = entity.pokemon.heldItem()
if ((objective.pickupItems.findMatchingEntry(entity.registryAccess(), resultItemStack)?.pickupPriority ?: 0) < 0) {
// Drop item
resultItemStack = entity.pokemon.swapHeldItem(resultItemStack)
if (!resultItemStack.isEmpty && !entity.level().isClientSide) {
dropItem(entity, resultItemStack)
}
}
return false
} else if ((itemConfig?.fullnessValue ?: 0) > 0 && entity.random.nextFloat() < 0.4f) {
ticksRemaining--
entity.playSound(entity.getEatingSound(itemStack), 1.0f, 1.0f)
world.broadcastEntityEvent(entity, 45.toByte())
spawnFoodParticles(entity, itemStack)
}
}
return true
}
return false
}
private fun spawnFoodParticles(entity: LivingEntity, itemStack: ItemStack) {
val serverLevel = entity.level() as ServerLevel
//TODO: Figure out how to this with snowstorm so we can use mouth/face/head locators
// The issue as of this writing is we don't have a clean way to utilize the item texture for the particle in snowstorm
serverLevel.sendParticles(
ItemParticleOption(ParticleTypes.ITEM, itemStack),
entity.x, entity.y + 0.5, entity.z, // particle position (centered on entity)
5, // count
0.1, 0.1, 0.1, // x, y, z offset spread
0.05 // speed
)
}
}
class Config : ObjectiveConfig {
var cooldownTicks: ExpressionOrEntityVariable = Either.left("120".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
cooldownTicks
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective? {
var pickupItems = emptyList<ObtainableItem>()
if (entity is PokemonEntity) {
pickupItems = entity.config.getObjectList<ObtainableItem>(PICKUP_ITEMS)
}
val cooldownTicks = cooldownTicks.resolveInt(behaviourConfigurationContext.runtime)
return EatHeldItem(
cooldownTicks = cooldownTicks,
pickupItems = pickupItems
)
}
}
}
@@ -0,0 +1,244 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.DistractionType
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.HurtDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.LockFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.LookingTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveBoolean
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.api.scheduling.afterOnServer
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.EntityTracker
import net.minecraft.world.entity.ai.memory.MemoryModuleType
/**
* An objective that ensures the entity, whether it's a PokemonEntity or an NPCEntity, will pay attention to its
* opponents in battle. They will not move, and will look at its opponents. For Pokémon, they will focus on the
* targeted opponent if one exists; otherwise, they will randomly look at one of their opponent Pokémon. For NPCs,
* they will randomly look at one of their opponent Pokémon.
*
* If the entity gets hurt and [stopBattleIfHurt] is true, this objective stops the battle.
*
* @author Hiroku
* @since December 29th, 2025
*/
class FocusDuringBattle(
var stopBattleIfHurt: Boolean = true,
var minDurationTicks: Int = 40,
var maxDurationTicks: Int = 80
) : Objective {
var fixation: EntityFixation? = null
override fun getDescription(entity: LivingEntity) = "Look at battle opponents"
override fun perform(entity: LivingEntity, brain: BiggerBrain, activeObjectiveTags: MutableSet<String>): ObjectiveStatus {
if (entity !is NPCEntity && entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
}
if (stopBattleIfHurt && brain.hasMemoryValue(MemoryModuleType.HURT_BY)) {
if (brain.isFixation(fixation)) {
if (entity is PokemonEntity) {
entity.battle?.stop()
} else if (entity is NPCEntity) {
entity.battleIds.mapNotNull { BattleRegistry.getBattle(it) }.forEach { it.stop() }
}
brain.distract(Distraction.FORCE)
}
return ObjectiveStatus.INACTIVE
}
val isInBattle = isInBattle(entity)
if (brain.isFixation(fixation)) {
if (isInBattle) {
// Ok this is fine
return ObjectiveStatus.FIXATED
} else {
// Alright my work here is done, going back to inactive.
fixation = null
brain.fixation = null
return ObjectiveStatus.INACTIVE
}
} else if (!isInBattle) {
// Ok we don't need to do anything
fixation = null
return ObjectiveStatus.INACTIVE
} else {
// We need to start focusing
if (brain.distract(Distraction.FORCE)) {
fixation = if (entity is NPCEntity) NPCFocusFixation(this) else PokemonFocusFixation(this)
// Handle kick starting flight for flying pokemon over water
if (entity is PokemonEntity && entity.exposedForm.behaviour.moving.fly.canFly) {
if (entity.ticksLived >= 0 && entity.navigation.isAirborne(entity.level(), entity.blockPosition())) {
// Let flyers fly in battle if they're in the air
entity.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
afterOnServer(0.1F) {
entity.navigation.moveTo(entity.x, entity.y + 0.2, entity.z, 1.0)
}
}
}
brain.fixation = fixation
return ObjectiveStatus.FIXATED
} else {
return ObjectiveStatus.BLOCKED
}
}
}
override fun <T> onMemoryChanged(entity: LivingEntity, brain: BiggerBrain, memory: MemoryModuleType<T>, value: T?) {
if (brain.isFixation(fixation) && memory == MemoryModuleType.HURT_BY && value != null && stopBattleIfHurt) {
brain.distract(HurtDistraction(value as DamageSource))
}
}
fun isInBattle(entity: LivingEntity): Boolean {
return when (entity) {
is PokemonEntity -> entity.isBattling
is NPCEntity -> entity.isInBattle()
else -> false
}
}
class NPCFocusFixation(val objective: FocusDuringBattle) : EntityFixation, LookingTrackerFixation {
override var lookingTracker: LookingTracker? = null
var ticksUntilReacquireTarget: Int = 0
override fun getDescription(entity: LivingEntity): String {
return if (lookingTracker == null) {
"Looking for an opponent Pokémon to look at"
} else {
"Looking at targeted or opponent Pokémon"
}
}
override fun canDistract(distraction: Distraction, entity: LivingEntity) = distraction.isForce
fun acquireLookTarget(entity: NPCEntity, brain: BiggerBrain) {
val battlingPokemon = brain.getMemory(CobblemonMemories.BATTLING_POKEMON) ?: return
val randomBattlingPokemon = battlingPokemon.randomOrNull()?.let { (entity.level() as ServerLevel).getEntity(it) }
if (randomBattlingPokemon != null) {
lookingTracker = LookingTracker(entity, EntityTracker(randomBattlingPokemon, true))
}
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (entity !is NPCEntity) {
return false
}
val battlingPokemon = brain.getMemory(CobblemonMemories.BATTLING_POKEMON) ?: return false
val lookingTracker = lookingTracker
if (lookingTracker != null && lookingTracker.entity.uuid !in battlingPokemon) {
this.lookingTracker = null
ticksUntilReacquireTarget = 0
}
if (ticksUntilReacquireTarget <= 0) {
acquireLookTarget(entity, brain)
ticksUntilReacquireTarget = (objective.minDurationTicks..objective.maxDurationTicks).random()
} else {
ticksUntilReacquireTarget--
}
lookingTracker?.tick()
return true
}
}
class PokemonFocusFixation(val objective: FocusDuringBattle) : EntityFixation, LookingTrackerFixation, LockFixation {
var ticksUntilReacquireTarget: Int = 0
override var lookingTracker: LookingTracker? = null
override fun getDescription(entity: LivingEntity): String {
return if (lookingTracker == null) {
"Looking for an opponent Pokémon to look at"
} else {
"Looking at targeted or opponent Pokémon"
}
}
override fun canDistract(distraction: Distraction, entity: LivingEntity) = distraction.isForce
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (entity !is PokemonEntity) {
return false
}
val battlingPokemon = brain.getMemory(CobblemonMemories.BATTLING_POKEMON) ?: return false
val targetedBattlePokemon = brain.getMemory(CobblemonMemories.TARGETED_BATTLE_POKEMON)
val lookingTracker = lookingTracker
// If there is a targetedBattlePokemon then that is the highest priority, and we should not look away
// Otherwise, look at one of the entities for a while and occasionally reacquire the target.
if (targetedBattlePokemon != null && (lookingTracker == null || lookingTracker.entity.uuid != targetedBattlePokemon)) {
// We should be targeting the targetedBattlePokemon
val targetedPokemon = (entity.level() as ServerLevel).getEntity(targetedBattlePokemon) ?: return false
this.lookingTracker = LookingTracker(entity, EntityTracker(targetedPokemon, true))
ticksUntilReacquireTarget = (objective.minDurationTicks..objective.maxDurationTicks).random()
} else if (targetedBattlePokemon == null && ticksUntilReacquireTarget <= 0) {
// Choose someone to look at
val randomBattlingPokemon = battlingPokemon.randomOrNull()?.let { (entity.level() as ServerLevel).getEntity(it) }
if (randomBattlingPokemon != null) {
this.lookingTracker = LookingTracker(entity, EntityTracker(randomBattlingPokemon, true))
ticksUntilReacquireTarget = (objective.minDurationTicks..objective.maxDurationTicks).random()
}
}
ticksUntilReacquireTarget--
this.lookingTracker?.tick()
return true
}
}
class Config : ObjectiveConfig {
var stopBattleIfHurt: ExpressionOrEntityVariable = Either.left("true".asExpression())
var minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
var maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
stopBattleIfHurt,
minDurationTicks,
maxDurationTicks
).asVariables()
override fun create(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): Objective {
val stopBattleIfHurt = stopBattleIfHurt.resolveBoolean(behaviourConfigurationContext.runtime)
val minDurationTicks = minDurationTicks.resolveInt(behaviourConfigurationContext.runtime)
val maxDurationTicks = maxDurationTicks.resolveInt(behaviourConfigurationContext.runtime)
return FocusDuringBattle(
stopBattleIfHurt = stopBattleIfHurt,
minDurationTicks = minDurationTicks,
maxDurationTicks = maxDurationTicks
)
}
}
}
@@ -0,0 +1,508 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asSimplifiedExpression
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.RegularMovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.DistractionType
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.comfortDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.idleBoredomDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.LookAndMoveFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.config.task.PollinateFlowerTaskConfig
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.block.SaccharineLeafBlock
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.distanceTo
import com.cobblemon.mod.common.util.getMemorySafely
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.resolveFloat
import com.mojang.datafixers.util.Either
import net.minecraft.core.BlockPos
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.memory.MemoryStatus
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.level.block.BeehiveBlock
import net.minecraft.world.level.block.entity.BeehiveBlockEntity
import net.minecraft.world.phys.Vec3
/**
* Mimics the vanilla bee behavior, with added interactions with Saccharine leaves.
* Only wild bees are allowed to enter hives because of dupe risks with pasture blocks.
*
* @author JazzMcNade
* @since February 23th, 2026
*/
class GatherNectar(
val ticksBetweenAttempts: Int = 60,
val maxDistance: Expression = "14.0".asExpression(),
val speedMultiplier: Expression = "0.2".asExpression()
) : Objective {
var workerFixation: EntityFixation? = null
var shelterFixation: EntityFixation? = null
var remainingCooldownTicks = ticksBetweenAttempts
override fun getDescription(entity: LivingEntity) = "Worker Bee"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (brain.isFixation(shelterFixation)) {
// Never preempt the shelter fixation
remainingCooldownTicks = ticksBetweenAttempts
return ObjectiveStatus.FIXATED
} else if (!entity.biggerBrain.hasMemoryValue(CobblemonMemories.HIVE_LOCATION) && !entity.biggerBrain.hasMemoryValue(CobblemonMemories.NEARBY_SACC_LEAVES)) {
return ObjectiveStatus.INACTIVE
}
val world = entity.level()
if ((world.isRaining || world.isNight) ) {
if (!brain.distract(comfortDistraction)) {
return ObjectiveStatus.BLOCKED
}
// Return to hive or do nothing
if (entity.pokemon.isWild()) {
// Only wilds can path to hives
val hivePos = entity.biggerBrain.getMemory(CobblemonMemories.HIVE_LOCATION)
if (hivePos != null && wantsToEnterHive(entity)) {
// Deliver to hive
if (!tryEnterHive(entity)) { // Attempt to enter the hive, if we fail, probably too far away
val hiveEntrance = getHiveEntrance(hivePos, entity)
if (hiveEntrance != null) {
// Move to hive
shelterFixation = tryMovementFixation(entity, hiveEntrance, "Sheltering in Hive", ::onHiveMovementComplete)
} else {
// Blacklist the hive
dropAndBlackListHive(entity)
}
} // no else the entity is gone and is stored in the hive
}
} else {
return ObjectiveStatus.INACTIVE
}
} else if (brain.isFixation(workerFixation)) {
// Already fixated on the work
remainingCooldownTicks = ticksBetweenAttempts
return ObjectiveStatus.FIXATED
} else {
// Perform nectar gathering/delivery
if (!brain.distract(idleBoredomDistraction)) {
return ObjectiveStatus.BLOCKED
}
if (entity.biggerBrain.hasMemoryValue(CobblemonMemories.HAS_NECTAR) ) {
// Deliver nectar to hive or Sacc leaves
val hivePos = entity.biggerBrain.getMemory(CobblemonMemories.HIVE_LOCATION)
if (hivePos != null && wantsToEnterHive(entity) && entity.pokemon.isWild()) {
// Deliver to hive
if (!tryEnterHive(entity)) { // Attempt to enter the hive, if we fail, probably too far away
val hiveEntrance = getHiveEntrance(hivePos, entity)
if (hiveEntrance != null) {
// Move to hive
workerFixation = tryMovementFixation(entity, hiveEntrance, "Delivering nectar to hive", ::onHiveMovementComplete)
} else {
// Blacklist the hive
dropAndBlackListHive(entity)
}
} // no else the entity is gone and is stored in the hive
} else {
// Deliver to Saccharine Leaves
val sacLeafPos : BlockPos = entity.biggerBrain.getMemory(CobblemonMemories.NEARBY_SACC_LEAVES)
?: return ObjectiveStatus.INACTIVE
if (entity.blockPosition() != sacLeafPos) {
workerFixation = tryMovementFixation(entity, sacLeafPos, "Delivering nectar to Saccharine Leaves")
return ObjectiveStatus.ACTIVE
} else {
// Do nectar deposit fixation
workerFixation = brain.fixate(DepositNectarInSaccharineLeavesFixation())
return ObjectiveStatus.ACTIVE
}
}
} else {
// Gather Nectar
val flowerPos =
entity.biggerBrain.getMemory(CobblemonMemories.NEARBY_FLOWER) ?: return ObjectiveStatus.INACTIVE
val distance = entity.distanceTo(flowerPos)
val maxDistance = mainThreadRuntime.resolveFloat(maxDistance)
if (distance < 1.0) {
// Pollinate/Gather nectar from the flower
if (workerFixation !is PollinateFlowerFixation && brain.distract(idleBoredomDistraction)) {
workerFixation = brain.fixate(PollinateFlowerFixation())
return ObjectiveStatus.FIXATED
}
} else if (distance < maxDistance) {
// Move to the flower
if (remainingCooldownTicks <= 0 && brain.distract(idleBoredomDistraction) && !brain.hasMemoryValue(
CobblemonMemories.PATH_TO_NEARBY_FLOWER_COOLDOWN
)
) {
remainingCooldownTicks = ticksBetweenAttempts
workerFixation = tryMovementFixation(entity, flowerPos, "Moving to flower")
}
}
}
}
if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
}
return ObjectiveStatus.ACTIVE
}
/*
* This Fixation has movement, but it doesn't utilize pathfinding, and it's more about flavor than accomplishing a goal
*
*
*/
class PollinateFlowerFixation(
) : EntityFixation {
var successfulPollinationTicks = 0
var lastSoundPlayedTick = 0
var hoverPos: Vec3? = null
override fun getDescription(entity: LivingEntity) = "Pollinating Flower"
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
return distraction.isDamage || distraction.isForce || distraction.isComfort || entity.brain.hasMemoryValue(
CobblemonMemories.HAS_NECTAR
)
}
override fun onDistract(distraction: Distraction, entity: LivingEntity) {
hoverPos = null
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
}
successfulPollinationTicks = 0
entity.brain.setMemoryWithExpiry(
CobblemonMemories.PATH_TO_NEARBY_FLOWER_COOLDOWN, true,
PollinateFlowerTaskConfig.Companion.PATH_TO_FLOWER_COOLDOWN_TICKS
)
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (entity !is PokemonEntity) return false
val flowerPos = entity.brain.getMemorySafely(CobblemonMemories.NEARBY_FLOWER).orElse(null)
if (!(flowerPos != null && Vec3.atCenterOf(flowerPos).distanceTo(entity.position()) <= 1.0)) {
onStop(entity)
return false
}
++successfulPollinationTicks
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
onStop(entity)
return false
}
if (entity.random.nextFloat() < 0.05f && successfulPollinationTicks > this.lastSoundPlayedTick + 60) {
this.lastSoundPlayedTick = successfulPollinationTicks
entity.playSound(SoundEvents.BEE_POLLINATE, 1.0f, 1.0f)
}
val bl = hoverPos == null || entity.position().distanceTo(hoverPos!!) <= 0.1
val bl3 = entity.random.nextInt(40) == 0
if (bl && bl3) {
// mimics the wriggling over a flower the vanilla bees do
if (hoverPos == null) {
hoverPos = flowerPos.bottomCenter.add(0.0, 0.4, 0.0)
}
hoverPos = flowerPos.bottomCenter.add(
Vec3(
(entity.random.nextDouble() * 2.0 - 1.0) * (1.0 / 5.0),
0.3 + (entity.random.nextDouble() * 2.0 - 1.0) * (1.0 / 7.0),
(entity.random.nextDouble() * 2.0 - 1.0) * (1.0 / 5.0)
)
)
entity.getMoveControl()
.setWantedPosition(hoverPos!!.x(), hoverPos!!.y(), hoverPos!!.z(), 0.35)
entity.lookControl.setLookAt(flowerPos.bottomCenter.add(0.0, 0.5, 0.0))
} else if (!bl) {
entity.getMoveControl()
.setWantedPosition(hoverPos!!.x(), hoverPos!!.y(), hoverPos!!.z(), 0.35)
}
entity.lookControl.setLookAt(flowerPos.bottomCenter.add(0.0, 0.5, 0.0))
return true
}
fun onStop(entity: LivingEntity) {
hoverPos = null
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
}
successfulPollinationTicks = 0
entity.brain.setMemoryWithExpiry(
CobblemonMemories.PATH_TO_NEARBY_FLOWER_COOLDOWN, true,
PATH_TO_FLOWER_COOLDOWN_TICKS
)
}
}
class DepositNectarInSaccharineLeavesFixation() : EntityFixation {
var successfulPollinationTicks = 0
var lastSoundPlayedTick = 0
var hoverPos: Vec3? = null
override fun getDescription(entity: LivingEntity) = "Depositing nectar in Saccharine Leaves"
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
return distraction.isDamage || distraction.isForce || distraction.isComfort || entity.brain.hasMemoryValue(
CobblemonMemories.HAS_NECTAR
)
}
override fun onDistract(distraction: Distraction, entity: LivingEntity) {
hoverPos = null
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
}
successfulPollinationTicks = 0
entity.brain.setMemoryWithExpiry(
CobblemonMemories.PATH_TO_NEARBY_FLOWER_COOLDOWN, true,
PollinateFlowerTaskConfig.Companion.PATH_TO_FLOWER_COOLDOWN_TICKS
)
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (entity !is PokemonEntity) return false
++successfulPollinationTicks
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
val blockPos = brain.getMemory(CobblemonMemories.NEARBY_SACC_LEAVES)
blockPos?.let {
val world = entity.level()
val blockState = world.getBlockState(blockPos)
if (blockState.block == CobblemonBlocks.SACCHARINE_LEAVES) {
val saccAge = blockState.getValue( SaccharineLeafBlock.AGE)
if (saccAge < SaccharineLeafBlock.MAX_AGE) {
brain.eraseMemory(CobblemonMemories.HAS_NECTAR)
val newBlockState = blockState.setValue(SaccharineLeafBlock.AGE, saccAge + 1)
world.setBlock(blockPos, newBlockState, 3)
}
}
}
return false
}
if (entity.random.nextFloat() < 0.05f && successfulPollinationTicks > this.lastSoundPlayedTick + 60) {
this.lastSoundPlayedTick = successfulPollinationTicks
entity.playSound(SoundEvents.BEEHIVE_DRIP, 1.0f, 1.0f)
}
val leavesPos = brain.getMemory(CobblemonMemories.NEARBY_SACC_LEAVES) ?: return false
val bl = hoverPos == null || entity.position().distanceTo(hoverPos!!) <= 0.1
val bl3 = entity.random.nextInt(40) == 0
if (bl && bl3) {
// mimics the wriggling over a flower the vanilla bees do
if (hoverPos == null) {
hoverPos = leavesPos.bottomCenter.add(0.0, 0.4, 0.0)
}
hoverPos = leavesPos.bottomCenter.add(Vec3((entity.random.nextDouble() * 2.0 - 1.0) * (1.0/5.0), 0.3 + (entity.random.nextDouble() * 2.0 - 1.0) * (1.0/7.0), (entity.random.nextDouble() * 2.0 - 1.0) * (1.0/5.0)))
entity.getMoveControl()
.setWantedPosition(hoverPos!!.x(), hoverPos!!.y(), hoverPos!!.z(), 0.35)
entity.lookControl.setLookAt(leavesPos.bottomCenter.add(0.0,0.5,0.0))
} else if (!bl) {
entity.getMoveControl()
.setWantedPosition(hoverPos!!.x(), hoverPos!!.y(), hoverPos!!.z(), 0.35)
}
return true
}
}
class Config : ObjectiveConfig {
val ticksBetweenAttempts: ExpressionOrEntityVariable = Either.left("60".asExpression())
val maxDistance: ExpressionOrEntityVariable = Either.left("10.0".asExpression())
val speedMultiplier: ExpressionOrEntityVariable = Either.left("0.4".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
ticksBetweenAttempts,
maxDistance,
speedMultiplier
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
val ticksBetweenAttempts = ticksBetweenAttempts.resolveInt(behaviourConfigurationContext.runtime)
return GatherNectar(
ticksBetweenAttempts = ticksBetweenAttempts,
maxDistance = maxDistance.asSimplifiedExpression(entity),
speedMultiplier = speedMultiplier.asSimplifiedExpression(entity)
)
}
}
fun onHiveMovementComplete(entity: LivingEntity, brain: BiggerBrain) {
if (entity !is PokemonEntity) return
if(!tryEnterHive(entity)) {
dropAndBlackListHive(entity)
}
}
fun tryMovementFixation(
entity: PokemonEntity,
blockPos: BlockPos,
description : String,
onMovementComplete : ((entity: LivingEntity, brain: BiggerBrain) -> Unit)? = null,
) : EntityFixation? {
val speedMultiplier = mainThreadRuntime.resolveFloat(speedMultiplier)
val movementTracker = RegularMovementTracker.attempt(
entity = entity,
walkTarget = WalkTarget(
blockPos,
speedMultiplier,
0
)
)
if (movementTracker != null) {
val fixation = entity.biggerBrain.fixate(
LookAndMoveFixation(
distractionTypes = setOf(
DistractionType.DAMAGE,
DistractionType.COMFORT,
DistractionType.FORCE
),
lookingTracker = LookingTracker.fromNavigationPathOrWalkTarget(
entity,
movementTracker.walkTarget
),
movementTracker = movementTracker,
description = description,
onMovementComplete = onMovementComplete
)
)
return fixation
}
return null
}
fun getHiveEntrance(hiveLocation: BlockPos, entity: LivingEntity) : BlockPos? {
val sidesByClosest = listOf(
hiveLocation.north(),
hiveLocation.south(),
hiveLocation.east(),
hiveLocation.west()
).sortedBy { it.distSqr(entity.blockPosition()) }
val world = entity.level()
var openSide = BlockPos.ZERO
for (side in sidesByClosest) {
if (world.getBlockState(side).isAir) {
openSide = side
break
}
}
if (openSide == BlockPos.ZERO) {
if (world.getBlockState(hiveLocation.above()).isAir) {
// If the above position is also air, we can use it
openSide = hiveLocation.above() // Fallback to above if no open sides found
} else if (world.getBlockState(hiveLocation.below()).isAir) {
// If the below position is also air, we can use it
openSide = hiveLocation.below() // Fallback to below if no open sides found
} else {
// If no open sides or above/below positions are found, we cannot proceed
return null
}
}
return openSide
}
fun tryEnterHive(entity: LivingEntity): Boolean {
if (entity !is PokemonEntity || !wantsToEnterHive(entity)) {
return false
}
val hiveLocation = entity.biggerBrain.getMemory(CobblemonMemories.HIVE_LOCATION) ?: return false
val targetVec = Vec3.atCenterOf(hiveLocation)
// if we are not close to it then end early
if (entity.distanceToSqr(targetVec) > 1.6 * 1.6) {
return false
}
val state = entity.level().getBlockState(hiveLocation)
val block = state.block
if (block is BeehiveBlock) {
val blockEntity = entity.level().getBlockEntity(hiveLocation)
if (blockEntity !is BeehiveBlockEntity) return false
if (blockEntity.isFull) {
// Erase Hive memory and give the bee a moment to locate a new hive
dropAndBlackListHive(entity)
} else {
blockEntity.addOccupant(entity)
return true
}
}
return false
}
fun wantsToEnterHive(entity: LivingEntity): Boolean {
val result = !entity.brain.checkMemory(CobblemonMemories.HIVE_COOLDOWN, MemoryStatus.VALUE_PRESENT)
&& (entity.level().isRaining || entity.level().isNight || entity.brain.getMemory(CobblemonMemories.HAS_NECTAR)
.orElse(false))
if (result) {
val blockPos = entity.brain.getMemorySafely(CobblemonMemories.HIVE_LOCATION).orElse(null)
val blockEntity = entity.level().getBlockEntity(blockPos)
return blockEntity is BeehiveBlockEntity && !blockEntity.isFireNearby
}
return false
}
fun dropAndBlackListHive(entity: PokemonEntity) {
val hivePos = entity.biggerBrain.getMemory(CobblemonMemories.HIVE_LOCATION)
if (hivePos == null) return
val blackList : MutableList<BlockPos> = entity.biggerBrain.getMemory(CobblemonMemories.HIVE_BLACKLIST)?.toMutableList() ?: emptyList<BlockPos>().toMutableList()
blackList.add(hivePos)
if (blackList.count() > 3) {
blackList.removeFirst()
}
entity.brain.eraseMemory(CobblemonMemories.HIVE_LOCATION)
entity.brain.setMemory(CobblemonMemories.HIVE_BLACKLIST, blackList)
}
companion object {
const val PATH_TO_FLOWER_COOLDOWN_TICKS: Long = 200
const val HAS_NECTAR_ASPECT = "has_nectar"
const val MIN_DURATION: Int = 300
const val MAX_DURATION: Int = 400
const val REQUIRED_SUCCESSFUL_POLLINATION_TICKS = 250
}
}
@@ -0,0 +1,155 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonActivities
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asSimplifiedExpression
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.status.PersistentStatusContainer
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.getMemorySafely
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.resolveBoolean
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
/**
* Randomly looks at nearby entities out of curiosity. Very easily distracted once doing so.
*
* @author Hiroku
* @since December 29th, 2025
*/
class GoToSleep(
val onlyFromStatus: Expression = "false".asExpression(),
) : Objective {
var fixation: EntityFixation? = null
override fun getDescription(entity: LivingEntity) = "Sleeping"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (brain.isFixation(fixation)) {
return ObjectiveStatus.FIXATED
} else if (brain.fixation != null) {
fixation = null
return ObjectiveStatus.BLOCKED
}
// Don't sleep if we're not tired
brain.getMemory(CobblemonMemories.POKEMON_DROWSY)
?: return ObjectiveStatus.INACTIVE
val hasSleepStatus = entity.pokemon.status?.status === Statuses.SLEEP
if (entity.behaviour.resting.canSleep && entity.canSleepAt(entity.blockPosition().below()) || hasSleepStatus) {
if (!hasSleepStatus) {
if (mainThreadRuntime.resolveBoolean(onlyFromStatus)) {
return ObjectiveStatus.BLOCKED
}
entity.pokemon.status = PersistentStatusContainer(Statuses.SLEEP)
}
entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET)
entity.navigation.stop()
entity.brain.setActiveActivityToFirstValid(listOf(CobblemonActivities.POKEMON_SLEEPING_ACTIVITY))
entity.brain.setMemory(CobblemonMemories.POKEMON_SLEEPING, true)
// Become fixated
fixation = brain.fixate(
SleepFixation(
this,
null
)
)
return ObjectiveStatus.FIXATED
}
return ObjectiveStatus.BLOCKED
}
class SleepFixation(
val objective: GoToSleep,
override val movementTracker: MovementTracker?,
) : EntityFixation, MovementTrackerFixation {
override fun getDescription(entity: LivingEntity): String {
return "Sleeping"
}
override fun tickMovementFixation(): MovementStatus? {
return MovementStatus.PENDING
}
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
if (distraction.isIdleBoredom) {
return false
}
wakeUp(entity)
return true
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (!entity.brain.getMemorySafely(CobblemonMemories.POKEMON_DROWSY).orElse(false)) {
wakeUp(entity)
return false
}
return true
}
fun wakeUp(entity: LivingEntity) {
if (entity !is PokemonEntity) return
val hasSleepStatus = entity.pokemon.status?.status == Statuses.SLEEP
if (hasSleepStatus && entity.pokemon.storeCoordinates.get()?.store is PartyStore) {
return // You can't wake up if you're in the party with the sleep status.
}
if (hasSleepStatus) {
entity.pokemon.status = null
}
entity.brain.eraseMemory(CobblemonMemories.POKEMON_SLEEPING)
entity.brain.useDefaultActivity()
}
}
class Config : ObjectiveConfig {
val onlyFromStatus: ExpressionOrEntityVariable = Either.left("false".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
onlyFromStatus
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
return GoToSleep(
onlyFromStatus = onlyFromStatus.asSimplifiedExpression(entity)
)
}
}
}
@@ -0,0 +1,204 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asSimplifiedExpression
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.RegularMovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.idleBoredomDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.LookingTrackerFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.distanceTo
import com.cobblemon.mod.common.util.getMemorySafely
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.GameRules
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.CaveVines
import net.minecraft.world.level.block.SweetBerryBushBlock
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.gameevent.GameEvent
/**
* Paths to ripened sweet berry bushes AND glowberry vines with berries.
* Upon reaching the target harvests the berries and stashes one in its
* held item slot if possible.
* Requires NEARBY_SWEET_BERRY_BUSH memory
*
* @author JazzMcNade
* @since February 8th, 2026
*/
class HarvestSweetBerryBush(
val ticksBetweenAttempts: Int = 60,
val maxDistance: Expression = "14.0".asExpression(),
val speedMultiplier: Expression = "0.4".asExpression()
) : Objective {
var harvestTask: EntityFixation? = null
var remainingCooldownTicks = ticksBetweenAttempts
override fun getDescription(entity: LivingEntity) = "Harvesting sweet/glow berry"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (brain.isFixation(harvestTask)) {
remainingCooldownTicks = ticksBetweenAttempts
return ObjectiveStatus.FIXATED
}
val berryPosition = entity.biggerBrain.getMemory(CobblemonMemories.NEARBY_SWEET_BERRY_BUSH) ?: return ObjectiveStatus.INACTIVE
if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
return ObjectiveStatus.ACTIVE
}
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val maxDistance = mainThreadRuntime.resolveFloat(maxDistance)
val speedMultiplier = mainThreadRuntime.resolveFloat(speedMultiplier)
val distance = entity.distanceTo(berryPosition)
if (distance < maxDistance) {
if (remainingCooldownTicks <= 0 && brain.distract(idleBoredomDistraction)) {
remainingCooldownTicks = ticksBetweenAttempts
val movementTracker = RegularMovementTracker.attempt(
entity = entity,
walkTarget = WalkTarget(
berryPosition,
speedMultiplier,
1
)
)
if (movementTracker != null) {
harvestTask = brain.fixate(
fixation = HarvestSweetBerryBushFixation(
entity = entity,
movementTracker = movementTracker
)
)
}
}
}
return ObjectiveStatus.ACTIVE
}
class HarvestSweetBerryBushFixation(
entity: PathfinderMob,
override val movementTracker: MovementTracker,
): EntityFixation, LookingTrackerFixation, MovementTrackerFixation {
override val lookingTracker: LookingTracker = LookingTracker(entity = entity, lookTarget = movementTracker.walkTarget.target)
override fun getDescription(entity: LivingEntity) = "Harvesting sweet/glow berry"
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
return distraction.isDamage || distraction.isForce || (movementTracker.lastStatus == MovementStatus.COMPLETED && entity.brain.getMemorySafely(
CobblemonMemories.NEARBY_SWEET_BERRY_BUSH).orElse(null) != null)
}
override fun onDistract(distraction: Distraction, entity: LivingEntity) {
movementTracker.stop()
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
lookingTracker.tick()
movementTracker.tick()
if (movementTracker.lastStatus == MovementStatus.COMPLETED) {
val world = entity.level()
if (entity !is PokemonEntity) return false
if (!world.gameRules.getRule(GameRules.RULE_MOBGRIEFING).get()) {
// Not allowed to alter the world
return false
}
val blockPos = entity.brain.getMemory(CobblemonMemories.NEARBY_SWEET_BERRY_BUSH).orElse(null) ?: return false
val blockState = world.getBlockState(blockPos)
if (CaveVines.hasGlowBerries(blockState)) { // Glow Berries Case
CaveVines.use(entity, blockState, world, blockPos)
} else if (blockState.`is`(Blocks.SWEET_BERRY_BUSH)) { // Sweet Berries Case
blockState.setValue(SweetBerryBushBlock.AGE, 1)
var j: Int = 1 + entity.level().random.nextInt(2) + if (blockState.getValue<Int>(SweetBerryBushBlock.AGE) == 3) 1 else 0
val itemStack: ItemStack = entity.pokemon.heldItem
if (itemStack.isEmpty) {
entity.pokemon.swapHeldItem(ItemStack(Items.SWEET_BERRIES))
--j
}
if (j > 0) {
Block.popResource(entity.level(), blockPos, ItemStack(Items.SWEET_BERRIES, j))
}
entity.playSound(SoundEvents.SWEET_BERRY_BUSH_PICK_BERRIES, 1.0f, 1.0f)
entity.level().setBlock(blockPos, blockState.setValue(SweetBerryBushBlock.AGE, 1) as BlockState, 2)
entity.level().gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(entity))
}
entity.brain.eraseMemory(CobblemonMemories.NEARBY_SWEET_BERRY_BUSH)
return false
} else if (movementTracker.lastStatus == MovementStatus.FAILED) {
// Cannot reach, give up for a awhile
entity.brain.setMemoryWithExpiry(CobblemonMemories.DISABLE_WALK_TO_BERRY_BUSH, true, 200)
entity.brain.eraseMemory(CobblemonMemories.NEARBY_SWEET_BERRY_BUSH)
return false
}
return true
}
}
class Config : ObjectiveConfig {
val ticksBetweenAttempts: ExpressionOrEntityVariable = Either.left("60".asExpression())
val maxDistance: ExpressionOrEntityVariable = Either.left("10.0".asExpression())
val speedMultiplier: ExpressionOrEntityVariable = Either.left("0.4".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
ticksBetweenAttempts,
maxDistance,
speedMultiplier
).asVariables()
override fun create(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): Objective {
val ticksBetweenAttempts = ticksBetweenAttempts.resolveInt(behaviourConfigurationContext.runtime)
return HarvestSweetBerryBush(
ticksBetweenAttempts = ticksBetweenAttempts,
maxDistance = maxDistance.asSimplifiedExpression(entity),
speedMultiplier = speedMultiplier.asSimplifiedExpression(entity)
)
}
}
}
@@ -0,0 +1,409 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.CobblemonWanderControl
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementStatus
import com.cobblemon.mod.common.api.ai.biggerbrain.RegularMovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.DistractionType
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.comfortDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.LookAndMoveFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveFloat
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonMoveControl
import com.cobblemon.mod.common.pokemon.ai.ToleratedHerdLeader
import com.cobblemon.mod.common.pokemon.status.PersistentStatusContainer
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.toBlockPos
import com.mojang.datafixers.util.Either
import java.util.UUID
import kotlin.math.cos
import kotlin.math.sin
import net.minecraft.server.level.ServerLevel
import net.minecraft.util.Mth
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.phys.Vec3
class Herd(
var checkTicks: Int = 60,
var tooFar: Float = 8F,
var closeEnough: Float = 4F,
/** Chance per tick of following the herd leader. */
val chance: Float = 1 / 60F,
val pathingCooldownTicks: Int = 80
) : Objective {
var wanderCenter: CobblemonWanderControl.WanderCenter? = null
var fixation: EntityFixation? = null
var leader: PokemonEntity? = null
var ticksUntilMaintainLeader: Int = checkTicks
var remainingPathingCooldownTicks = 0
override fun getDescription(entity: LivingEntity) = "Herd"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
entity as PokemonEntity
val moveControl = entity.moveControl as? PokemonMoveControl ?: return ObjectiveStatus.INVALID
if (remainingPathingCooldownTicks > 0) {
remainingPathingCooldownTicks--
}
val level = entity.level() as ServerLevel
if (leader == null && brain.hasMemoryValue(CobblemonMemories.HERD_LEADER)) {
leader = level.getEntity(brain.getMemory(CobblemonMemories.HERD_LEADER).let(UUID::fromString)) as? PokemonEntity
if (leader == null) {
brain.eraseMemory(CobblemonMemories.HERD_LEADER)
}
}
if (ticksUntilMaintainLeader > 0) {
ticksUntilMaintainLeader--
} else if (ticksUntilMaintainLeader == 0) {
if (brain.fixation == null || brain.isFixation(fixation)) {
// Don't maintain the herd leader if we're busy with something else
maintainHerdLeader(entity, brain)
}
ticksUntilMaintainLeader = checkTicks
}
if (leader?.level() != level) {
this.leader = null
}
val leader = leader
if (leader == null && brain.isFixation(fixation)) {
brain.distract(Distraction.FORCE)
}
val wanderControl = brain.getMemory(CobblemonMemories.WANDER_CONTROL)
?: CobblemonWanderControl()
if (this.wanderCenter != null && leader == null) {
if (wanderControl.center == this.wanderCenter) {
wanderControl.center = null
wanderControl.wanderChanceMultiplier = null
brain.setMemory(CobblemonMemories.WANDER_CONTROL, wanderControl)
}
this.wanderCenter = null
} else if (leader != null) {
wanderControl.center = CobblemonWanderControl.WanderCenter(
x = leader.x,
y = leader.y,
z = leader.z,
minRange = 1F,
maxRange = tooFar
)
this.wanderCenter = wanderControl.center
wanderControl.wanderChanceMultiplier = 0.25F
brain.setMemory(CobblemonMemories.WANDER_CONTROL, wanderControl)
}
leader ?: return ObjectiveStatus.INACTIVE
if (brain.isFixation(fixation) && fixation is MovementTrackerFixation) {
return ObjectiveStatus.FIXATED
}
val leaderFixation = leader.biggerBrain.fixation
val canMove = brain.canDistract(comfortDistraction) || brain.isFixation(fixation)
val isMovingCloser = brain.isFixation(fixation) && fixation is LookAndMoveFixation
val leaderMoveControl = leader.moveControl as? PokemonMoveControl ?: return ObjectiveStatus.INVALID
if (leader.distanceTo(entity) > tooFar) {
return when {
isMovingCloser -> ObjectiveStatus.FIXATED // Already have the fixation to move closer
remainingPathingCooldownTicks > 0 -> manageFixation(brain) // Still cooling down from last pathing attempt
!canMove -> ObjectiveStatus.BLOCKED // I'm not able to distract the brain and move closer
else -> tryMovingCloser(entity, brain, level, leader) // let's give it a fair shake then
}
} else if (leader.isFlying() && !entity.isFlying() && !isMovingCloser) {
if (!entity.canFly()) {
entity.brain.eraseMemory(CobblemonMemories.HERD_LEADER) // We can't go where this guy's going
this.leader = null
return ObjectiveStatus.INACTIVE
} else if (!canMove) {
return ObjectiveStatus.BLOCKED
}
return tryMovingCloser(entity, brain, level, leader)
} else if (leaderMoveControl.banking && !isMovingCloser) {
if (!canMove) {
return ObjectiveStatus.BLOCKED
}
if (leader.isInLiquid && !entity.isInLiquid) {
if (remainingPathingCooldownTicks > 0) {
return manageFixation(brain) // Still cooling down from last pathing attempt
}
// We should get into water asap so we can mimic the banking
return tryMovingCloser(entity, brain, level, leader, completionRange = 1)
} else {
removeSleep(entity, brain)
entity.yRot = leader.yRot
moveControl.startBanking(
forwardBlocksPerTick = leaderMoveControl.bankForwardBlocksPerTick,
upwardsBlocksPerTick = leaderMoveControl.bankUpwardsBlocksPerTick,
durationTicks = 2,
rightDegreesPerTick = 0F // Relying on the above yRot = leader.yRot because we dunno when we first started mimicking the banking
)
return ObjectiveStatus.FIXATED
}
} else if (leaderFixation is MovementTrackerFixation && leaderFixation.movementTracker?.lastStatus == MovementStatus.PENDING) {
if (entity.random.nextFloat() > chance) {
return manageFixation(brain) // Not this tick
} else if (!canMove) {
return ObjectiveStatus.BLOCKED
} else if (isMovingCloser) {
return ObjectiveStatus.FIXATED // Already moving
}
val leaderWalkTarget = leaderFixation.movementTracker?.walkTarget ?: return manageFixation(brain)
// We're already closer to the walk target than the leader is, so no need to move. If anything we should get out of the way
if (entity.distanceToSqr(leaderWalkTarget.target.currentPosition()) + closeEnough < leader.distanceToSqr(leaderWalkTarget.target.currentPosition())) {
return manageFixation(brain)
}
// Go to the leader's walk target, roughly.
val walkTarget = CobblemonWalkTarget(
pos = leaderWalkTarget.target.currentPosition().add(getRandomOffset(entity, level)).toBlockPos(),
speedModifier = leaderWalkTarget.speedModifier,
nodeTypeFilter = (leaderWalkTarget as? CobblemonWalkTarget)?.nodeTypeFilter ?: { true },
completionRange = closeEnough.toInt()
)
return tryMovingCloser(entity, brain, level, leader, walkTarget = walkTarget)
} else if (leader.getCurrentPoseType() == PoseType.SLEEP) {
// Leader is sleeping, if I'm drowsy and can sleep here then I will sleep too.
if (entity.canSleepAt(entity.blockPosition().offset(0, -1, 0)) && brain.getMemory(CobblemonMemories.POKEMON_DROWSY) == true) {
if (entity.random.nextFloat() < 1 / 40F) {
applySleep(entity, brain)
}
}
} else if (brain.getMemory(CobblemonMemories.POKEMON_SLEEPING) == true) {
// Leader is awake, so we should be awake too. Maybe.
if (entity.random.nextFloat() < 1 / 15F) {
removeSleep(entity, brain)
}
}
return manageFixation(brain)
}
fun manageFixation(brain: BiggerBrain): ObjectiveStatus {
if (brain.isFixation(fixation)) {
return ObjectiveStatus.FIXATED
} else if (leader != null) {
return ObjectiveStatus.ACTIVE
} else {
return ObjectiveStatus.INACTIVE
}
}
fun tryMovingCloser(
entity: PokemonEntity,
brain: BiggerBrain,
level: ServerLevel,
leader: PokemonEntity,
walkTarget: WalkTarget? = null,
completionRange: Int = closeEnough.toInt()
): ObjectiveStatus {
val walkTarget = walkTarget ?: CobblemonWalkTarget(
pos = leader.position().add(getRandomOffset(entity, level)).toBlockPos(),
speedModifier = 0.4F,
completionRange = completionRange
)
val movementTracker = RegularMovementTracker.attempt(entity, walkTarget)
remainingPathingCooldownTicks = pathingCooldownTicks
if (movementTracker == null) {
// Couldn't find a path, wait a bit before trying again
return manageFixation(brain)
} else if (!(brain.isFixation(fixation) && brain.distract(Distraction.FORCE)) && !brain.distract(comfortDistraction)) {
return manageFixation(brain) // Not likely based on checks run on callers to this function.
}
brain.sendDebugMessage("Moving closer, to ${movementTracker.walkTarget.target.currentBlockPosition()}")
removeSleep(entity, brain)
fixation = brain.fixate(
LookAndMoveFixation(
distractionTypes = setOf(DistractionType.DAMAGE, DistractionType.COMFORT, DistractionType.FORCE),
lookingTracker = LookingTracker.forTargetEntity(entity, leader, trackEyeHeight = true),
movementTracker = movementTracker,
description = "Moving towards herd leader"
)
)
return ObjectiveStatus.FIXATED
}
fun maintainHerdLeader(entity: PokemonEntity, brain: BiggerBrain) {
val world = entity.level() as ServerLevel
val leader = brain.getMemory(CobblemonMemories.HERD_LEADER)?.let(UUID::fromString).let(world::getEntity) as? PokemonEntity
val currentLeaderDefinition = leader?.let { leader ->
entity.behaviour.herd.toleratedLeaders.find { it.pokemon.matches(leader) }
}
if (leader == null || currentLeaderDefinition == null) {
entity.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
this.leader = null
}
val bestLeader = getBestHerdLeader(
currentLeader = if (leader == null || currentLeaderDefinition == null) null else (leader to currentLeaderDefinition),
nearbyEntities = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES) ?: return,
entity = entity
)
if (bestLeader != null && bestLeader != leader) {
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
entity.brain.setMemory(CobblemonMemories.HERD_LEADER, bestLeader.uuid.toString())
bestLeader.adjustHerdSize(1)
leader?.adjustHerdSize(-1)
this.leader = bestLeader
}
}
fun getRandomOffset(entity: PokemonEntity, level: ServerLevel): Vec3 {
val leader = leader ?: return Vec3.ZERO
val minRange = closeEnough.toDouble()
val maxRange = (tooFar - closeEnough / 2).toDouble()
val randomDistance = Mth.nextDouble(level.random, minRange, maxRange)
val randomAngle = Mth.nextDouble(level.random, 0.0, 2 * Math.PI)
var offset = Vec3(cos(randomAngle) * randomDistance, 0.0, sin(randomAngle) * randomDistance)
if ((entity.isInLiquid && leader.isInLiquid) || (entity.isFlying() && leader.isFlying())) {
val verticalRange = randomDistance * 0.5
val randomY = Mth.nextDouble(level.random, -verticalRange, verticalRange)
offset = offset.add(0.0, randomY, 0.0)
}
return offset
}
fun applySleep(entity: PokemonEntity, brain: BiggerBrain) {
brain.setMemory(CobblemonMemories.POKEMON_SLEEPING, true)
entity.pokemon.status = PersistentStatusContainer(Statuses.SLEEP)
}
fun removeSleep(entity: PokemonEntity, brain: BiggerBrain) {
if (brain.hasMemoryValue(CobblemonMemories.POKEMON_SLEEPING)) {
brain.eraseMemory(CobblemonMemories.POKEMON_SLEEPING)
val status = entity.pokemon.status
if (status != null && status.status == Statuses.SLEEP) {
entity.pokemon.status = null
}
}
}
/**
* Logic used to choose the best herd leader from nearby visible entities.
*
* - Higher tier leaders are always preferred.
* - Same-tier leaders that are closer are preferred except for when they're the same tier as the current leader.
* - We don't want to exceed the target's herd size limit.
* - We don't want to choose a leader that is themselves following a leader.
* - Some leader definitions allow lower-level Pokémon to lead them.
* - Leaders just have to not be in a party - pastured and wild Pokémon can mingle.
*/
fun getBestHerdLeader(
currentLeader: Pair<PokemonEntity, ToleratedHerdLeader>?,
nearbyEntities: NearestVisibleLivingEntities,
entity: PokemonEntity,
): PokemonEntity? {
var bestLeader: PokemonEntity? = null
val (currentLeaderEntity, currentLeaderDefinition) = currentLeader ?: Pair(null, null)
var bestTier = currentLeaderDefinition?.tier?.let { it + 1 } ?: 0 // Only upgrade to a higher tier leader
var bestDistance = Float.MAX_VALUE
nearbyEntities.findAll {
it is PokemonEntity &&
it != currentLeader &&
it.pokemon.storeCoordinates.get()?.store !is PartyStore &&
it.getHerdSize() < it.behaviour.herd.maxSize &&
!it.brain.hasMemoryValue(CobblemonMemories.POKEMON_DROWSY)
}.forEach { possibleLeader ->
possibleLeader as PokemonEntity
val bestMatchingHerdLeader = entity.behaviour.herd.bestMatchLeader(entity, possibleLeader) ?: return@forEach
val possibleLeaderIsAlreadyALeader = possibleLeader.brain.hasMemoryValue(CobblemonMemories.HERD_SIZE)
val currentLeaderHerdTier = currentLeaderEntity?.getHerdTier() ?: entity.getHerdTier()
if (currentLeaderHerdTier >= bestMatchingHerdLeader.tier) {
return@forEach // This leader is following a leader of a higher tier, we can't replace them
}
val distance = entity.distanceTo(possibleLeader)
if (bestMatchingHerdLeader.tier < bestTier) {
return@forEach // No need to check further if this leader is worse than the best found so far
} else if ((distance > bestDistance && !possibleLeaderIsAlreadyALeader) && bestMatchingHerdLeader.tier == bestTier) {
return@forEach // No need to check further if this leader is farther than the best found so far, unless they are already a leader - I'd prefer to join a pack
} else {
bestLeader = possibleLeader
bestDistance = distance
bestTier = bestMatchingHerdLeader.tier
}
}
return bestLeader ?: currentLeaderEntity
}
class Config : ObjectiveConfig {
// How frequently to check for whether it should herd. Probably isn't that expensive but might use this for chance.
val checkTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
val tooFar: ExpressionOrEntityVariable = Either.left("8".asExpression())
val closeEnough: ExpressionOrEntityVariable = Either.left("4".asExpression())
val chance: ExpressionOrEntityVariable = Either.left("1 / 60".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(checkTicks, tooFar, closeEnough, chance).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
behaviourConfigurationContext.addMemories(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)
behaviourConfigurationContext.addMemories(CobblemonMemories.HERD_LEADER)
behaviourConfigurationContext.addMemories(CobblemonMemories.HERD_SIZE)
return Herd(
checkTicks = checkTicks.resolveInt(behaviourConfigurationContext.runtime),
tooFar = tooFar.resolveFloat(behaviourConfigurationContext.runtime),
closeEnough = closeEnough.resolveFloat(behaviourConfigurationContext.runtime),
chance = chance.resolveFloat(behaviourConfigurationContext.runtime)
)
}
}
}
@@ -0,0 +1,166 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.MovementTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.idleBoredomDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import net.minecraft.core.BlockPos
import net.minecraft.sounds.SoundEvents
import net.minecraft.tags.FluidTags
import net.minecraft.util.Mth
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.level.material.FluidState
import kotlin.math.atan2
/**
* Swimming Pokemon perform a cool little jump out of the water if they're near the surface
*
*/
class JumpOutOfWater(
val ticksBetweenAttempts: Int = 60,
) : Objective {
var inWater = false
var remainingCooldownTicks = ticksBetweenAttempts
var fixation: EntityFixation? = null
override fun getDescription(entity: LivingEntity) = "Jump out of water"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is PokemonEntity) {
return ObjectiveStatus.INVALID
} else if (brain.isFixation(fixation)) {
remainingCooldownTicks = ticksBetweenAttempts
return ObjectiveStatus.FIXATED
}
if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
return ObjectiveStatus.ACTIVE
}
if (entity.random.nextInt(CHANCE) != 0) {
return ObjectiveStatus.INACTIVE
} else {
if (!brain.distract(idleBoredomDistraction)) return ObjectiveStatus.BLOCKED
val direction = entity.motionDirection
val x = direction.stepX
val z = direction.stepZ
val blockPos = entity.blockPosition()
val offsets = OFFSET_MULTIPLIERS
for (offset in offsets) {
if (!this.isWater(entity, blockPos, x, z, offset) || !this.isAirAbove(entity, blockPos, x, z, offset)) {
return ObjectiveStatus.ACTIVE
}
}
val newVelocity = entity.deltaMovement.add(direction.stepX.toDouble() * 0.6, 0.7, direction.stepZ.toDouble() * 0.6)
entity.deltaMovement = newVelocity
entity.getNavigation().stop()
fixation = brain.fixate(
fixation = JumpOutOfWaterFixation(
this,
movementTracker = null
)
)
}
return ObjectiveStatus.ACTIVE
}
class JumpOutOfWaterFixation(
val objective: JumpOutOfWater,
override val movementTracker: MovementTracker?,
) : EntityFixation, MovementTrackerFixation {
override fun getDescription(entity: LivingEntity) = "Jumping out of water"
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
return distraction.isDamage || distraction.isForce
}
override fun onDistract(distraction: Distraction, entity: LivingEntity) {}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
val bl: Boolean = objective.inWater
if (!bl) {
val fluidState: FluidState = entity.level().getFluidState(entity.blockPosition())
objective.inWater = fluidState.`is`(FluidTags.WATER)
}
if (objective.inWater && !bl) {
// Transition tick from in water to out of water
entity.playSound(SoundEvents.DOLPHIN_JUMP, 1.0f, 1.0f)
}
val vec3d = entity.deltaMovement
if (vec3d.y * vec3d.y < 0.029999999329447746 && entity.xRot != 0.0f) {
entity.xRot = Mth.rotLerp(0.2f, entity.xRot, 0.0f)
} else if (vec3d.length() > 9.999999747378752E-6) {
val d = vec3d.horizontalDistance()
val e = atan2(-vec3d.y, d) * 57.2957763671875
entity.xRot = e.toFloat()
}
val d: Double = vec3d.y
return (!(d * d < 0.029999999329447746) || entity.xRot == 0.0f || !(Math.abs(entity.xRot) < 10.0f) || !entity.isInWater) && !entity.onGround()
}
}
class Config : ObjectiveConfig {
val ticksBetweenAttempts: ExpressionOrEntityVariable = Either.left("60".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
ticksBetweenAttempts,
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
val ticksBetweenAttempts = ticksBetweenAttempts.resolveInt(behaviourConfigurationContext.runtime)
return JumpOutOfWater(
ticksBetweenAttempts = ticksBetweenAttempts,
)
}
}
private fun isWater(entity: PokemonEntity, pos: BlockPos, offsetX: Int, offsetZ: Int, multiplier: Int): Boolean {
val blockPos = pos.offset(offsetX * multiplier, 0, offsetZ * multiplier)
return entity.level().getFluidState(blockPos).`is`(FluidTags.WATER) && !entity.level().getBlockState(blockPos)
.blocksMotion()
}
private fun isAirAbove(entity: PokemonEntity, pos: BlockPos, offsetX: Int, offsetZ: Int, multiplier: Int): Boolean {
return entity.level().getBlockState(pos.offset(offsetX * multiplier, 1, offsetZ * multiplier))
.isAir && entity.level().getBlockState(pos.offset(offsetX * multiplier, 2, offsetZ * multiplier))
.isAir
}
companion object {
private const val CHANCE = 10
private val OFFSET_MULTIPLIERS = intArrayOf(0, 1, 4, 5, 6, 7)
}
}
@@ -0,0 +1,136 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.LookingTracker
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.LookingTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.ai.resolveDouble
import com.cobblemon.mod.common.api.ai.resolveInt
import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import kotlin.math.pow
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.EntityTracker
import net.minecraft.world.entity.ai.memory.MemoryModuleType
/**
* Randomly looks at nearby entities out of curiosity. Very easily distracted once doing so.
*
* @author Hiroku
* @since December 29th, 2025
*/
class LookAtNearbyEntities(
val maxDistance: Double = 10.0,
val minDuration: Int = 20,
val maxDuration: Int = 80
) : Objective {
var fixation: EntityFixation? = null
override fun getDescription(entity: LivingEntity) = "Look at nearby entities"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (brain.isFixation(fixation)) {
return ObjectiveStatus.FIXATED
} else if (brain.fixation != null) {
fixation = null
return ObjectiveStatus.BLOCKED
}
val nearestVisibleLivingEntities = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)
?: return ObjectiveStatus.INVALID
val closest = nearestVisibleLivingEntities.findClosest(
{ otherEntity -> otherEntity.distanceToSqr(entity) <= maxDistance.pow(2) && !entity.hasPassenger(otherEntity) }
).orElse(null)
if (closest == null) {
return ObjectiveStatus.INACTIVE
} else {
// Become fixated
fixation = brain.fixate(
IdleLookFixation(
this,
closest,
(minDuration..maxDuration).random()
)
)
return ObjectiveStatus.FIXATED
}
}
class IdleLookFixation(
val objective: LookAtNearbyEntities,
val targetEntity: LivingEntity,
var remainingTicks: Int
) : EntityFixation, LookingTrackerFixation {
override var lookingTracker: LookingTracker? = null
override fun getDescription(entity: LivingEntity): String {
return "Looking at a nearby entity ($remainingTicks ticks left)"
}
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
// Bro literally anything will distract me
return true
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
if (targetEntity.isRemoved || entity !is PathfinderMob) {
return false
}
if (lookingTracker == null) {
lookingTracker = LookingTracker(entity, EntityTracker(targetEntity, true))
}
val lookingTracker = lookingTracker!!
remainingTicks--
lookingTracker.tick()
return remainingTicks > 0
}
}
class Config : ObjectiveConfig {
val maxDistance: ExpressionOrEntityVariable = Either.left("10.0".asExpression())
val minDuration: ExpressionOrEntityVariable = Either.left("20".asExpression())
val maxDuration: ExpressionOrEntityVariable = Either.left("80".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
maxDistance,
minDuration,
maxDuration
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
val maxDistance = maxDistance.resolveDouble(behaviourConfigurationContext.runtime)
val minDuration = minDuration.resolveInt(behaviourConfigurationContext.runtime)
val maxDuration = maxDuration.resolveInt(behaviourConfigurationContext.runtime)
return LookAtNearbyEntities(
maxDistance = maxDistance,
minDuration = minDuration,
maxDuration = maxDuration
)
}
}
}
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.biggerbrain.BiggerBrain
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.OmniPathingEntity
import net.minecraft.world.entity.LivingEntity
class MaintainFluidY : Objective {
override fun getDescription(entity: LivingEntity) = "Maintain Y in fluids"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is OmniPathingEntity) {
return ObjectiveStatus.INVALID
}
val fixation = brain.fixation
if (fixation is MovementTrackerFixation) {
return ObjectiveStatus.BLOCKED
}
if (entity.isFlying()) {
return ObjectiveStatus.INACTIVE
}
if (entity.canSwimInWater() && entity.isUnderWater) {
entity.isNoGravity = true
} else if (entity.canSwimInLava() && entity.isInLava) {
entity.isNoGravity = true
} else {
entity.isNoGravity = false
}
return if (entity.isNoGravity) ObjectiveStatus.ACTIVE else ObjectiveStatus.INACTIVE
}
class Config : ObjectiveConfig {
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): List<MoLangConfigVariable> {
return emptyList()
}
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
return MaintainFluidY()
}
}
}
@@ -0,0 +1,251 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.biggerbrain.objective
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.*
import com.cobblemon.mod.common.api.ai.biggerbrain.*
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.Distraction
import com.cobblemon.mod.common.api.ai.biggerbrain.distraction.comfortDistraction
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.EntityFixation
import com.cobblemon.mod.common.api.ai.biggerbrain.fixation.MovementTrackerFixation
import com.cobblemon.mod.common.api.ai.config.objective.ObjectiveConfig
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
import com.cobblemon.mod.common.util.*
import com.mojang.datafixers.util.Either
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.TamableAnimal
import net.minecraft.world.entity.ai.behavior.BehaviorUtils
import net.minecraft.world.entity.ai.util.RandomPos
import net.minecraft.world.level.pathfinder.PathType
import net.minecraft.world.phys.Vec3
/**
* Tries to path into water if the entity usually avoids land.
* Will pathfind through land even if the entity usually filters out land nodes.
* If water cannot be found in the entity's wander range it'll wander randomly in a spiral-ish pattern
*
* @author JazzMcNade
* @since January 25th, 2026
*/
class MoveIntoWater(
val ticksBetweenAttempts: Int = 60,
val maxDistance: Expression = "14.0".asExpression(),
val speedMultiplier: Expression = "0.4".asExpression()
) : Objective {
var movementTask: EntityFixation? = null
var remainingCooldownTicks = ticksBetweenAttempts
var wanderDirection: Vec3? = null
var isWanderTurnDirectionClockwise = true
var wanderTurnChance = BASE_TURN_CHANCE
var failCount = 0
override fun getDescription(entity: LivingEntity) = "Move into water if currently out of water"
override fun perform(
entity: LivingEntity,
brain: BiggerBrain,
activeObjectiveTags: MutableSet<String>
): ObjectiveStatus {
if (entity !is TamableAnimal) {
return ObjectiveStatus.INVALID
}
if (entity.isInWater) {
// All good, nothing to do here
return ObjectiveStatus.INACTIVE
}
if (brain.isFixation(movementTask)) {
remainingCooldownTicks = ticksBetweenAttempts
return ObjectiveStatus.FIXATED
}
if (remainingCooldownTicks > 0) {
remainingCooldownTicks--
return ObjectiveStatus.INACTIVE
} else {
remainingCooldownTicks = ticksBetweenAttempts
}
if (brain.distract(comfortDistraction)) {
val maxDistance = mainThreadRuntime.resolveInt(maxDistance)
val speedMultiplier = mainThreadRuntime.resolveFloat(speedMultiplier)
val runtime = mainThreadRuntime
val wanderControl = entity.brain.getMemorySafely(CobblemonMemories.WANDER_CONTROL).orElse(null)
val allowLand = wanderControl?.allowLand
?: runtime.resolveBoolean("(q.entity.behaviour.moving.walk.can_walk && q.entity.behaviour.moving.walk.avoids_land) || q.entity.behaviour.moving.fly.can_fly".asExpression())
val allowAir = wanderControl?.allowAir
?: runtime.resolveBoolean("q.entity.behaviour.moving.fly.can_fly && !q.entity.behaviour.moving.walk.can_walk".asExpression())
val types = mutableSetOf<WanderType>()
if ((allowLand || allowAir)) {
types.add(WanderType.WATER)
}
if (types.isEmpty()) {
return ObjectiveStatus.INACTIVE
}
var walkTarget: CobblemonWalkTarget? = null
val targetVec3 = BehaviorUtils.getRandomSwimmablePos(entity, 10, 7)
if (targetVec3 != null) {
walkTarget = CobblemonWalkTarget(
BlockPos.containing(targetVec3.x, targetVec3.y, targetVec3.z),
speedMultiplier,
0,
nodeTypeFilter = { nodeType ->
true
}
)
}
if (walkTarget == null) {
if (failCount >= 5) {
// No out of water target could be found.
// Need to choose a direction and move as far as possible, hoping we randomly find water
// Totally possible that a shoreline is *just* outside the entity's wander range and
// we choose a direction that's opposite of the shoreline
// To counteract this, the pokemon moves in a (very roughly) spiral pattern outward from the origin
var wanderPosition: BlockPos? = null
if (wanderDirection == null) {
val wanderOffset = RandomPos.generateRandomDirection(entity.level().random, maxDistance / 2, 0)
wanderDirection = wanderOffset.toVec3d().normalize()
isWanderTurnDirectionClockwise = entity.random.nextInt(2) > 0
wanderTurnChance = BASE_TURN_CHANCE
wanderPosition = entity.blockPosition().offset(wanderOffset.x, wanderOffset.y, wanderOffset.z)
} else {
if (entity.level().random.nextFloat() < wanderTurnChance) {
// Turn 30 degrees
wanderDirection =
wanderDirection!!.yRot(Math.PI.toFloat() / 3.0f * if (isWanderTurnDirectionClockwise) -1f else 1f)
wanderTurnChance *= 0.7
}
val wanderVec = entity.position().add(wanderDirection!!.scale(maxDistance.toDouble()))
wanderPosition = BlockPos.containing(wanderVec)
}
val wanderTarget = generateWaterSafePosToward(entity, maxDistance, wanderPosition)
if (wanderTarget != null) {
walkTarget = CobblemonWalkTarget(
wanderPosition,
speedMultiplier,
0,
nodeTypeFilter = { nodeType ->
true
}
)
} else {
return ObjectiveStatus.ACTIVE
}
} else {
failCount++
}
}
if (walkTarget != null) {
failCount = 0
val movementTracker = RegularMovementTracker.attempt(entity, walkTarget)
?: return ObjectiveStatus.ACTIVE
brain.distract(comfortDistraction)
movementTask = brain.fixate(
fixation = MoveIntoWaterFixation(
movementTracker = movementTracker
)
)
}
}
return ObjectiveStatus.ACTIVE
}
fun generateWaterSafePosToward(
mob: PathfinderMob,
range: Int,
targetPos: BlockPos
): BlockPos? {
for (i in 0..4) {
val candidate: BlockPos? = RandomPos.generateRandomPosTowardDirection(
mob,
range,
mob.level().random,
targetPos
)
if (candidate == null) continue
val pathType = mob.navigation.nodeEvaluator.getPathType(mob, candidate)
// Don't actually care if it can be reached, only if it's not hazardous
if (pathType == PathType.WALKABLE || mob.getPathfindingMalus(pathType) <= 0)
return candidate
}
return null
}
companion object {
val BASE_TURN_CHANCE = 0.8
}
class MoveIntoWaterFixation(
override val movementTracker: MovementTracker,
) : EntityFixation, MovementTrackerFixation {
override fun getDescription(entity: LivingEntity) = "Moving into water"
override fun canDistract(distraction: Distraction, entity: LivingEntity): Boolean {
return distraction.isDamage || distraction.isForce || movementTracker.lastStatus == MovementStatus.COMPLETED
}
override fun onDistract(distraction: Distraction, entity: LivingEntity) {
movementTracker.stop()
}
override fun tick(entity: LivingEntity, brain: BiggerBrain): Boolean {
val movementStatus = tickMovementFixation()
if (movementStatus == MovementStatus.COMPLETED) return false
if (!entity.isInWater) {
return false
}
return movementStatus != MovementStatus.FAILED
}
}
class Config : ObjectiveConfig {
val ticksBetweenAttempts: ExpressionOrEntityVariable = Either.left("60".asExpression())
val maxDistance: ExpressionOrEntityVariable = Either.left("10.0".asExpression())
val speedMultiplier: ExpressionOrEntityVariable = Either.left("0.4".asExpression())
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = listOf(
ticksBetweenAttempts,
maxDistance,
speedMultiplier
).asVariables()
override fun create(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): Objective {
val ticksBetweenAttempts = ticksBetweenAttempts.resolveInt(behaviourConfigurationContext.runtime)
return MoveIntoWater(
ticksBetweenAttempts = ticksBetweenAttempts,
maxDistance = maxDistance.asSimplifiedExpression(entity),
speedMultiplier = speedMultiplier.asSimplifiedExpression(entity)
)
}
}
}

Some files were not shown because too many files have changed in this diff Show More