Compare commits

..
Author SHA1 Message Date
Paul bf50570ade Toying with data reload for species data, current issue is render thread needs species data (shouldn't it be concmodding sometimes) 2024-10-13 07:26:06 +10:00
Paul 8951816ddd Delay deserialization of Pokemon S2C codec until it's in the handler for SetPCPokemonPacket, SetPCBoxPokemonPacket, SetPartyPokemonPacket 2024-10-12 18:18:32 +10:00
Paul bc668d84c9 Fixed advancement display of pokemon renders, closes #976 2024-10-12 16:59:48 +10:00
MiaandWeblate b1290cbc38 Translated using Weblate (German)
Currently translated at 87.5% (5579 of 6375 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-12 02:00:08 +00:00
Paul 2261cf1077 Conflicto fixo 2024-10-12 11:55:50 +10:00
Paul 0ae427fd14 Fixed NPC pokemon still dropping items on faint 2024-10-12 10:18:47 +10:00
Paul 37a25c6b5a Fixed applyplayertexture not working on NPCs that delegate to standard but are not standard 2024-10-12 09:12:24 +10:00
MiaandWeblate 597080aac2 Translated using Weblate (German)
Currently translated at 87.4% (5578 of 6375 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2024-10-11 21:41:28 +00:00
Paul 2ae2d9f53b Initialize NPCs at level 1 by default from /spawnnpc 2024-10-11 20:23:46 +10:00
Paul 38df6f4833 Fixed deserialization of custom_script NPC interactions 2024-10-11 19:51:11 +10:00
Paul bed2e3035b Added /spawnnpc and /spawnnpcat commands 2024-10-11 16:33:39 +10:00
Paul a784aa38cb Lang update 2024-10-11 16:09:46 +10:00
Hiroku c18d853a55 Merge branch 'fuck-assets' into 'main'
move best spawner config & showdown data to resources/data

See merge request cable-mc/cobblemon!1191
2024-10-10 20:45:29 +00:00
Xander Forrest d6581e9931 try with resources block when copying from stream 2024-10-11 00:14:47 +07:00
Nick d7962e7d48 Merge branch 'feature/more-bugs-fixed' into 'main'
more smaller bugs fixed (neoforge users rejoice)

Closes #1068, #1072, and #1073

See merge request cable-mc/cobblemon!1192
2024-10-10 16:57:59 +00:00
PolymetaandNick f3f6a9744b more smaller bugs fixed (neoforge users rejoice) 2024-10-10 16:57:59 +00:00
Nick 715112f8d9 Merge branch 'feature/shinies' into 'main'
Shiny Pokémon Particles and Sound Effects! ✨✨✨💖

See merge request cable-mc/cobblemon!1183
2024-10-10 16:52:39 +00:00
TyzillionandNick 278d0d6f96 Shiny Pokémon Particles and Sound Effects! ✨✨✨💖 2024-10-10 16:52:39 +00:00
Xander Forrest 95c26448bc move best-spawner-config & showdown zip/metadata to resources/data instead of assets, where they should not be
add FileUtils.copyInternalToExternal to move things from internal to, you guessed it, external paths.
2024-10-10 17:20:12 +07:00
Hiroku 8d99ebbcde Merge branch 'feature/bug-galore' into 'main'
various bug fixes

Closes #994, #1037, #1057, #1060, #1070, and #420

See merge request cable-mc/cobblemon!1188
2024-10-10 10:09:19 +00:00
PolymetaandHiroku 4c024ac947 various bug fixes 2024-10-10 10:09:19 +00:00
Hiroku b4946e13f2 Merge branch 'misc' into 'main'
add Upper Hand name/description

See merge request cable-mc/cobblemon!1190
2024-10-10 09:25:16 +00:00
Xander Forrest bc4af40a34 remove gb specific move name 2024-10-10 16:24:21 +07:00
Xander Forrest 64ecec1a9a add Upper Hand name/description 2024-10-10 16:10:05 +07:00
Hiroku 7f8ef38b64 Merge branch 'clone' into 'main'
regen tethering ID as well as UUID in Pokemon.clone()

See merge request cable-mc/cobblemon!1189
2024-10-10 08:52:19 +00:00
Hiroku e4360ca9b5 Play animation sound keyframes through the entity where possible, the way Arceus intended 2024-10-10 08:47:09 +00:00
Xander Forrest bc27ec7288 remove tethering id not randomly generate 2024-10-10 15:44:41 +07:00
Xander Forrest 875f2d99ab regen tethering ID as well as UUID in Pokemon.clone() 2024-10-10 14:24:05 +07:00
Hiroku a4d18eba89 Merge branch 'sound' into 'main'
Sound bugfix and small volume tweaks

Closes #1069

See merge request cable-mc/cobblemon!1187
2024-10-07 06:36:58 +00:00
Sterrezo edffc248f4 Small volume tweaks to Pokedex sounds 2024-10-07 08:29:51 +02:00
Sterrezo 600bbfc5f3 Prevented the zoom sound from playing when unable to increase or decrease zoom further 2024-10-07 08:28:40 +02:00
Hiroku 692f1de510 Merge branch 'Updating-Structures-to-1.21' into 'main'
1.21.1 structure fixes

See merge request cable-mc/cobblemon!1184
2024-10-06 20:55:42 +00:00
Polymeta e230dd740d Merge branch 'refs/heads/main' into Updating-Structures-to-1.21
# Conflicts:
#	common/src/main/resources/data/minecraft/worldgen/template_pool/village/desert/houses.json
#	common/src/main/resources/data/minecraft/worldgen/template_pool/village/plains/houses.json
#	common/src/main/resources/data/minecraft/worldgen/template_pool/village/savanna/houses.json
#	common/src/main/resources/data/minecraft/worldgen/template_pool/village/snowy/houses.json
#	common/src/main/resources/data/minecraft/worldgen/template_pool/village/taiga/houses.json
2024-10-06 20:46:40 +01:00
Hiroku e24008c89e Merge branch 'keybind-shmebind' into 'main'
Remove PokedexBinding.kt and references.

See merge request cable-mc/cobblemon!1185
2024-10-06 02:48:08 +00:00
Hiroku ed29801820 Merge branch 'feature/pokedex-sync-fixes' into 'main'
fix pokedex sync and other issues

Closes #1000, #1041, and #1051

See merge request cable-mc/cobblemon!1186
2024-10-06 02:47:53 +00:00
Polymeta a5fe51b8fa various pokedex fixes
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-10-06 03:37:46 +01:00
Hiroku 600cc48073 Merge branch 'slated' into 'main'
Added Missing Recipe

Closes #1033

See merge request cable-mc/cobblemon!1180
2024-10-06 00:08:09 +00:00
JPAKx4 a4aa8f3778 Remove PokedexBinding.kt and references. 2024-10-05 14:38:21 -05:00
Slippy 2f16490aa8 Hopefully this fixed village centers from not having loot and generating very uncommonly 2024-10-04 23:06:11 -05:00
Hiroku ed82a72919 Merge branch 'unblank_descriptions' into 'main'
Fix scrolling issue in InfoTextScrollWidget.kt

Closes #1023

See merge request cable-mc/cobblemon!1182
2024-10-05 03:29:48 +00:00
JPAKx4 953163b12e Fix scrolling issue in InfoTextScrollWidget.kt 2024-10-04 22:20:26 -05:00
Test aa57cd7e3e prevent cry animation stacking on button click 2024-10-04 22:32:48 -04:00
dhi_holo 863baa5ae6 Added Missing Recipe
Resolves #1033
2024-09-30 18:34:32 +10:00
Hiroku 913ca3d467 Merge branch 'sound' into 'main'
Tweaked evolution sound logic

See merge request cable-mc/cobblemon!1179
2024-09-29 08:44:30 +00:00
Sterrezo 22b541af10 Tweaked evolution sound logic
Added a click sound to the evolve widget. Evolution ui sound now plays only when evolving from the ui, not with the Pokemon sent out.
2024-09-29 10:43:28 +02:00
Hiroku c1a706ca69 Merge branch 'scan-fixes' into 'main'
scan and dex fixes

See merge request cable-mc/cobblemon!1178
2024-09-29 02:42:23 +00:00
TestandHiroku 47f8647d48 scan and dex fixes 2024-09-29 02:42:22 +00:00
Hiroku a0e01b9652 Merge branch '#1013-immortal-pokemon' into 'main'
Fixes Pokemon being immortal after breaking free from capture

Closes #1013

See merge request cable-mc/cobblemon!1177
2024-09-28 04:23:40 +00:00
Deltric 9d88fb7ca2 Resets beam mode to 0 after a Pokemon is finished breaking free from capture. Prevents them from staying immortal. 2024-09-27 22:49:32 -05:00
Paul ca0170f1ed Several camera mode fixes, fixing several move effects. Closes #1010 2024-09-28 11:36:45 +10:00
Paul 050f7e6161 Added property on PokemonEntity to toggle pose type recalculation 2024-09-27 12:20:57 +10:00
Paul 658ec95e6b Fixed pressing E for a nickname closing the GUI, closes #1006 2024-09-27 11:28:57 +10:00
Hiroku 883f8149da Merge branch 'BattleBugStomping' into 'main'
BattleBugStomping Bugaloo

See merge request cable-mc/cobblemon!1167
2024-09-27 00:06:53 +00:00
Hiroku e5e4871c96 Merge branch 'feature/bugfixes' into 'main'
small fixes

Closes #1001 and #999

See merge request cable-mc/cobblemon!1176
2024-09-27 00:05:34 +00:00
JazzMcNade e074411596 Cleaned up Revival Blessing logic 2024-09-26 01:53:51 -05:00
JazzMcNade adf0ba7c9f Merge branch 'main' into BattleBugStomping 2024-09-26 01:22:11 -05:00
JazzMcNade 3d8c22fd68 Fixed client sync issues with triple battle's auto shift to center. 2024-09-26 00:18:03 -05:00
Polymeta a966f0f9a6 dont reset state with empty state causing the loss of aspects
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-25 23:32:01 +01:00
Polymeta da74990909 only rotate collection when leading pokemon is passed in to preserve original party order
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-25 22:43:00 +01:00
JazzMcNade 0e3102f5e4 Fixed a bug in which not having enough pokemon to fill all fainted slots would cause a soft lock. Fixed Revival Blessing. 2024-09-25 00:45:41 -05:00
Nick 36e3816bf3 Merge branch 'feature/pokemon-debug-utils' into 'main'
debug galore for pokemon

See merge request cable-mc/cobblemon!1175
2024-09-24 23:05:41 +00:00
PolymetaandNick 99e47e4cb7 debug galore for pokemon 2024-09-24 23:05:41 +00:00
Nick aa875b06ab Merge branch 'feature/form-dfu' into 'main'
introduce feature DFU to prevent loss of forms and other features when migrating from 1.20

Closes #993 and #541

See merge request cable-mc/cobblemon!1174
2024-09-24 17:24:29 +00:00
PolymetaandNick dfb08c8db0 introduce feature DFU to prevent loss of forms and other features when migrating from 1.20 2024-09-24 17:24:29 +00:00
Nick eefff036b7 Merge branch 'more-npcs' into 'main'
Many NPC improvements for foundation

See merge request cable-mc/cobblemon!1171
2024-09-23 23:02:00 +00:00
HirokuandNick 43050b4276 Many NPC improvements for foundation 2024-09-23 23:02:00 +00:00
Nick b1b8c6e9db Merge branch 'bugfix/fix-for-slippy' into 'main'
Fixed Jigsaw structure maximums

See merge request cable-mc/cobblemon!1173
2024-09-23 22:06:16 +00:00
Paul 583a973e53 Fixed Jigsaw structure maximums 2024-09-23 15:51:58 +10:00
Hiroku c0b945e3da Merge branch 'parchment' into 'main'
Added parchment mappings for param names

See merge request cable-mc/cobblemon!1172
2024-09-23 02:10:44 +00:00
apion fa73fb8e46 Added parchment mappings for param names 2024-09-22 22:00:49 -04:00
Hiroku 1fd9128b33 Merge branch 'DoubledPokeballSendOutParticlesFix' into 'main'
DoubledPokeballSendOutParticlesFix

See merge request cable-mc/cobblemon!1169
2024-09-23 00:34:43 +00:00
Hiroku f9799ef55e Merge branch 'feature/small-tweaks' into 'main'
remove redundant tracker and hardcode battle ui navigation to leftclick

Closes #992

See merge request cable-mc/cobblemon!1170
2024-09-22 21:25:15 +00:00
PolymetaandHiroku ab69c4f095 remove redundant tracker and hardcode battle ui navigation to leftclick 2024-09-22 21:25:15 +00:00
JazzMcNade a9a0fff643 PokemonClientDelagate now checks if beammode 1 in currently in progress before applying its effects. 2024-09-22 12:27:11 -05:00
Apion 9bdb8102c1 Merge branch 'bugfix/1-6-fixes' into 'main'
Dex variation definitions for many pokes, show all pose types in dex

See merge request cable-mc/cobblemon!1168
2024-09-21 23:01:33 +00:00
HirokuandApion febcb7092a Dex variation definitions for many pokes, show all pose types in dex 2024-09-21 23:01:33 +00:00
Apion 4ec8b01efb Merge branch 'feature/jarring-changes' into 'main'
JarInJar fabric kotlin instead of shadowing kotlin libs to avoid compatibility issues

Closes #933

See merge request cable-mc/cobblemon!1161
2024-09-21 22:44:42 +00:00
PolymetaandApion 95b15d50c3 JarInJar fabric kotlin instead of shadowing kotlin libs to avoid compatibility issues 2024-09-21 22:44:42 +00:00
JazzMcNade 88d7b38a90 Cleaned up math 2024-09-21 17:44:21 -05:00
Apion 471eef6c31 Merge branch 'SinglesSendoutAdjustments' into 'main'
SinglesSendoutAdjustments

See merge request cable-mc/cobblemon!1166
2024-09-21 22:40:15 +00:00
JazzMcNadeandApion 513910e448 SinglesSendoutAdjustments 2024-09-21 22:40:15 +00:00
JazzMcNade 528f1d68b9 Fixed bug in which a fainted pokemon could be sent out in multibattles. Fixed actor display test when the first slot is fainted. Fixed timings of gui items now that the BattleOverlay tick speed has been fixed. 2024-09-21 17:32:36 -05:00
apion 1613250f5d Add method for in PlatformRegistry for sidemod usage 2024-09-21 18:27:14 -04:00
Hiroku f8a2802a8e Merge branch 'feature/sneaky-label' into 'main'
Tweak pokemon label display and additional config setting

See merge request cable-mc/cobblemon!1164
2024-09-21 22:16:44 +00:00
PolymetaandHiroku fdcbca4410 Tweak pokemon label display and additional config setting 2024-09-21 22:16:44 +00:00
Hiroku 85b96268be Merge branch 'Uh-Oh-Slippy-is-Messing-with-Code-Again' into 'main'
Uh oh slippy is messing with code again

See merge request cable-mc/cobblemon!1162
2024-09-21 00:17:15 +00:00
Hiroku 0a94c00859 Merge branch 'bugfix/1-6-fixes' into 'main'
Fixes

Closes #973 and #989

See merge request cable-mc/cobblemon!1165
2024-09-21 00:16:55 +00:00
Paul b7a2091c3e Fixed battle overlay animations absolutely zooooming 2024-09-21 10:01:45 +10:00
Polymeta 2dcd9467ec fix compile errors
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-20 13:08:50 +01:00
Polymeta 4fc6d35aab Merge branch 'Myslippy-main-patch-44800' into 'Uh-Oh-Slippy-is-Messing-with-Code-Again'
Update CHANGELOG.md (I apologize for my sins hiro please forgive me)

See merge request cable-mc/cobblemon!1163
2024-09-20 11:41:48 +00:00
Paul 89d62606d3 Merge remote-tracking branch 'origin/main' into bugfix/1-6-fixes 2024-09-20 19:54:21 +10:00
Myslippy c424e3a8c5 Update CHANGELOG.md (I apologize for my sins hiro please forgive me) 2024-09-20 09:36:35 +00:00
Slippy 792a8795ed more adjustments 2024-09-20 04:20:48 -05:00
Slippy 05d3c6d928 updated village pokecenter structure nbt files 2024-09-20 04:01:33 -05:00
Slippy 3f56af4b86 updated village pokecenter structure nbt files 2024-09-20 03:50:25 -05:00
Apion fe0e32de76 Merge branch 'Whaet' into 'main'
Update treasure.json

See merge request cable-mc/cobblemon!1160
2024-09-20 06:43:35 +00:00
apion 7456afac58 Fix crash 2024-09-20 02:28:13 -04:00
dhi_holo ee07204bae Merge branch 'main' into Whaet 2024-09-20 15:18:50 +10:00
dhi_holo 252296bf71 Update treasure.json
Made it so you can't fish obscene numbers of Poké Rod Smithing Templates anymore, but you can still get more from higher enchanted rods
2024-09-20 15:18:09 +10:00
Apion 3c4da18040 Merge branch 'bugfix/1-6-fixes' into 'main'
1.6 fixes

Closes #991, #973, and #989

See merge request cable-mc/cobblemon!1159
2024-09-20 05:16:46 +00:00
HirokuandApion 88ff54b97b 1.6 fixes 2024-09-20 05:16:45 +00:00
Hiroku 1f1590a49f Merge branch 'sidemoddable-storage-types' into 'main'
Moved PlayerInstancedDataStoreType to not be an enum (so sidemods can add new ones)

See merge request cable-mc/cobblemon!1158
2024-09-20 05:14:36 +00:00
apion c9476efe6f Licenses (please have mercy) 2024-09-20 00:12:00 -04:00
apion ac77262c88 Moved PlayerInstancedDataStoreType to not be an enum (so sidemods can add new ones) 2024-09-20 00:05:21 -04:00
Paul ba649652da Fixed shiny property not syncing properly #991 2024-09-20 13:25:32 +10:00
Paul c63dff32a0 Fixed capture pokeballs in battle UI spinning forever, fixes #973 2024-09-20 12:51:56 +10:00
Paul c253683506 Made relic coin pouches waterloggable, fixes #989 2024-09-20 12:24:46 +10:00
Hiroku d7788e277f Merge branch 'dialogue' into 'main'
cleanup dialog

See merge request cable-mc/cobblemon!1152
2024-09-19 23:54:48 +00:00
TestandHiroku 44cd81eb24 cleanup dialog 2024-09-19 23:54:47 +00:00
Hiroku 0987afe645 Merge branch 'feature/post-port-trauma' into 'main'
1.21.1 port fixes and other things

Closes #941, #214, #959, #986, #978, #975, and #952

See merge request cable-mc/cobblemon!1155
2024-09-19 23:47:01 +00:00
Polymeta d407561978 add datafixer for pokemon model components
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-19 17:04:06 +01:00
Polymeta dfe6c19e01 also apply regenerator on force switches
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-19 16:43:55 +01:00
Polymeta 978e625ba2 fix regenrator ability HP desync
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-19 15:35:20 +01:00
Polymeta d401009dbb restore some "lost" default pokemon nbt so it can be targeted by selectors
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 23:53:55 +01:00
Polymeta 0d16619eb8 create BeastBallModel.kt and assign it so the beast ball gets correct throwing animation and small cleanup
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 23:10:16 +01:00
Polymeta fd8feca60b merge 2 item renderer mixin classes into one and refactor out equality method to use for both dex and pokeball
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 21:45:54 +01:00
Polymeta d13908a8e7 fix pasture pokemon dropping loot when owner is not "present"
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 21:45:14 +01:00
Polymeta 1aae6fcc57 PR feedback
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 21:45:14 +01:00
Polymeta 6331742f93 fix mixin doing instance based comparison into something a little more concrete (resource location) also fixed boat crash
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 21:45:13 +01:00
Polymeta a21d99c871 make the interaction wheel slightly bigger to prevent overlapping buttons
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 21:45:13 +01:00
Polymeta c8f230ee8f update multiblock to contain all 3 parts as valid blocks for block entity also fix shoulder mount showing pre-evo and make pokemon smarter on leash
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-18 21:45:08 +01:00
Nick 8cf6645cdd Merge branch 'dfu-fun' into 'main'
DataFixers for a bunch of stuff

See merge request cable-mc/cobblemon!1156
2024-09-18 17:36:37 +00:00
ApionandNick 2b4b8fe13a DataFixers for a bunch of stuff 2024-09-18 17:36:37 +00:00
Slippy 3fcfac1cf6 Bug Fixes for ruins and fossil structures 2024-09-16 23:01:40 -05:00
Hiroku c73bfe67bf Merge branch 'no_ai-and-freeze_frame' into 'main'
Added no_ai and freeze_frame props, respect noai=true, added /freezepokemon

See merge request cable-mc/cobblemon!1154
2024-09-16 00:08:10 +00:00
Paul 25bdef0510 Cleanup isNoAi references since it's not needed 2024-09-16 08:16:18 +10:00
Paul d0c9093f41 Added no_ai and freeze_frame props, respect noai=true, added /freezepokemon 2024-09-15 20:12:45 +10:00
Hiroku 98e38836c5 Merge branch 'implement_pokemon' into 'main'
Petilil animation fix

See merge request cable-mc/cobblemon!1140
2024-09-15 09:51:19 +00:00
Frank The FarmerandHiroku b3a3064e1b Petilil animation fix 2024-09-15 09:51:19 +00:00
Paul a8caaf4654 Added changelog for breaking changes, use 'maxHealth' instead of 'hp' with temporary backcompat 2024-09-15 16:31:28 +10:00
Apion 232e0f478a Merge branch 'fix/storage-registry-support' into 'main'
Fixed NBT on pokemon held items not serializing, updated to 1.21.1

See merge request cable-mc/cobblemon!1153
2024-09-15 06:17:18 +00:00
Hiroku c039bf7f20 Merge branch 'another-minor-tag-push' into 'main'
Tag updates

See merge request cable-mc/cobblemon!1151
2024-09-15 03:36:59 +00:00
Paul 88d6c17c90 Fixed NBT on pokemon held items not serializing, updated to 1.21.1 2024-09-15 13:26:33 +10:00
dhi_holo 4e76871046 Tag updates
Forgot to add some blocks to some tags, so now that's fixed :)
2024-09-15 12:30:29 +10:00
Hiroku 598d016172 Merge branch 'feature/turn-off-dex-with-hotbar' into 'main'
ensure that when using hotbar, the scanning gui disappears

Closes #981

See merge request cable-mc/cobblemon!1150
2024-09-15 02:09:41 +00:00
PolymetaandHiroku 0c5baec179 ensure that when using hotbar, the scanning gui disappears 2024-09-15 02:09:41 +00:00
Hiroku 4729d4204c Merge branch 'more-json-fixes' into 'main'
Flash Fire Lang Addition

See merge request cable-mc/cobblemon!1149
2024-09-14 23:44:38 +00:00
dhi_holo 1a07b21b8d Merge branch 'main' into more-json-fixes 2024-09-15 09:17:32 +10:00
Hiroku b10bee6a3e Merge branch 'feature/fix-pipeline' into 'main'
make sure to deploy maven artefacts from main

See merge request cable-mc/cobblemon!1148
2024-09-14 23:01:00 +00:00
PolymetaandHiroku 44889a6c7d make sure to deploy maven artefacts from main 2024-09-14 23:01:00 +00:00
Hiroku 705eeae700 Merge branch 'BattleTargetSelectionRevision' into 'main'
Battle target selection revision / player interaction options consistency

See merge request cable-mc/cobblemon!1144
2024-09-14 22:11:00 +00:00
Hiroku a2122c7b24 Merge branch 'feature/advanced-advancements!' into 'main'
fix interaction advancement json files and ensure resurrection advancement is triggered by machine

Closes #985 and #957

See merge request cable-mc/cobblemon!1147
2024-09-14 22:10:19 +00:00
PolymetaandHiroku 940ed1450d fix interaction advancement json files and ensure resurrection advancement is triggered by machine 2024-09-14 22:10:18 +00:00
Hiroku 265ecd3749 Merge branch 'sound_tracker' into 'main'
Client sound tracking for entities & casting sound preemption

See merge request cable-mc/cobblemon!1119
2024-09-14 22:09:08 +00:00
Polymeta 561ded8747 merge artefacts...
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-14 22:27:31 +01:00
Hiroku 4e695cf020 Merge branch 'Corrected-natural-tag' into 'main'
Paul is fired for breaking the spawns!

See merge request cable-mc/cobblemon!1146
2024-09-14 21:06:07 +00:00
Segfault GuyandPolymeta f9288efb31 i forgot to add licenses because i dont care 2024-09-14 22:00:52 +01:00
Segfault GuyandPolymeta f69ffe9d99 Preemptively discarding bobber entity stops cast sound. 2024-09-14 22:00:52 +01:00
Segfault GuyandPolymeta 6ec81e6af2 Implement SoundTracker for active client sounds + fix rod casting sounds. 2024-09-14 22:00:43 +01:00
FrankTheFarmer c6baf6eafb Paul is fired for breaking the spawns! 2024-09-14 21:23:23 +10:00
dhi_holo 31fc59236f Lang addition and failed advancement fix
Issue #985 is relevant to some of the changes
2024-09-14 20:41:28 +10:00
JazzMcNade c4fa18ef41 Merge branch 'main' into BattleTargetSelectionRevision 2024-09-14 01:35:02 -05:00
Hiroku 2d34b7446e Merge branch 'feature/poke-rod-crash' into 'main'
fix pokerods crashing servers when being cast

See merge request cable-mc/cobblemon!1145
2024-09-14 05:52:07 +00:00
Paul eee994831c Merge remote-tracking branch 'origin/main' 2024-09-14 15:09:21 +10:00
Paul 72768ed1ac Changelog cleanup 2024-09-14 15:09:10 +10:00
Hiroku 635279c076 Merge branch 'sculk_sensor' into 'main'
Made PC and Pasture click the Sculk sensor

See merge request cable-mc/cobblemon!1137
2024-09-14 05:08:52 +00:00
Hiroku ad9f758b2f Merge branch 'feature/pokemon-label-name-config' into 'main'
Pokemon label is working again and new config setting

See merge request cable-mc/cobblemon!1142
2024-09-14 05:03:41 +00:00
PolymetaandHiroku 6a804792e3 Pokemon label is working again and new config setting 2024-09-14 05:03:41 +00:00
Hiroku 2104bf28b1 Merge branch 'UI_close_like_minecraft' into 'main'
Ui close like minecraft

See merge request cable-mc/cobblemon!1127
2024-09-14 05:00:34 +00:00
JazzMcNade 2300581493 Merge branch 'main' into BattleTargetSelectionRevision 2024-09-13 20:14:42 -05:00
Paul 7ce6fb065a Merge remote-tracking branch 'origin/main' 2024-09-14 10:27:21 +10:00
Paul dcea385b66 Created a #cobblemon:natural tag so spawns are faster 2024-09-14 10:24:41 +10:00
Polymeta d680e998ce rip out soundinstance from bobber as it was clientOnly and therefore not working properly anyways - also tidy up
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2024-09-13 17:16:40 +01:00
Hiroku 23ea4c6474 Merge branch 'feature/primary-click-batte-ui' into 'main'
use primary click only when navigating battle UI

Closes #954

See merge request cable-mc/cobblemon!1141
2024-09-13 05:56:04 +00:00
PolymetaandHiroku abf106ce94 use primary click only when navigating battle UI 2024-09-13 05:56:04 +00:00
JazzMcNade 1b3343589f Updated Triples Shift Button 2024-09-13 00:55:23 -05:00
Hiroku 96c6af8d59 Merge branch 'where-are-they' into 'main'
Recipes and Loot Tables

See merge request cable-mc/cobblemon!1143
2024-09-13 05:10:05 +00:00
Hiroku 82bbcfad26 Merge branch 'career-development' into 'main'
Decrease unemployment rate among villagers

See merge request cable-mc/cobblemon!1138
2024-09-13 05:09:18 +00:00
TestandHiroku 70e55626a0 Decrease unemployment rate among villagers 2024-09-13 05:09:17 +00:00
dhi_holo 107665c415 Merge branch 'main' into where-are-they 2024-09-13 12:04:36 +10:00
dhi_holo c8dd002e4a Some Tag Additions
Just a few new standard namespace tag additions for our items, and fixed an error with the poke rods tag
2024-09-13 12:04:20 +10:00
Paul fd2d06458b Merge remote-tracking branch 'origin/main' 2024-09-13 11:26:58 +10:00
Paul 29cb1276eb Clear calculated values on the client when data changes in pokedex 2024-09-13 11:26:40 +10:00
dhi_holo 0e0f6cee27 Merge branch 'main' into where-are-they 2024-09-13 10:21:12 +10:00
Apion 9c3a0704b9 Merge branch 'feature/bug-squashing' into 'main'
various smaller bugfixes

Closes #969, #970, #971, #972, and #967

See merge request cable-mc/cobblemon!1135
2024-09-12 23:28:49 +00:00
PolymetaandApion e9db3fc70c various smaller bugfixes 2024-09-12 23:28:49 +00:00
Slippy a41c3cb805 Updated village loot table 2024-09-12 13:46:51 -05:00
Slippy dd9fc85100 Updated structure files of village pokecenters 2024-09-12 03:42:24 -05:00
Slippy 00483ef54c Adjusted Decorated Pot Loot Table 2024-09-12 01:59:21 -05:00
dhi_holo 03210f0465 More Loot Table Fixes
Apricorn Leaves cleaned up, Medicinal Leek cleaned up, Tumblestone Clusters, Buddling Tumblestones, and basic Tumblestone Block fixed to behave properly.
2024-09-12 16:39:33 +10:00
JazzMcNade 26dc76a4f3 Fixed inconsistent ordering of options in PlayerInteractOptionsPacket 2024-09-12 01:35:26 -05:00
dhi_holo ae5e63aac9 Gilded Chest Update
Updated Gilded Chest's loot tables to use updated component data formatting, however this didn't fix them not dropping. Will need further investigation.
2024-09-12 15:53:12 +10:00
dhi_holo 08c8dd0f99 Added Missing Recipes
with tags and advancements related to the missing recipes too.
2024-09-12 14:18:51 +10:00
JazzMcNade 2044862edd Implemented tile based target selection, removed battle portrait target selection 2024-09-11 20:18:51 -05:00
apion 148b3c4271 Fixes #977 (Sherds not rendering) 2024-09-11 20:37:38 -04:00
Slippy 870cd0ec52 Updated structure files in taiga village and snowy village 2024-09-11 12:41:59 -05:00
Hiroku ef58d38c12 Merge branch 'loot-oh' into 'main'
Loot Table Fixes

See merge request cable-mc/cobblemon!1139
2024-09-11 10:10:14 +00:00
dhi_holo 7250b1a83c Loot Table Fixes
Ores now drop stuff correctly again, and Relic Coin Sacks (due to having an unused Natural blockstate) now can drop 20-64 relic coins when broken with the Natural blockstate set to true
2024-09-11 17:22:09 +10:00
Erusel 710b3f0303 Even better, centralised function 2024-09-11 02:32:01 +02:00
Erusel 57cf6f09fd Thanks to Hiroku's advice, it's more graceful. 2024-09-11 02:06:12 +02:00
Hiroku ec6820fa9d Merge branch 'holographic-cleanups' into 'main'
Holographic Cleanups

Closes #964

See merge request cable-mc/cobblemon!1136
2024-09-10 20:38:37 +00:00
Slippy bf4b211c4f removed "adapt noise" field. removed forest gate template pool. removed "start_height" field from structure sets. removed birch tree structures from oak tree template pool. 2024-09-10 06:25:07 -05:00
Slippy 3a2accb239 Ruin structures have been given loot tables for decorated pots 2024-09-10 02:46:00 -05:00
dhi_holo 6508d39e22 Merge branch 'main' into holographic-cleanups 2024-09-10 11:35:29 +10:00
Hiroku d0c7862103 Merge branch 'party-control-tweaks' into 'main'
Tweaks and fixes of sendout and other R key functions

See merge request cable-mc/cobblemon!1113
2024-09-09 02:47:52 +00:00
Paul f12962fd24 Changelog cleanup 2024-09-09 12:38:23 +10:00
Paul 9c7db81e22 Merge remote-tracking branch 'origin/main' into party-control-tweaks 2024-09-09 12:18:28 +10:00
Hiroku 6be1caf41a Merge branch 'sound' into 'main'
Fixed sound stuff lost in merges

See merge request cable-mc/cobblemon!1133
2024-09-09 02:17:55 +00:00
Hiroku d582507a6e Merge branch 'implement_pokemon' into 'main'
Some rather important animation fixes

See merge request cable-mc/cobblemon!1134
2024-09-09 02:17:13 +00:00
Frank The FarmerandHiroku 302c0e6fe7 Some rather important animation fixes 2024-09-09 02:17:13 +00:00
Erusel 97761ba1e3 Made PC and Pasture click the Sculk sensor 2024-09-09 00:10:04 +02:00
Slippy a75b578954 Updated Ruin Structure template_pool files to contain the new "override_liquid_settings" field. 2024-09-07 23:43:24 -05:00
dhi_holo 44ade828fa Update en_us.json
Updated Smithing Templates to the 1.21.2 style (because it's so much more usable, and means less updating work later)
Improved names of Gone Fishin' and A True Antiquarian advancements
2024-09-08 11:05:45 +10:00
dhi_holo 4c1a5f12b7 Merge branch 'main' into holographic-cleanups 2024-09-08 10:51:06 +10:00
Hiroku bbe7f96332 Merge branch 'BallBuffs' into 'main'
Ball buffs

See merge request cable-mc/cobblemon!1131
2024-09-08 00:37:11 +00:00
Hiroku a29a7ebbca Merge branch 'feature/resolve-some-todos' into 'main'
now that pokedex is present, resolve some todos that required on it, also use OTs for exp calc

Closes #966

See merge request cable-mc/cobblemon!1132
2024-09-08 00:18:10 +00:00
PolymetaandHiroku f4a7cc92ee now that pokedex is present, resolve some todos that required on it, also use OTs for exp calc 2024-09-08 00:18:10 +00:00
Sterrezo 9768711c5e Evolution sound is working now! 2024-09-08 01:56:54 +02:00
Sterrezo 4b3a864b28 Nothing is working
I fixed some missing sounds that were lost in merges. Added a placeholder animation to Hisui bias Petilil. Removed an empty sound event.
2024-09-08 01:19:06 +02:00
Slippy 60f057d28e Fossil Template Pools updated to contain "apply_waterlogging" field 2024-09-07 18:11:54 -05:00
Slippy 3c4219b069 update village template_pools to include 1.21 "override_liquid_settings" field 2024-09-07 17:12:11 -05:00
JazzMcNade 0db6da951e Updated tooltip strings for dusk ball. 2024-09-07 16:44:54 -05:00
JazzMcNade 3963537e40 Buffed Dusk Ball and Repeat Ball catch rate 2024-09-07 16:38:57 -05:00
Licious dd5e578d3a Merge branch 'ImplementRepeatBall' into 'main'
Implemented Repeat Ball's catch modifier

See merge request cable-mc/cobblemon!1130
2024-09-07 20:13:37 +00:00
JazzMcNade 4dab4b7ef6 Implemented Repeat Ball's catch modifier 2024-09-07 14:44:20 -05:00
Hiroku c19444816a Merge branch 'log-async' into 'main'
More safely check thread for spawners and influencers access and fix internal illegal access

See merge request cable-mc/cobblemon!1123
2024-09-07 10:11:27 +00:00
Paul 0610a997e2 Merge remote-tracking branch 'origin/main' into log-async
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/factory/JsonPlayerDataStoreFactory.kt
2024-09-07 19:37:38 +10:00
Hiroku 10faab68f9 Merge branch 'DoublesAreTheFuture' into 'main'
Added Doubles/Triples/Multibattles

See merge request cable-mc/cobblemon!1091
2024-09-07 09:36:59 +00:00
Paul 42c91c667b Licenses AGAIN RAAAAA 2024-09-07 19:25:09 +10:00
Paul bde9ddd017 TODO clearing 2024-09-07 19:14:49 +10:00
Paul c19a92406e Resolving merge issues 2024-09-07 19:05:50 +10:00
dhi_holo 93389ae98b Merge branch 'main' into holographic-cleanups 2024-09-07 18:14:41 +10:00
dhi_holo cb1dba64c0 missed a bit
one day I'll do this properly from stage 0

This is funnier though
2024-09-07 18:14:05 +10:00
Slippy 2d01e7a482 Village Pokecenters 2024-09-07 02:12:20 -05:00
dhi_holo 88f285199c added a thing for the rod recipe advancements
just makes it less spammy
2024-09-07 17:10:40 +10:00
dhi_holo e17bd10660 Automaton Fixes
Fixed Automaton Armour Trim being called that (instead of Armor because it's en_us), and missing the item name entirely
2024-09-07 17:00:06 +10:00
Hiroku c2ac903180 Merge branch 'mod-compat' into 'main'
Re add JEI compat

See merge request cable-mc/cobblemon!1129
2024-09-07 06:47:59 +00:00
dhi_holo 84feb449d9 Rodvancements
+Added Recipe Advancements for all of the Poké Rod Smithing Template stuff
+Unhid the Candy advancement, as there's now enough ways to get them that it doesn't need to be hidden
-Removed the Poké Rod Smithing Template from the Archaeology tab, as it's unfitting and is located in another tab where it does fit as well.
2024-09-07 16:44:06 +10:00
apion c475e51a1c Re add JEI compat 2024-09-07 02:16:02 -04:00
dhi_holo 682abbdd43 Green Dye Switch
For the sake of sanity
2024-09-07 16:11:23 +10:00
dhi_holo f8e68d2217 Updated Protector Recipe
Now cleaner and cooler
2024-09-07 14:51:31 +10:00
dhi_holo e8ddabe3ac Merge branch 'main' into holographic-cleanups 2024-09-07 14:33:35 +10:00
dhi_holo 32dd49b669 Update display_case.json
Fixes z-fighting, resolving #964
2024-09-07 14:30:54 +10:00
Paul b9d3966cfe Merge remote-tracking branch 'origin/main' into DoublesAreTheFuture
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/events/CobblemonEvents.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/gui/GuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/interpreter/instructions/SwitchInstruction.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/battle/ClientBattle.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/PokemonGuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/battle/BattleOverlay.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/battle/subscreen/BattleSwitchPokemonSelection.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/RenderHelper.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
#	common/src/main/resources/assets/cobblemon/sounds.json
#	common/src/main/resources/assets/cobblemon/sounds/item/pokedex/pokedex_show.ogg
2024-09-07 14:26:07 +10:00
Paul 682325af59 Merge remote-tracking branch 'origin/main' into evolution-effect 2024-09-07 14:03:45 +10:00
Paul d145969631 Removed unneeded glowTime code 2024-09-07 14:03:23 +10:00
Hiroku 432ccf17c0 Merge branch 'evolution-effect' into 'main'
Evolution effect

See merge request cable-mc/cobblemon!970
2024-09-07 04:03:14 +00:00
Paul c6452d1905 I will teach the license file the true meaning of pain (bread) 2024-09-07 13:54:16 +10:00
Paul f72f422ef0 Conflict fixes and fixes to recent animation function changes 2024-09-07 13:43:56 +10:00
dhi_holo d10ba586c8 To Undo Later
Just making it so the game doesn't have errors from the bug with the species not loading before the advancements, will undo this change once we can
(also corrected an error I put in the lang)
2024-09-07 13:09:25 +10:00
Paul 39fc384b67 Merge remote-tracking branch 'origin/main' into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokemon/evolution/Evolution.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/snowstorm/ParticleEvent.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityState.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/animation/PoseTransitionAnimation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/animation/PrimaryAnimation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/animation/StatefulAnimation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/bedrock/animation/BedrockActiveAnimation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/pokemon/PokemonRenderer.kt
2024-09-07 13:09:21 +10:00
Paul 477318b124 Imports 2024-09-07 12:53:10 +10:00
Paul 367d79a976 Merge remote-tracking branch 'origin/main' into poker-decks 2024-09-07 12:52:01 +10:00
Hiroku eb36320396 Merge branch 'sega_bass_pro_fishing_2' into 'main'
Make it possible to add new animation molang functions.

See merge request cable-mc/cobblemon!1115
2024-09-07 02:45:21 +00:00
dhi_holo 6409b75aef Merge branch 'main' into holographic-cleanups 2024-09-07 12:34:15 +10:00
Hiroku 98e4f6facc Merge branch 'stone-blocks' into 'main'
Blocks! More Blocks! Stones, even!

Closes #930

See merge request cable-mc/cobblemon!1120
2024-09-07 02:16:31 +00:00
Hiroku 5ea8bbd08e Merge branch 'TheSketchySmeargle' into 'main'
Sketch and Forget

See merge request cable-mc/cobblemon!1093
2024-09-07 01:55:18 +00:00
Paul e7efb94ee9 Merge remote-tracking branch 'origin/main' into poker-decks 2024-09-07 10:51:04 +10:00
Hiroku c3230f0722 Update CHANGELOG.md 2024-09-07 00:49:52 +00:00
Paul 0fd6328ae4 Fixed compile error from mappings switch 2024-09-07 10:43:43 +10:00
Hiroku 43a05e5037 Merge branch 'feature/neoforge-bump-fixes' into 'main'
bump neoforge to stable version and fix breaking changes (and add missing license headers)

Closes #961 and #960

See merge request cable-mc/cobblemon!1128
2024-09-07 00:38:35 +00:00
PolymetaandHiroku c2b5eca4c7 bump neoforge to stable version and fix breaking changes (and add missing license headers) 2024-09-07 00:38:35 +00:00
Hiroku e9c88ae899 Merge branch 'feature/poker-chips' into 'poker-decks'
variation tooltip to display when buttons are hovered

See merge request cable-mc/cobblemon!1125
2024-09-07 00:38:01 +00:00
PolymetaandHiroku fece798b92 variation tooltip to display when buttons are hovered 2024-09-07 00:38:01 +00:00
Myslippy 564b5ae413 Update StructurePoolGeneratorMixin.java 2024-09-06 20:51:40 +00:00
Myslippy a8c93146da Update StructurePoolGeneratorMixin 2024-09-06 20:08:37 +00:00
Licious a0c3e40cc4 Merge branch 'fix_moves_description' into 'main'
Fix moves descriptions cutting off

See merge request cable-mc/cobblemon!1126
2024-09-06 13:10:23 +00:00
EruselandLicious 1da011026e Fix moves descriptions cutting off 2024-09-06 13:10:23 +00:00
Erusel 4ab4f27690 fixed trade gui not closing 2024-09-06 14:39:50 +02:00
Erusel 5aaf3aaa8a fixed doomed key pressed method not being called and screens not closing 2024-09-06 14:38:18 +02:00
BuildTools 73ba27a148 fixed imports 2024-09-06 13:55:44 +02:00
BuildTools 7493ac80c4 changing thing for making it closing at the inventory key and not "e" 2024-09-06 13:55:05 +02:00
BuildTools 5d4c4a2d9d added minecraft like closing on PC 2024-09-06 13:24:03 +02:00
BuildTools dad87454cf added minecraft like closing on Pokenav 2024-09-06 13:23:18 +02:00
BuildTools fbcbdd0d1f added minecraft like closing on Starter Selection 2024-09-06 13:21:16 +02:00
BuildTools 37ac4837b2 added minecraft like closing on Trade GUI 2024-09-06 13:20:21 +02:00
BuildTools 8cae97b297 added minecraft like closing on Summary 2024-09-06 13:17:49 +02:00
JazzMcNade 3981ccc332 Player Interactions: Server now informs the client on why an option is unavailable. 2024-09-06 01:31:48 -05:00
Lily e5c2daac2e added cosmetic variants for several pokemon in the pokedex 2024-09-04 21:28:57 -04:00
Lily cccd3aa310 fixed searching 2024-09-04 17:56:44 -04:00
Lily b8dc811a4f fixed missing drop button 2024-09-04 12:51:48 -04:00
Lily 2e8529cc62 oops 2024-09-04 12:34:43 -04:00
Lily 5f8a49e008 re-ordered paldean dex; fixed johto dex missing from the national category 2024-09-04 12:28:59 -04:00
JazzMcNade a945c839f0 Greyed out trade request option if it's unavailable 2024-09-03 23:51:22 -05:00
Test 607413db61 Merge branch 'fix_pc_arrow_hover' into 'main'
Fix NavigationButton hover

See merge request cable-mc/cobblemon!1124
2024-09-04 04:07:32 +00:00
EruselandTest d478eecf47 Fix NavigationButton hover 2024-09-04 04:07:31 +00:00
SPGesus dd624d06f3 Update galar.json 2024-09-04 01:26:13 +00:00
SPGesus bc596a48ed Update alola.json 2024-09-03 22:59:34 +00:00
dhi_holo 25ad6e96f4 Not Yet Fixed Because Grr
The component data for these is pretty much solved, except for one major issue:
It totally stops the advancements loading in game for some reason. Doesn't like the species ID effectively. If anyone wants to take a crack at it between now and whenever it's solved, plz
2024-09-03 16:26:37 +10:00
dhi_holo 8efd658a93 Fix Batch 1
Added translation strings for the two new gamerules and 6 new tags (even if one of them isn't actually in this branch)
Fixed two advancements having incorrect icons (due to switch from nbt to item components)
2024-09-02 18:22:07 +10:00
dhi_holo c565a79697 Change Instrument
Evolution Blocks now use the Bit instrument (from Emerald Blocks) instead of Basedrum (from stone)
2024-09-02 16:30:13 +10:00
dhi_holo 81f82faa2d Updated to 1.21
Updated to Main/1.21
2024-09-02 16:20:28 +10:00
dhi_holo 978e886b6e Merge branch 'main' into stone-blocks 2024-09-02 15:35:58 +10:00
Paul 6d7784cb3a Added dex additions and dex entry additions 2024-09-02 15:11:03 +10:00
JazzMcNade 63de39b970 Merged Main into DoublesAreTheFuture 2024-09-01 19:18:50 -05:00
JazzMcNade 05a8154d2e Merge Conflicts 2024-09-01 18:32:30 -05:00
JazzMcNade 134b071a1d Merge branch 'main' into TheSketchySmeargle 2024-09-01 18:32:08 -05:00
Paul 5f4366735f Merge remote-tracking branch 'origin/poker-decks' into poker-decks 2024-09-01 22:00:00 +10:00
apion 7fd0f2710e Fixed pokedex grant all command 2024-09-01 07:09:55 -04:00
Paul 7a4760e1bc Merge remote-tracking branch 'origin/main' into poker-decks
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/events/CobblemonEvents.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/gui/GuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/PokemonGuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/AerodactylModel.kt
#	common/src/main/resources/assets/cobblemon/sounds.json
2024-09-01 20:24:24 +10:00
apion 6574976f2d Pokedex scrolls to correct mon when opened via scanner 2024-09-01 06:18:34 -04:00
apion 6126653a2c Fix neoforge scanner rendering 2024-09-01 05:38:32 -04:00
Paul f45bc68ee6 Changelog! Again! Check again tomorrow for more (also mojmaps) 2024-09-01 19:33:07 +10:00
Paul 1c71e68323 Merge remote-tracking branch 'origin/main' into log-async 2024-09-01 19:29:56 +10:00
Paul 2d9523b9a1 Deleted unused posers 2024-09-01 19:27:00 +10:00
Paul 5ed9fba170 Changelog squashing for 1.6 2024-09-01 19:25:40 +10:00
Hiroku 22583bd207 Merge branch 'sega_bass_pro_fishing_2' into 'main'
1.6 Merge

Closes #916

See merge request cable-mc/cobblemon!1107
2024-09-01 07:53:43 +00:00
Paul 32d68ce554 Conflicto begonus 2024-09-01 17:10:26 +10:00
Paul 72a897063c Merge remote-tracking branch 'origin/main' into sega_bass_pro_fishing_2
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/PlayerMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonSounds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/item/PokemonSelectingItem.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokemon/evolution/Evolution.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/interpreter/instructions/SwitchInstruction.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/block/HealingMachineBlock.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/block/PCBlock.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/net/battle/BattleMusicHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/net/battle/BattleSwitchPokemonHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/sound/battle/BattleMusicInstance.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/battle/BagItemConvertible.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/interactive/ReviveItem.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/evolution/controller/ServerEvolutionController.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/world/gamerules/CobblemonGameRules.kt
#	common/src/main/resources/data/cobblemon/loot_table/ruins/common/luna_henge_ruins.json
#	common/src/main/resources/data/cobblemon/loot_table/ruins/common/sol_henge_ruins.json
#	common/src/main/resources/data/cobblemon/loot_table/ruins/common/stonjourner_henge_ruins.json
#	common/src/main/resources/data/cobblemon/loot_table/ruins/uncommon/luna_henge_ruins.json
#	common/src/main/resources/data/cobblemon/loot_table/ruins/uncommon/sol_henge_ruins.json
#	common/src/main/resources/data/cobblemon/loot_table/ruins/uncommon/stonjourner_henge_ruins.json
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_center1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_center1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_center1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side2a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side2b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side2c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side3a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side3b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side3c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side4a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side4b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/lunatone_side4c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_center1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_center1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_center1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side2a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side2b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side2c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side3a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side3b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side3c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side4a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side4b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/solrock_side4c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_center1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_center1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_center1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner10a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner10b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner10c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner11a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner11b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner11c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner12a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner12b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner12c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner2a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner2b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner2c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner3a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner3b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner3c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner4a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner4b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner4c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner5a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner5b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner5c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner6a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner6b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner6c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner7a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner7b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner7c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner8a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner8b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner8c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner9a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner9b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_corner9c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side1a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side1b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side1c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side2a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side2b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side2c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side3a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side3b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side3c.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side4a.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side4b.nbt
#	common/src/main/resources/data/cobblemon/structure/ruins/stonjourner_side4c.nbt
2024-09-01 16:32:14 +10:00
Paul a471a0183f Fixed form unlocking not working properly and gender ratios misbehaving in dex 2024-09-01 16:25:37 +10:00
Hiroku 11cfb7184d Merge branch 'sound' into 'main'
Sound updates

See merge request cable-mc/cobblemon!1121
2024-09-01 06:15:36 +00:00
Hiroku e2645e02d1 Merge branch 'poker-table' into 'poker-decks'
Table for poker decks

See merge request cable-mc/cobblemon!1122
2024-09-01 04:50:21 +00:00
TestandHiroku 33ff9e90b6 Table for poker decks 2024-09-01 04:50:21 +00:00
Test e75e2801ce fix slot spacing 2024-08-31 23:53:53 -04:00
Tyzillion 7f77abd9a2 License update and changelog update. 2024-08-31 23:13:46 -04:00
Paul 592e6ce5a8 Properly setup dex data with ordering 2024-09-01 11:47:52 +10:00
JazzMcNade f653d325bb Battle wheel option is now greyed out if the target is unable to battle. 2024-08-31 19:11:40 -05:00
Paul 859ca62dc8 Fixed flashing dex screen and seen pokemon not showing properly 2024-08-31 12:25:05 +10:00
Paul 148f4be444 Dex sort order 2024-08-31 11:07:45 +10:00
Paul 4bf6ec80b4 re-enabled dex scanning but it blows up the game 2024-08-30 22:12:50 +10:00
Paul d9a0998213 Added variation controls to dex, fixed various bugs with dex 2024-08-30 22:00:14 +10:00
JazzMcNade eeec0e853b Fixed request button text. Updated team leave icon. 2024-08-30 00:34:42 -05:00
Tyzillion 925b18d809 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-08-28 20:37:39 -04:00
Paul 9c817f77dc Dex initialization fixes, display correct first-known-forms in national dex, fixed species features not saving 2024-08-26 21:36:12 +10:00
Paul b044fe01bb Form dex squashing, Alola dex with separated Rattata as example, various fixes for UI knowledge 2024-08-26 17:03:09 +10:00
Paul d46c88dcf3 Significant restructuring of pokedex entry data 2024-08-26 12:26:20 +10:00
JazzMcNade 03231beab7 Sketch's new move is now immediately applied to effectedpokemon, rather than during postbattle. 2024-08-25 19:44:43 -05:00
apion 3d84063f9a Fix licenses, delete unnecessary files 2024-08-25 02:17:18 -04:00
apion 73237073c2 Lang fixes 2024-08-25 02:09:47 -04:00
apion 05b04cfa67 Added swapping between dexes 2024-08-25 02:09:00 -04:00
apion 4187c04374 Added Johto pokemon, and allowed for aggregation of separately defined dexes 2024-08-25 01:48:05 -04:00
apion d5fca78ba0 Merge remote-tracking branch 'origin/poker-decks-key-value' into poker-decks-key-value
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/pokedex/PokedexGUI.kt
2024-08-24 23:25:28 -04:00
apion 8411cd44f9 Added a codec backed GSON adapter, added a codec for ExpressionLikes, setup infrastructure for different types of dexes 2024-08-24 23:24:54 -04:00
Paul e1dc9b1b1b Merge relics 2024-08-25 11:40:41 +10:00
Paul 595a079625 Merge remote-tracking branch 'origin/poker-decks' into poker-decks-key-value
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokedex/PokedexJSONRegistry.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokedex/PokedexRecord.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokedex/SpeciesPokedexEntry.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/pokedex/PokedexGUI.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokedex/DexData.kt
#	common/src/main/resources/data/cobblemon/pokedexes/national.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_alola.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_galar.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_hisui.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_hoenn.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_johto.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_kalos.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_kanto.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_paldea.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_sinnoh.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_unknown.json
#	common/src/main/resources/data/cobblemon/pokedexes/national_unova.json
2024-08-25 11:11:14 +10:00
apion cf5bd4dca6 Fix conditions (again) 2024-08-24 16:59:42 -04:00
apion a0d9322e55 Fix conditions 2024-08-24 16:52:23 -04:00
apion 304f6c83ee Fix compile errors and encode/decode issues 2024-08-24 16:20:22 -04:00
Paul 8d4a7de267 Calculated pokedex data, some clean up of unused stuff, need to fix up dex client 2024-08-24 22:36:57 +10:00
apion 3b302d6777 Add referential integrity 2024-08-23 23:14:40 -04:00
Paul 59a92391cd Merge remote-tracking branch 'origin/poker-decks-key-value' into poker-decks-key-value 2024-08-23 22:27:55 +10:00
Paul d18a3e43e4 Reworking dex data to be declarative 2024-08-23 22:27:36 +10:00
apion c9baf9332b Add forms 2024-08-22 18:27:44 -04:00
apion ccf3d8eefe Add the 151 OG pokemon as dex entries 2024-08-22 17:24:24 -04:00
Sterrezo 9ac8ca3a7b Final tweaks to the new evolution sound 2024-08-22 14:08:58 +02:00
apion 0698f8265b Fixed numbering 2024-08-21 22:39:41 -04:00
apion a10622151c Renamed stuff to be pokedex specific 2024-08-21 21:15:21 -04:00
apion f69ed78582 Cleaned up event subscriptions a bit, hooked into player party store instead of trying to track pokedex events everywhere. 2024-08-21 19:43:12 -04:00
apion c52ad67435 Fix pokemon rendering when not supposed to 2024-08-21 19:06:01 -04:00
dhi_holo a79428cfb6 Update CobblemonBlocks.kt
Made Ice Block use the Ice colour on maps (why are the map colour names so annoying)
2024-08-21 17:17:17 +10:00
dhi_holo a0672f6354 Data and Textures
all the data files for the smooth tumblestone block suites, and the textures updated since past commit
2024-08-21 16:40:49 +10:00
dhi_holo 72000a1340 More Tumblestone Blocks WIP
Needing to take a break, so untested WIP push just so it's saved. Adds all 9 smooth blocks, and updates older textures. Should be fully functional on the asset side as of this commit, data side will be done later.
2024-08-21 14:57:16 +10:00
Sterrezo 9d25da31dc Fixed block sounds playing at an incorrect pitch
Increased the pitch in CobblemonSounds.kt, workaround for #929
Tweaked volumes again.
2024-08-20 13:10:58 +02:00
Sterrezo 96778d2de0 Implemented sounds for evolution stone blocks 2024-08-20 11:58:19 +02:00
dhi_holo c646f7555e Blocks In
All 10 blocks implemented in near full.
Block data, models, loot tables, recipes, advancements, item groups, lang. Only missing the textures for 6 of the blocks, the sounds (needs changing in Blocks as well as implementation), and confirmation for one texture.

Ice Stone texture also updated
2024-08-20 12:30:07 +10:00
Test c5600ff881 rolling scan lines 2024-08-18 23:17:08 -04:00
apion a39b3092be Actually added a pokemon with an alternate form (rattata) 2024-08-18 17:21:04 -04:00
apion 8c5a24c431 More progress 2024-08-18 16:38:53 -04:00
Sterrezo fb84c48d4d Merge branch 'main' into sound 2024-08-18 21:20:54 +02:00
Sterrezo efc59ab2be More updates to the UI evolution sound 2024-08-18 21:19:09 +02:00
apion 44560195fc Things are kinda working 2024-08-18 14:17:15 -04:00
apion 9b2f0c9375 More work trying to convert to new data format 2024-08-18 13:34:38 -04:00
Hiroku 5cbcef5a88 Merge branch 'remove-unused-event' into 'main'
Remove unused held item update event

See merge request cable-mc/cobblemon!1118
2024-08-18 02:46:56 +00:00
Hiroku 7aa76587df Merge branch 'whatsy/poker-decks' into 'poker-decks'
poker decks

See merge request cable-mc/cobblemon!1089
2024-08-18 02:46:37 +00:00
JazzMcNade ebbbec9d6c Fixed merge conflicts 2024-08-17 21:30:46 -05:00
JazzMcNade 8bb2d1321d Merge branch 'main' into TheSketchySmeargle 2024-08-17 21:30:20 -05:00
Tyzillion e5ffb6db96 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect 2024-08-17 22:23:57 -04:00
apion 7700a606d0 IDK if this stuff is staying 2024-08-17 20:52:49 -04:00
Paul 57dbb9fc02 Conflicto confundo 2024-08-18 10:01:47 +10:00
Paul 938cd995d7 Merge remote-tracking branch 'origin/poker-decks' into whatsy/poker-decks
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/net/pokedex/MapUpdatePacketHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokedex/scanner/PokedexUsageContext.kt
2024-08-18 09:58:41 +10:00
Paul 112649081f Properly handle the ordering of dexes 2024-08-18 09:54:36 +10:00
apion d27ee304cb This ones for you Village 2024-08-17 13:53:44 -04:00
apion 1b5ad6e860 Fix server crashes 2024-08-17 10:58:44 -04:00
apion d283eb061a Fix issue where only assets for the red pokedex are used 2024-08-17 09:46:08 -04:00
Paul 92111b1046 Ported some dex stuff to mojmaps, scanning owned pokemon adds to Caught status in dex 2024-08-17 21:35:23 +10:00
Paul fbc976bfa0 Merge branch 'poker-decks' into whatsy/poker-decks
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokedex/PokedexJSONRegistry.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/pokedex/PokedexGUI.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/keybind/keybinds/PokedexBinding.kt
2024-08-17 19:37:52 +10:00
Landon Wills 5c6ecb1807 Remove unused held item update event 2024-08-16 23:13:39 -04:00
Paul cb266499a3 Use a snapshot of the storm matrix for event particle type EMITTER 2024-08-16 17:28:29 +10:00
Paul 094f860b80 Fixed evo burst particle being emitter bound 2024-08-16 15:53:04 +10:00
Paul 79c1259cae Restored original particle event source matrix for EMITTER and EMITTER_BOUND types 2024-08-16 15:43:53 +10:00
Sterrezo 01f922b653 Clarified a change in the changelog and re-added a sound for evolution in sounds.json 2024-08-16 01:11:52 +02:00
Sterrezo 71d1730697 Merge branch 'main' into sound 2024-08-16 00:58:52 +02:00
Apion 84dfd56c12 Merge branch 'Slippy-is-a-Coder-Now' into 'main'
Slippy is a coder now

See merge request cable-mc/cobblemon!1108
2024-08-15 21:25:57 +00:00
Nick 770abc2b9b Merge branch 'feature/fix-license' into 'main'
fix missing license headers

See merge request cable-mc/cobblemon!1116
2024-08-15 17:35:28 +00:00
Polymeta 353069803f fix missing license headers 2024-08-15 18:17:55 +01:00
Waterpicker 03227d07f2 Make it possible to add new animation molang functions. 2024-08-15 02:06:51 -05:00
Paul 3a759eccf7 Improved "!" above challenger heads, it's not smooth yet 2024-08-12 13:45:26 +10:00
apion d515091b30 Add all unimplemented mons to dex 2024-08-11 01:30:14 -04:00
apion 1f3e408396 Made pokemon types into an enum, changed how server side scan validation works 2024-08-10 22:38:03 -04:00
apion f800070f91 Made scanning actually add pokedex records 2024-08-10 20:27:21 -04:00
apion 5f4c2d1d7e God have mercy on my soul 2024-08-10 19:15:33 -04:00
JazzMcNade d8bae04239 BattleChallengeParticleWIP 2024-08-10 18:06:59 -05:00
Tyzillion 4efd8a7fef Tweaked evolution particles. 2024-08-10 15:52:27 -04:00
Tyzillion e7911644d8 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokemon/evolution/Evolution.kt
2024-08-10 14:57:33 -04:00
apion 590c3cfcd2 Added zooming back 2024-08-10 10:05:40 -04:00
apion 2b1b393c92 Added back the display of the species name 2024-08-10 07:27:56 -04:00
apion 0b3d78e509 More cleanup 2024-08-10 06:30:47 -04:00
Sylvonir b42b561e49 Oops random extra variable 2024-08-09 21:38:44 -07:00
Sylvonir 68639390f5 Merge remote-tracking branch 'origin/party-control-tweaks' into party-control-tweaks 2024-08-09 21:38:17 -07:00
Sylvonir 226fefc08a Hopefully match party scroll behaviour with vanilla logic 2024-08-09 21:38:07 -07:00
Sylvonir c8fb04e0ea Hopefully match party scroll behaviour with vanilla logic 2024-08-09 21:35:38 -07:00
Sylvonir f4aa67390a Merge remote-tracking branch 'origin/party-control-tweaks' into party-control-tweaks 2024-08-09 21:30:38 -07:00
Hiroku de3342226b Merge branch 'battle_bug_fixes' into 'main'
Battle bugs pentakill

Closes #865, #912, #880, #466, and #819

See merge request cable-mc/cobblemon!1105
2024-08-10 00:37:40 +00:00
Hiroku ca890133ba Merge branch 'Myslippy-main-patch-47052' into 'main'
Update CHANGELOG.md

See merge request cable-mc/cobblemon!1111
2024-08-10 00:36:24 +00:00
Hiroku c452aa77a9 Merge branch 'fix-missing-stellar-message' into 'main'
Fix terastallize message missing when using stellar

See merge request cable-mc/cobblemon!1112
2024-08-10 00:36:12 +00:00
Sylvonir 1530f4d09a Update CHANGELOG.md 2024-08-09 15:22:26 -07:00
Sylvonir 2a64c405f9 Update CHANGELOG.md 2024-08-09 15:12:51 -07:00
Sylvonir d5a22165c6 Fix battle log GUI flashing when BattleGUI is opened 2024-08-09 15:00:40 -07:00
Sylvonir a16ae6665a Fix party scroll not overriding vanilla scroll with high scroll speeds 2024-08-09 13:55:01 -07:00
Sylvonir 12595dde53 Let Pokémon be invulnerable during sendout and intangible during recall 2024-08-09 13:33:15 -07:00
Sylvonir 68299d2b57 Tweak recall timing and allow it to cancel sendout 2024-08-09 13:02:13 -07:00
JazzMcNade 3d8935136e Updated Lang key references 2024-08-09 01:17:24 -05:00
Landon Wills fba2217e6f Fix terastallize message missing when using stellar 2024-08-09 02:00:10 -04:00
JazzMcNade 462a8502bf Removed delay in damage being applied for some targets in multitarget attacks 2024-08-09 00:54:50 -05:00
JazzMcNade d8645530de Fixed up challenge notification messages 2024-08-08 00:28:42 -05:00
Myslippy 8026a7c0b7 Update CHANGELOG.md 2024-08-08 03:16:19 +00:00
JazzMcNade 1e27298f36 Sendouts for double/triples now better reflect the party team ordering 2024-08-07 21:36:05 -05:00
Segfault Guy 640c7b1086 Switch clarity and cleanup to address log flooding. 2024-08-05 23:51:07 -04:00
JazzMcNade 35cc7cc956 Adjusted sendout timings so that the first sendout always happens immediately. Challengers always sendout first. 2024-08-05 20:27:41 -05:00
JazzMcNade a34bc3ef49 Battle start sendout timings are now staggered and randomized. 2024-08-05 00:24:16 -05:00
JazzMcNade e7f1092264 Added Actor display names to battle overlay 2024-08-04 23:21:13 -05:00
JazzMcNade 077669d34f Fixed back button from from playing a click sound when it is not visible 2024-08-04 17:54:02 -05:00
JazzMcNade d3784e918e Merge branch 'sega_bass_pro_fishing_2' into DoublesAreTheFuture 2024-08-04 17:36:57 -05:00
JazzMcNade d0f2d816fe Back button position is now consistent between screens. refactored class name for better clarity 2024-08-04 17:09:23 -05:00
JazzMcNade d54d91e60f Implemented Compact battle portraits, Added portrait target selection, fixed some styling 2024-08-04 16:16:24 -05:00
apion 301b210d5a Started some big boy cleanup for the dex 2024-08-04 16:31:04 -04:00
apion b942c3a45e Fix dimension serialization 2024-08-04 13:17:04 -04:00
apion 8b053f491b Another pass 2024-08-04 09:05:42 -04:00
apion a65c82c2b4 Third pass at resolving mapping problems 2024-08-04 08:27:13 -04:00
apion 813258064c Second pass at resolving mapping problems 2024-08-04 08:16:58 -04:00
apion c5124cf19d First pass at resolving mapping problems 2024-08-04 03:46:24 -04:00
apion 6ffa7b1be3 Merge branch 'refs/heads/sega_bass_pro_fishing_2' into poker-decks
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/PartyScrollMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/gui/GuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/GeneralPlayerData.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/PlayerDataStoreManager.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/adapter/JsonPlayerData.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/adapter/MongoPlayerData.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/factory/JsonPlayerDataStoreFactory.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/factory/PlayerDataStoreFactory.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonBakingOverrides.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/PokemonGuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/battle/BattleOverlay.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/keybind/CobblemonKeyBinds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/net/SetClientPlayerDataHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/RenderHelper.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PosableModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/bedrock/animation/BedrockAnimation.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/ChangeScaleAndSize.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/ChangeWalkSpeed.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/OpenStarterScreenCommand.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/battle/BattleInitializePacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/starter/SetClientPlayerDataPacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/serverhandling/starter/RequestStarterScreenHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/starter/CobbledStarterHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/MiscUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/PlayerExtensions.kt
#	common/src/main/resources/cobblemon-common.accesswidener
#	fabric/src/main/kotlin/com/cobblemon/mod/fabric/client/CobblemonFabricClient.kt
2024-08-04 02:53:12 -04:00
Hiroku cd68665cf4 Merge branch 'main' into 'main'
Enhance Test Coverage for IVs.createRandomIVs

See merge request cable-mc/cobblemon!1101
2024-08-03 01:34:39 +00:00
Hiroku de9d9ec645 Merge branch 'battle_theme_tweaks' into 'main'
Battle theme Sound Physics Remastered compat + fade out override

See merge request cable-mc/cobblemon!1106
2024-08-03 01:33:58 +00:00
Hiroku 598748220f Less code = better 2024-08-03 01:05:05 +00:00
JazzMcNade 0fd4f68f69 Corrected Lang 2024-08-02 19:30:25 -05:00
Paul 313250347c More safely check thread for spawners and influencers access 2024-08-03 10:09:56 +10:00
Sterrezo cbdb63b102 I never forget to ctrl + s the changelog 2024-08-02 15:10:05 +02:00
Sterrezo d211fb2310 Updated sounds for clicks, evolution and evolution notification. Renamed and relocated evolution sound assets.
Evolution sounds were scattered in the folder with Pokemon. I moved them all to their own folder and renamed them to be more descriptive as to where they play both in files and in code.
2024-08-02 15:07:17 +02:00
Sterrezo 2f730be207 Merge branch 'main' into sound 2024-08-02 13:53:20 +02:00
Slippy 761eb07300 Merge branch 'Slippy-is-a-Coder-Now' of https://gitlab.com/cable-mc/cobblemon into Slippy-is-a-Coder-Now 2024-08-02 00:11:15 -05:00
Slippy fec9ace152 PC loot table 2024-08-02 00:10:55 -05:00
tmetcalfe89 63e5274fc9 healer pools and entries 2024-08-01 21:32:10 -07:00
Slippy ae28d186a0 When PC and Healer blow up and is set to natural = false, they won't drop anything. 2024-08-01 22:16:46 -05:00
Slippy e901d3d1e7 PC and Healing Machine now drop iron ingots when natural = true 2024-08-01 22:11:00 -05:00
Plastered_Crab 1e0c2005da - fixed closing animation 2024-08-01 14:00:56 -07:00
Slippy 33aa6d4591 I coded something. hope it doesnt break :) 2024-08-01 11:30:42 -05:00
Segfault Guy 14c3e4e9a0 Merge remote-tracking branch 'origin/main' into battle_theme_tweaks 2024-07-30 23:25:32 -04:00
Segfault Guy b89cd88639 Merge remote-tracking branch 'origin/main' into battle_bug_fixes 2024-07-30 23:00:49 -04:00
Segfault Guy 87a106bd1e Changelogs 2024-07-30 23:00:11 -04:00
Segfault Guy 1aacad2733 Battle start + invulnerability cleanup. 2024-07-30 21:50:39 -04:00
Plastered_Crab 89dca86a21 - added test compass to top of scanner 2024-07-30 16:19:12 -07:00
Plastered_Crab cdcd7bdec6 - More adjustments to the smaller hitboxes during scanning so scanning tiny pokemon (like joltik) is easier 2024-07-30 13:22:07 -07:00
Plastered_Crab 35c3e8f245 - scanner range adjustment when zooming and fixed my goofs with the grace period 2024-07-30 09:56:13 -07:00
plastered_crab 678b0cc7fd - making smaller hitboxes bigger when scanning (needs fine tuning) 2024-07-30 00:32:49 -07:00
plastered_crab f2dd1a5c62 - overlay is kill (for real this time) 2024-07-29 22:23:05 -07:00
Segfault Guy 7c26008ad4 Turn 0, battle init fix, switch tile changes, eject pack implementation. 2024-07-29 23:52:56 -04:00
plastered_crab b54d284fdb - kill overlay upon scan finishing 2024-07-29 20:35:19 -07:00
plastered_crab 79d8425749 - added grace period for scanning 2024-07-29 20:13:40 -07:00
Test 36c4e4e553 overlay screen tests 2024-07-29 22:56:21 -04:00
Paul c28c17b514 Smoothed dex zoom in and zoom out transitioning 2024-07-28 11:06:50 +10:00
Test 75faa7b798 overlay screen tests 2024-07-27 20:42:35 -04:00
JazzMcNade f76d0511b9 Fixed Battle tiles for Single battles 2024-07-27 19:09:47 -05:00
JazzMcNade ebe47700b2 BattleRequestUI: Improved performance, expanded navigation button height, some refactoring 2024-07-27 13:56:02 -05:00
JazzMcNade f1de8adc68 Made Multibattle requests and responses more flexible 2024-07-25 23:32:31 -05:00
JazzMcNade ee0e76a172 Multibattles: Simple Geometry to make Showdown positions match Minecraft player positions 2024-07-25 00:59:31 -05:00
VasconcelosJoao 0b7c183eeb New test cases 2024-07-24 18:40:39 -03:00
VasconcelosJoao e790f03066 New test cases 2024-07-24 18:38:52 -03:00
JazzMcNade 12da3a428f Improved sendout positions for multi-battles 2024-07-24 01:08:15 -05:00
JazzMcNade 0ddd8a499a Fixed an issue with switch menu selection when there are no reserve pokemon 2024-07-23 21:51:09 -05:00
Segfault Guy faa9e73d22 Merge remote-tracking branch 'origin/main' into battle_bug_fixes 2024-07-23 00:24:37 -04:00
Segfault Guy b2fe1c2fb4 Switch and withdraw logs. 2024-07-23 00:24:07 -04:00
JazzMcNade 3a3fe49c7c Merge branch 'sega_bass_pro_fishing_2' into DoublesAreTheFuture 2024-07-22 00:35:37 -05:00
JazzMcNade cf06bed1f3 Rough Draft of new Battle Request UI 2024-07-22 00:35:22 -05:00
Segfault Guy 0011cab21e Fix nullptr exceptions when using revive or healing bench pokemon in battle. 2024-07-21 12:22:38 -04:00
Paul d282631662 Added logging for unsafe access to various APIs and moved JOIN and DISCONNECT platform events to always be sync 2024-07-21 13:16:13 +10:00
Segfault Guy 260767bed4 Add gamerule for invulnerability during battle. 2024-07-20 19:58:56 -04:00
Slippy 2895c0a2ef I hate the crumbling arch 2024-07-18 08:57:11 -05:00
Test e7cbd74b05 fix scale 2024-07-18 01:51:35 -04:00
Test bd9ebce842 Merge remote-tracking branch 'origin/DoublesAreTheFuture' into DoublesAreTheFuture 2024-07-18 01:08:36 -04:00
Test 94a1943398 assets 2024-07-18 01:08:13 -04:00
Slippy acc87f9eae Solhenge, Lunahenge, and Stonjournerhenge structures completed. 2024-07-17 12:31:55 -05:00
JazzMcNade 41cf571958 Timeout Expiration Callback for Multibattle team requests. 2024-07-16 23:42:24 -05:00
JazzMcNade c09f534746 Peer Review: Refactored interaction range constants as configuration variables. 2024-07-16 00:59:25 -05:00
JazzMcNade 3f389bd351 Some peer review Corrections 2024-07-15 23:46:27 -05:00
plastered_crab 26d431cd5e - wip function for rending scan progress 2024-07-13 16:34:44 -07:00
JazzMcNade 2f32886576 Changed BenchMovePacket to not map the empty string to null. Updated Changelog 2024-07-13 01:23:12 -05:00
JazzMcNade 074b32ef9c Merge branch 'main' into TheSketchySmeargle 2024-07-12 20:53:27 -05:00
JazzMcNade e169009c6c Updated Changelog 2024-07-12 14:25:40 -05:00
JazzMcNade 3102189a66 Merge branch 'sega_bass_pro_fishing_2' into DoublesAreTheFuture 2024-07-12 14:10:41 -05:00
JazzMcNade 1be9325a65 Resolved more remappings, fixed a triples related sendout position bug 2024-07-12 14:09:39 -05:00
plastered_crab db048b68bb - tweaked scanning distance to feel a bit better based on zoom level 2024-07-12 00:41:45 -07:00
plastered_crab 76c3cba300 - tweaks to Dex Scanner mode so Scanner overlay doesn't get stuck on randomly 2024-07-11 23:31:09 -07:00
Segfault Guy 653e048d2e Fix new battle music instance not playing when old instance is still fading out 2024-07-11 22:22:26 -04:00
Segfault Guy 36f87425c9 Sound Physics Remastered compat 2024-07-11 21:37:44 -04:00
plastered_crab 57603e60e6 - distance of scanning and detection of pokemon is determined by Zoom Level now 2024-07-11 01:05:40 -07:00
plastered_crab 487361208e - pokemon are detected if scanner is aimed at them when initiating scan overlay 2024-07-11 00:41:14 -07:00
plastered_crab 20b2711703 - attempt to fix HUD UI of Scanner getting stuck 2024-07-11 00:11:23 -07:00
Lily 43d4eacefc Merge branch 'poker-decks' into whatsy/poker-decks 2024-07-09 10:49:15 -04:00
Lily caa9ff5eba text now shows up when there's no drops available for a mon 2024-07-09 10:47:20 -04:00
Sterrezo 3f5286c0a9 Increased snap sound's asset volume 2024-07-09 00:10:29 +02:00
Sterrezo fedf2eb950 Decreased the scan's volume 2024-07-08 23:44:40 +02:00
Sterrezo 56b2951d88 Sound updates and fixes 2024-07-08 23:29:37 +02:00
Sterrezo 35d96d2eb7 A lot of sound updates to herbs and blocks 2024-07-08 13:35:36 +02:00
Sterrezo b6e6d9a151 Merge branch 'main' into sound 2024-07-08 11:35:44 +02:00
JazzMcNade d01989343c Merge branch 'sega_bass_pro_fishing_2' into DoublesAreTheFuture 2024-07-07 14:08:17 -05:00
JazzMcNade fd40ec47ab 99% conflicts resolved 2024-07-07 14:07:22 -05:00
JazzMcNade eed218b994 Merge branch 'sega_bass_pro_fishing_2' into DoublesAreTheFuture 2024-07-07 04:22:06 -05:00
plastered_crab 2013f890a5 - no more transparent issues 2024-07-06 16:24:18 -07:00
plastered_crab 42efbe5a07 - new sounds (again) 2024-07-05 17:10:04 -07:00
plastered_crab cf17f2f4ac - new sounds 2024-07-05 17:04:48 -07:00
Lily 301d1c377a fix drop percentage display showing decimals 2024-07-05 12:05:37 -04:00
plastered_crab df3d2f99d4 - test feature trimming of borders 2024-07-04 17:45:07 -07:00
Lily 2c6229417f drop table fixes 2024-07-04 17:25:39 -04:00
Lily 94d18593a0 region selection and drops info tab 2024-07-04 16:48:47 -04:00
Lily b4b6606f39 work on region selection and viewing pokemon drops 2024-07-04 10:48:22 -04:00
plastered_crab a70c08f484 - hopefully this won't end badly 2024-07-04 00:11:01 -07:00
plastered_crab b19a5f637a - I broke everything.... put it back 2024-07-03 23:51:27 -07:00
plastered_crab 331551a614 - tweak to test feature 2024-07-03 23:33:56 -07:00
Plastered_Crab 0897d3afb5 - the maps Todd Howards better now 2024-07-03 12:51:28 -07:00
Plastered_Crab a2be8c9fdd - maps interacting with decks starting to Todd Howard 2024-07-03 09:26:57 -07:00
plastered_crab 9f71d45eeb - new classes for a test feature 2024-07-03 08:03:35 -07:00
plastered_crab 910d42af16 - even MORE prep for the handoff for the Village people 2024-07-02 21:09:19 -07:00
plastered_crab 8af83a2cb9 - extra prep for big flashy features 2024-07-02 20:57:53 -07:00
Plastered_Crab 04c3a1cd0d - more important stuff 2024-07-02 20:39:44 -07:00
Plastered_Crab 6f5efa3d62 - more stuff for the new features 2024-07-02 16:02:10 -07:00
Plastered_Crab 32c7f178b5 Merge remote-tracking branch 'origin/poker-decks' into poker-decks 2024-07-02 13:08:52 -07:00
Plastered_Crab 4129f29da0 - lots of changes for a top-secret mysterious feature 2024-07-02 13:08:31 -07:00
JazzMcNade a2145b6bf7 Merge branch 'sega_bass_pro_fishing_2' into DoublesAreTheFuture 2024-06-29 21:12:35 -05:00
JazzMcNade e14c8b5264 Refactored los checking for interactions 2024-06-29 18:41:22 -05:00
JazzMcNade 22385421ef Lang fix for range messaging 2024-06-28 01:25:53 -05:00
JazzMcNade dc103d286b Interaction wheel no longer lies about where it is actually clickable 2024-06-26 20:58:31 -05:00
Lily 766a7e5595 filled in a ton of missing langs 2024-06-26 19:43:46 -04:00
Paul 9f75d842d8 Lil generic cleanup 2024-06-26 19:47:58 +10:00
Paul 636e938789 Broader applyEffects functionality, implemented cry function in dex 2024-06-26 19:28:25 +10:00
Paul 26a4e9a7d8 Fixed misplaced \r in PokedexEntryProgress tripping up the license checker 2024-06-24 18:59:11 +10:00
Paul 6fd1e31c87 Fixed size display for dex 2024-06-24 18:41:00 +10:00
Paul 85a855be97 Licenses 2024-06-24 14:39:05 +10:00
Paul 4d108e424e Dex ported to 1.21 2024-06-24 14:37:34 +10:00
Paul b1333e490f Merge branch 'refs/heads/sega_bass_pro_fishing_2' into poker-decks
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/advancement/criterion/BattleCountableCriterion.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/gui/GuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonBakingOverrides.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/PokemonGuiUtils.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/battle/BattleOverlay.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/battle/subscreen/BattleSwitchPokemonSelection.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/data/CobblemonDataProvider.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/events/AdvancementHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/battle/BattleInitializePacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/starter/SetClientPlayerDataPacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/PlayerExtensions.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2024-06-24 11:20:24 +10:00
Village 9a57fc5d40 🃏 2024-06-23 20:08:32 -04:00
Paul 78bce64df2 Fixed hisui pokedex data not migrated to new format stuff 2024-06-23 16:53:31 +10:00
JazzMcNade 0e7b9bdd0c Refactoring getSendoutPosition 2024-06-13 20:02:30 -05:00
JazzMcNade 9c8ff24bf2 Enforcement of minimum spacing for pokemon entities during battle. 2024-06-12 01:20:22 -05:00
JazzMcNade 3738b035d1 Changed allowed ranges and range checking for most interactions 2024-06-11 20:15:45 -05:00
JazzMcNade 7a97b7e92a Added the ability to empty a move slot (forget a move) on the move swap screen 2024-06-08 17:28:09 -05:00
JPAKx4 2ac91b0731 Added data for pokedex and classes that process that data. Utility Scripts also contains two scripts used for generating data. Data not final. 2024-06-04 20:36:24 -05:00
JazzMcNade c689f7c48e Merge branch 'main' into TheSketchySmeargle 2024-06-04 00:24:20 -05:00
JazzMcNade 12592f437e Fixed bug with clients not receiving power point updates post battle for Sketch acquired moves on Smeargle 2024-06-04 00:23:01 -05:00
JazzMcNade 22565a0ed5 Fixed a bug with recognizing that a pair of players already have an existing challenge 2024-06-01 21:11:26 -05:00
JazzMcNade e9085a3339 Added lang key for multibattles in the interact gui 2024-06-01 20:11:52 -05:00
JazzMcNade 5d32d043a1 Refactored getSendoutPosition(), adjusted singles sendout positions 2024-06-01 16:10:30 -05:00
JazzMcNade 1028ba07af Pokemon in single battles are sent out a bit to the side for better viewing 2024-06-01 13:19:54 -05:00
JazzMcNade 86bd2240c3 Compacted Battle portraits 2024-05-29 19:14:05 -05:00
JazzMcNade 27b276fc36 Moves learned via Sketch now persist post battle 2024-05-28 16:17:12 -05:00
JazzMcNade 8fdb551fe8 Merge branch 'main' into DoublesAreTheFuture 2024-05-27 01:45:17 -05:00
Sterrezo 0f3104f9d4 Merge branch 'main' into sound 2024-05-27 01:33:14 +02:00
Sterrezo 21a32bd459 Updated all generic impact assets
Increased the volume of all generic impact sounds. Audio assets have been updated to have a 0.2ms delay to account for ogg file compression cutting the initial start of the sound, making the attack have less impact.
2024-05-26 14:25:34 +02:00
Tyzillion f9a37791b7 Evolution can now be canceled when withdrawn during evolution animation. 2024-05-26 00:17:22 -04:00
Tyzillion fb6e9f3493 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into evolution-effect
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/pokemon/evolution/Evolution.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/entity/PokemonClientDelegate.kt
2024-05-26 00:04:59 -04:00
JazzMcNade b851fa0d5f Merge branch 'main' into DoublesAreTheFuture 2024-05-25 19:35:26 -05:00
JPAKx4 ee73058f5b Added a count for amount of species with a specific knowledge level and getting the knowledge level of a specific species in ClientPokedex.kt . 2024-05-20 06:35:31 -05:00
JPAKx4 1d20051888 ScrollingWidget has a function for rendering the scrollbar, which is able to be overriden. 2024-05-19 18:15:42 -05:00
JPAKx4 5ec1ef72be Added searching to the Pokedex, and the "Invisible" property for pokemon. 2024-05-14 22:25:12 -05:00
JPAKx4 76560198b8 Updated Pokedex to Cobblemon 1.5 2024-05-11 19:57:43 -05:00
JPAKx4 b546327af9 Merge branch 'main' into its-dexter-time
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/keybind/CobblemonKeyBinds.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/events/AdvancementHandler.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/battle/BattleInitializePacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/starter/SetClientPlayerDataPacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/PlayerExtensions.kt
2024-05-11 19:45:55 -05:00
JazzMcNade 04d1f8c37e Added command to allow users to leave a multiteam without needing to find their teammate 2024-05-11 18:38:17 -05:00
JazzMcNade 2363d76f85 Added command portrait highlighting for multi-battles 2024-05-11 04:39:28 -05:00
JPAKx4 eead2724e7 Pokedex is Datapackable probably 2024-05-10 22:22:16 -05:00
JazzMcNade 419cb48327 Re-enabled targeting fainted slots. Removed target check that was generating false positive errors for target selection 2024-05-09 23:52:55 -05:00
JazzMcNade 8a91a58caa Items that did not have an opportunity to have their effect applied b/c of the battle ending are now refunded post battle. Refactored BagItem to specify the returnItem 2024-05-09 01:23:33 -05:00
JPAKx4 2b68ccd0f9 Forms in the Pokedex are read from the Pokedex Files now. 2024-05-02 14:49:28 -05:00
JPAKx4 5adefaac5e Pokedex is now based on files in the resources, and such is also datapackable. Forms still need to be fixed and the spreadsheet needs expanded as well. 2024-05-01 16:36:02 -05:00
JazzMcNade eee563f07a Fixed cancelling selection around fainted slots. Disabled cancelling item selections. 2024-04-29 01:02:54 -05:00
JazzMcNade a231250372 Triples: no longer mentions a fainted pokemon's name if a move targets a pokemon after it has already fainted. 2024-04-25 02:01:01 -05:00
JazzMcNade 14f486d086 Added language keys to differentiate between ally switch and triples shift 2024-04-25 01:33:42 -05:00
JazzMcNade c2f7f3d506 Merge branch 'main' into DoublesAreTheFuture 2024-04-23 23:53:12 -05:00
JazzMcNade 593f9cee03 Disabled single target selection against fainted slots 2024-04-23 21:36:14 -05:00
Paul ba6513942d Fixed evo_glow_time call not using query struct 2024-04-24 12:12:00 +10:00
Paul 84c7d36840 Merge remote-tracking branch 'origin/main' into evolution-effect 2024-04-24 12:00:20 +10:00
JazzMcNade f0821bc1d2 More precise revive switch selection checking 2024-04-23 19:56:53 -05:00
amo 084e5f744a early flash layer impl 2024-04-23 14:53:36 +01:00
Paul 90a1acb56e Fixed evolution animation being cancelled when the entity is pushed, minor fix to action effects 2024-04-22 15:03:44 +10:00
JazzMcNade ef7ad797d1 PvP doubles/triples now require a sufficient number of unfainted pokemon to start, Fainted pokemon can no longer be send as part of the initial sendout 2024-04-21 19:49:05 -05:00
JazzMcNade 56f86e15ae Selecting forfeit in a double/triple battle now short circuits any other pending action requests 2024-04-21 13:59:50 -05:00
JazzMcNade a285dbbe43 Fixed a number of issues with Revival Blessing and (Max) Revive bag item, removed a dupe of super effective message 2024-04-21 04:08:34 -05:00
JazzMcNade cc2783a553 Fixed softlock when 2 pokemon are ko'd but the player only has 1 pokemon in reserve 2024-04-18 21:37:06 -05:00
JazzMcNade 2ca67c805f Fixed double shift positioning in triples.
Fixed fainted pokemon portraits reappearing after shifting into a fainted slot
2024-04-17 21:58:45 -05:00
JazzMcNade 4b0f1e3d7d Merge Conflict: Fixed swap instruction string key 2024-04-17 01:25:02 -05:00
JazzMcNade 06a8c9e713 Fixed more merge conflicts 2024-04-17 01:02:31 -05:00
JazzMcNade a447228de1 More Merge Conflicts 2024-04-16 21:43:11 -05:00
JazzMcNade c6032fdaab Merge branch 'main' into DoublesAreTheFuture
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/ShowdownActionRequest.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/ShowdownInterpreter.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/interpreter/instructions/CritInstruction.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/interpreter/instructions/SuperEffectiveInstruction.kt
2024-04-16 21:16:11 -05:00
JazzMcNade 103af083a3 Fixed a Multibattle softlock when a player's last pokemon has fainted but their teammate has unfainted pokemon 2024-04-16 01:47:54 -05:00
JazzMcNade e67c0ebbb8 Added the ability for players to "team up" for Multibattles. Added Multibattle Support. 2024-04-15 21:54:45 -05:00
JazzMcNade a51d282007 Added Battle Portrait highlighting for the mon currently receiving commands in Doubles/Triples 2024-03-20 00:33:38 -05:00
JPAKx4 afb93ba15c Cleaned up the ScrollingWidget.kt and the children now that the Mixin is implemented. 2024-03-19 06:16:17 -05:00
Nick fef655065b Merge branch 'its-dexter-time' of gitlab.com:cable-mc/pokemon-cobbled into its-dexter-time 2024-03-18 19:18:58 -07:00
Nick 1d2ce79fba Fix scroll widget being slightly off on both x and y axis 2024-03-18 19:18:50 -07:00
JPAKx4 0b13ad2fbc Fixed the ScrollingWidget.kt to properly select entries based on mouse position. 2024-03-18 15:13:47 -05:00
JazzMcNade 3004c2a44c Added additional checks for doubles/triples exp gain 2024-03-17 20:06:36 -05:00
JazzMcNade a2a2d8860e Fixed another instance of giving orders to fainted mons. 2024-03-17 13:45:34 -05:00
JazzMcNade af81763577 Refactoring out function 2024-03-15 22:09:32 -05:00
JazzMcNade c3dafcc615 Added target declaration for super effective, resist, and crit on multitarget attack hits. 2024-03-15 01:30:34 -05:00
JazzMcNade 0340f54e2c Position shifting can now swap pokemon into fainted position slots. 2024-03-13 02:08:09 -05:00
JazzMcNade e2917b044a Added lang strings for different battle formats 2024-03-13 00:29:54 -05:00
JazzMcNade 34f00dbb05 Split BattleChallengePacket into BattleChallengePacket and BattleChallengeResponsePacket 2024-03-12 01:11:40 -05:00
JazzMcNade 93801ae6d5 Added Shifting to Triple Battles 2024-03-10 15:07:08 -05:00
JazzMcNade b50bf547f8 Battle effects now strike all targets in a multitarget attack. Fixed another softlock issue 2024-03-10 00:18:16 -06:00
JazzMcNade 01ac831c24 Fixed soft locking after a switch event 2024-03-09 18:01:49 -06:00
JazzMcNade adcccfee02 Fixed a bug in which during a forced switch event, the player would be requested to input actions on non-switching slots. 2024-03-07 23:56:47 -06:00
JPAKx4 365dd2c45c Began doing the "deltaDex" config file 2024-03-07 22:48:15 -06:00
JazzMcNade a97e8c819d Switch menu tiles are now vertically offset from the lowest active pokemon tiles 2024-03-07 00:42:49 -06:00
JazzMcNade 4eeaf5102f Added support for Ally Switch 2024-03-06 01:19:23 -06:00
JPAKx4 e9d4524a4f Worked on forms and added Weight/Height stuff. 2024-02-27 20:24:12 -06:00
JPAKx4 78c32e5396 Created a generic ScrollingWidget.kt and added a DescriptionWidget.kt for the PokedexGUI.kt 2024-02-27 13:35:09 -06:00
JPAKx4 58cb6295fa Merge remote-tracking branch 'origin/its-dexter-time' into its-dexter-time 2024-02-26 18:17:35 -06:00
JPAKx4 4bc94f8deb Made the info section render an animated pokemon. 2024-02-26 18:15:27 -06:00
apion 25d3d9f7da Made tint values travel down to emissive layers 2024-02-26 18:04:30 -05:00
JPAKx4 e5235cb121 Added Scroll bar to the PokedexGUI.kt 2024-02-26 16:42:22 -06:00
apion 3534dc0722 Added revoke command 2024-02-26 17:07:02 -05:00
apion ce5b94745e Fixed add only for pokemon with no alternate forms 2024-02-26 16:49:07 -05:00
apion 0868d71c59 Added command to fill pokedex, licenses 2024-02-26 05:42:28 -05:00
JPAKx4 801de096fd Work on Scrollbar and added the starter event to the PokedexHandler.kt 2024-02-25 22:04:25 -06:00
JPAKx4 347c56c484 Added Portraits and Text 2024-02-25 19:59:51 -06:00
JPAKx4 a184c8b960 Merge remote-tracking branch 'origin/its-dexter-time' into its-dexter-time 2024-02-25 17:46:47 -06:00
JazzMcNade d15307a809 The target menu now displays if a target is valid or not. Multitargeting is supported as well. 2024-02-25 17:13:42 -06:00
apion 950994d95c Added tracked data serialization 2024-02-25 06:29:41 -05:00
apion 19535fc81e Cleanup 2024-02-25 02:26:34 -05:00
apion a80938badf Moved pokedex storage to use nbt 2024-02-25 00:45:43 -05:00
apion a484ba6c68 Cool codec stuff 2024-02-24 22:55:51 -05:00
JPAKx4 8afe6d5b22 Added Slots for pokedex and sorting for the species. 2024-02-24 21:48:09 -06:00
apion 30ba386294 Started trying to do incremental updates 2024-02-24 20:20:22 -05:00
apion f2ae51df7d Small fixes 2024-02-24 17:57:32 -05:00
apion b5d354164c Added back previously tracked events 2024-02-24 16:18:37 -05:00
JazzMcNade 935fd53b70 Fixed pokemon positioning in doubles/triples. Fixed positioning in portraits/targeting. Added triples as a selectable battleType. 2024-02-24 14:00:52 -06:00
apion fe69659191 Merge remote-tracking branch 'origin/its-dexter-time' into its-dexter-time 2024-02-24 03:22:18 -05:00
apion 536fac3904 Restructured the pokedex so that we can configure exactly what data gets tracked. It is super cool 2024-02-24 03:22:08 -05:00
JPAKx4 77a416b699 Merge remote-tracking branch 'origin/its-dexter-time' into its-dexter-time 2024-02-23 21:10:23 -06:00
apionandJPAKx4 1e05d35e06 Added Justify Text Right and new text for the pokedex. 2024-02-23 21:10:07 -06:00
apion a84c72d703 Merge branch 'main' into its-dexter-time
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/GeneralPlayerData.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/PlayerDataStoreManager.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/factory/JsonPlayerDataStoreFactory.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/BattleBuilder.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/PlayerExtensions.kt
2024-02-23 20:39:27 -05:00
apion 0b29bbf82c Merge branch 'main' into its-dexter-time
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/Cobblemon.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/GeneralPlayerData.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/PlayerDataStoreManager.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/storage/player/factory/JsonPlayerDataStoreFactory.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/battles/BattleBuilder.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonClient.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/command/TestCommand.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/PlayerExtensions.kt
2024-02-23 20:39:07 -05:00
JPAKx4 35085c462e Created layout for Pokedex. Placeholder images added for the background. 2024-02-23 11:56:58 -06:00
JazzMcNade db33633406 Added sendout locations for doubles and triples first pass. 2024-02-23 02:12:19 -06:00
apion 809f1aeca3 Got incremental pokedex updates working 2024-02-23 01:06:56 -05:00
apion dfa76da95e Move onBattle logic to PokedexHandler 2024-02-23 00:07:36 -05:00
apion 776883c96d Small cleanup 2024-02-22 23:44:19 -05:00
JPAKx4 c5c58c0c60 Added events in PokedexHandler that update the server and client side pokedexes and added an optimization to track when a PokedexEntry was actually changed to reduce how much is sent on updates 2024-02-22 21:50:29 -06:00
JPAKx4 9861877f45 Merge remote-tracking branch 'origin/its-dexter-time' into its-dexter-time 2024-02-22 19:41:27 -06:00
apion 338a312485 Darken icon for encountered only mons 2024-02-22 20:14:32 -05:00
JPAKx4 a3b2bed484 Merge remote-tracking branch 'origin/its-dexter-time' into its-dexter-time
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/pokedex/Progress.kt
2024-02-22 19:00:34 -06:00
JPAKx4 fa2ac5d984 Refactored packages for pokedex networking 2024-02-22 19:00:02 -06:00
apion 951676e6bf Added icon to pokemon who have been encountered before 2024-02-22 19:56:33 -05:00
JazzMcNade 49095f73d5 Fainted Pokemon no longer display on the target selection. Added the ability to cancel the previous action in a double battle. 2024-02-22 00:17:20 -06:00
apion 15940ff0a6 Added Pokedex store, plus added tracking of wild pokemon encounters 2024-02-22 01:00:42 -05:00
apion bec608be96 Refactored storage system to make adding more types of stores easier. 2024-02-21 22:55:09 -05:00
JazzMcNade 2ffe107789 Added primitive targeting. Fixed an issue in which the client would attempt to give orders to a fainted slot. 2024-02-18 23:47:01 -06:00
JazzMcNade f2f6c3d0ef Added UI endpoint to initiate a double battle. Added primitive battleFormat selection for BattleChallengePacket 2024-02-14 00:35:24 -06:00
JPAKx4 3704865ddb Created several classes related to creating the pokedex. DTO has been handled, but may need to change depending on functionality. Added keybind for "k", which all it currently does is display test text and print the pokedex entry class memories into a log. 2023-11-25 22:31:29 -06:00
JPAKx4 8815e8f03e Created several classes related to creating the pokedex. DTO has been handled, but may need to change depending on functionality. Added keybind for "k", which all it currently does is display test text and print the pokedex entry class memories into a log. 2023-11-25 22:00:26 -06:00
JPAKx4 a2414f9ffc Created several classes related to creating the pokedex. DTO has been handled, but may need to change depending on functionality. Added keybind for "k", which all it currently does is display test text and print the pokedex entry class memories into a log. 2023-11-25 22:00:26 -06:00
JPAKx4 db8ee43fd3 Merge remote-tracking branch 'origin/main' into its-dexter-time
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/data/CobblemonDataProvider.kt
2023-11-19 16:19:21 -06:00
JPAKx4 7e755721a8 Added pokedex UI and net (very early progress) 2023-11-19 16:18:22 -06:00
MoeBoy76 231b3d2eac Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into its-dexter-time 2023-03-03 11:44:23 +11:00
MoeBoy76 ac4d36100a updated some parts per design and added some fail-safe checking 2023-03-03 11:43:37 +11:00
MoeBoy76 2bf1c39839 Initial dex code and testing for datapacks 2023-02-24 08:38:06 +11:00
MoeBoy76 ad2c307b60 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into its-dexter-time
# Conflicts:
#	common/src/main/resources/assets/cobblemon/sounds.json
2023-02-17 11:39:00 +11:00
MoeBoy76 74ba080937 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into its-dexter-time
# Conflicts:
#	common/src/main/resources/assets/cobblemon/sounds.json
2022-12-23 16:19:56 +11:00
2744 changed files with 89273 additions and 18296 deletions
+2 -1
View File
@@ -39,4 +39,5 @@ common/src/main/resources/assets/cobblemon/showdown
common/.fabric
# MacOS
.DS_Store
.DS_Store
.kotlin/sessions/kotlin-compiler-16609242564043830292.salive
+1 -1
View File
@@ -35,7 +35,7 @@ publish:
- neoforge/build/libs/*.jar
- fabric/build/libs/*.jar
rules:
- if: '$CI_COMMIT_BRANCH == "sega_bass_pro_fishing_2"'
- if: '$CI_COMMIT_BRANCH == "main"'
script:
- export GRADLE_OPTS="-Xmx4G -Xms4G"
- chmod +x ./gradlew
+3
View File
@@ -0,0 +1,3 @@
### Additions
- Added the Poké Dex as a craftable item.
- Poké Dexes can be placed on lecterns.
+6
View File
@@ -0,0 +1,6 @@
### Additions
- Added `moves` option to PokemonProperties, allowing you to set the moves of a Pokémon in commands and spawn files.
- Added /spawnnpc and /spawnnpcat commands.
### Fixes
- Fixed sync issues with recently learned moves where their PP would not go down until you logout and in.
+197 -119
View File
@@ -1,77 +1,36 @@
# Changelog
## [1.6.0 - The Bass Pro Fishing Update (Month Xth, 2024)](#1-6-0)
#### "Now that there's a fishing mechanic, the mod is actually good!"
### Fixes
- Fixed trading Pokémon setting their friendsip to 0 instead of the base value.
- Fixed a scenario where a Pokémon that rolled to spawn with a special Tera type sometimes has 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
### Additions
- 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. Why not?
- 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 property chaining support for duplicate CustomPokemonPropertyType elements.
- 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.
### Developer
- SpawnCause is now an implementation of SpawningInfluence.
- Added "forcedAspects" to Pokemon 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 sidemods but if you are affected by this then you were using it wrong! Use Pokemon.forcedAspects to fix it.
- Many types related to ``Pokemon`` including itself now have dedicated ``Codec``, please migrate to them from the NBT/JSON/PacketBuffer write/read methods.
- ``TeraTypes`` now implements ``Iterable``.
## [1.5.3](#1-5-3)
### Fixes
- Scaled down Amaura's fetus model to avoid clipping through the tank while animating
- Fixed Cubone's cry not having a sound.
- 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 Chimchar and Monferno T posing whenever they sleep.
- 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 Crumbling Arch not blending in with the world.
- Fixed Energy Root applying being usable on a fainted Pokemon.
- Fixed Pokémon entity not spawning 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 PC not saving when Pokemon was changed outside.
- Fixed shearble Pokemon not dropping correct wool colors.
- Fixed pasture spawning Pokemon 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
### Additions
- Added extra visuals to early berry growth stages
- 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.
- Added support for Double Battles, Triple Battles, and Multi-battles.
- CriticalCaptures and Pokédex progress capture multiplier now work with the Pokédex.
- Added extra visuals to early berry growth stages.
- Hidden Power now displays its effective typing.
- Moves impacted by the abilities Pixelate, Refrigerate, Aerilate, Galvanize, and Normalize now display as their altered typing.
- Added Polished Tumblestone and Tumblestone Brick block sets from Tumblestone, Black Tumblestone, and Sky Tumblestone.
- Added 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 cries to the following Pokémon
- Timburr, Gurdurr, Conkeldurr
- Golett, Golurk
### Changes
- 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
- Changes to mulch buffs/durations
- Dreepy is now shoulder mountable
- Link Cable recipe has been redesigned
- Updated potion sprites
- Weedle, Caterpie, Spearow, Smoochum, Mew, Murkrow, Larvitar, Taillow, Plusle, Minun, Beldum, Starly, Buneary, Combee, Pachirisu, Pidove, Petilil, Hisui Bias Petilil, Zorua, Hisuian Zorua, Elgyem, Fletchling, Skrelp, Klefki, Fomantis, Morelull, Dreepy, Shroodle, Tatsugiri, Glimmet, and Roaming Gimmighoul are now shoulder mountable
- Chikorita's ability to look around removed due to the awkwardness of it.
- Link Cable recipe has been redesigned
- Updated potion sprites
- 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.
- 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
- Moves can now be benched without specifying a replacement move, allowing for empty move slots.
- Moves learned via Sketch now persist after battle.
- Added `stonjourner_henge_ruins`, `luna_henge_ruins`, and `sol_henge_ruins` structures.
- 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 battle log messages for switching out Pokémon.
- Added Evolution particles and sounds 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.
- Added pokecenters to all 5 village types.
- 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.
- New config setting `displayEntityNameLabel` and `displayEntityLabelsWhenCrouchingOnly` to control what and when is displayed for the pokemon label
- `/freezepokemon` command to pause a Pokémon's animation at a specific point in time.
- Added `no_ai` and `freeze_frame` options to the `/spawnpokemon` command.
- Added shiny Pokémon particles with sound effects.
### Pokémon Added
#### Gen 2
@@ -85,17 +44,136 @@
#### Gen 3
- Wynaut
#### Gen 8
- Cramorant
#### Gen 9
- Farigiraf
### Added cries to the following Pokémon
- Timburr, Gurdurr, Conkeldurr
- Golett, Golurk
### Changes
- Kakuna, Beedrill, Snorlax, Munchlax, and Lurantis received model updates
- 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.
- Dreepy is now shoulder mountable.
- Updated potion sprites.
- Weedle, Caterpie, Spearow, Smoochum, Mew, Murkrow, Larvitar, Taillow, Plusle, Minun, Beldum, Starly, Buneary, Combee, Pachirisu, Pidove, Petilil, Hisui Bias Petilil, Zorua, Hisuian Zorua, Elgyem, Fletchling, Skrelp, Klefki, Fomantis, Morelull, Dreepy, Shroodle, Tatsugiri, Glimmet, and Roaming Gimmighoul are now shoulder mountable.
- Link Cable recipe has been redesigned.
- Updated sounds for Medicinal Leeks, Big Roots, Energy Roots and Revival Herbs.
- Updated UI sounds for clicking and evolving Pokémon.
- 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.
- Kakuna, Beedrill, Snorlax, Munchlax, Krabby, Kingler, and Lurantis received model updates.
- Vivillon wings will stop being clear when you remove any Vivillon related resourcepacks. The default pattern will be the meadow wings.
- Adjusted Pokémon sendout positions for single battles.
- 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.
- Updated party switching interface when in battle.
- Relic coin pouches can now be waterlogged.
- Pokemon Name (and level) labels are now only visible when crouching by default, set the `displayEntityLabelsWhenCrouchingOnly` to `false` to always them even when not crouching
- The "Press R to start battle prompt" will now disappear after a player's first battle has been won
- The default number of digits for the Pokédex number in the summary has been increased, from 3 to 4.
### Fixes
- Scaled down Amaura's fetus model to avoid clipping through the tank while animating.
- Fixed Cubone's cry not having a sound.
- 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 Chimchar and Monferno T-posing whenever they sleep.
- 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 Crumbling Arch not blending in with the world.
- Fixed Energy Root applying being usable on a fainted Pokémon.
- Fixed Pokémon entity not spawning 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 PC not saving when Pokémon was changed outside.
- 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.
- Evolution notification and UI sound is now correctly playing (again).
- Fix Starter prompt not showing up.
- Fix evolution now granting Pokédex entries.
- Fix Pokédex crash when a form is looked up without ever seeing the "normal" form.
- Fixed owned poké balls floating upwards if pausing mid-transition.
- 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 has 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.
- 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 T posing whenever they sleep.
- 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 sadder than Tandemaus!
- Fixed Slowking's battle idle.
- Fixed Grafaiai's walk speed to prevent model sliding.
- Fixed reviving items throwing an exception 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` from 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.
- Pokémon are now invincible 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 gains 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!
- Fixed the Ice Face ability activation being displayed incorrectly in a battle
### 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.
- `TeraTypes` now implements `Iterable`.
- `PokemonBattle` now starts on turn 0.
- SpawnCause is now an implementation of SpawningInfluence.
- 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.
- Many types related to ``Pokemon`` including itself now have dedicated ``Codec``, please migrate to them from the NBT/JSON/PacketBuffer write/read methods.
- 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``.
- PokemonBattle now starts on turn 0.
- All sounds related to evolving Pokémon have been moved to the "sounds/evolution" folder.
- 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.
### Data Pack & Resource Pack Creators
- 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.
- 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.
### 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/
## [1.5.2 (May 27th, 2024)](#1-5-2)
### Fixes
@@ -194,13 +272,13 @@
- 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
`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.
### Localization
@@ -506,7 +584,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- 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 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.
@@ -519,17 +597,17 @@ These are our compromise for having both regular and Hisuian forms of these Pok
### 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.
- 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 rerolls for a legal ability for the Pokémon.
- 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.
@@ -538,14 +616,14 @@ These are our compromise for having both regular and Hisuian forms of these Pok
### 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
`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:
@@ -554,10 +632,10 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- `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.
- 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
`JSON
{
"lightingData": {
"lightLevel": 14,
@@ -566,10 +644,10 @@ These are our compromise for having both regular and Hisuian forms of these Pok
"_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.
`
- 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.
## [1.4.1 (December 23rd, 2023)](#1-4-1)
@@ -585,7 +663,7 @@ These are our compromise for having both regular and Hisuian forms of these Pok
- 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 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.
@@ -1078,7 +1156,7 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 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.
@@ -1095,11 +1173,11 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 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.
@@ -1114,11 +1192,11 @@ Thank you so much to all of our community translators that bring the mod to the
- 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.
- 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
- `json
{
"type": "potion_effect",
"effect": "minecraft:slow_falling",
@@ -1127,18 +1205,18 @@ Thank you so much to all of our community translators that bring the mod to the
"showParticles": false,
"showIcon": false
}
```
- Renamed the ``walked_steps`` evolution requirement to ``blocks_traveled``.
`
- 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 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.
- 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.
@@ -1156,7 +1234,7 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 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.
@@ -1281,7 +1359,7 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 `/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.
@@ -1290,18 +1368,18 @@ Thank you so much to all of our community translators that bring the mod to the
- 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.
- 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.
@@ -1314,9 +1392,9 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 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``.
- 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.
@@ -1354,17 +1432,17 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 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 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 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 `/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.
@@ -1399,7 +1477,7 @@ Thank you so much to all of our community translators that bring the mod to the
- 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 / 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 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)).
+1 -1
View File
@@ -40,7 +40,7 @@ dependencies {
modApi(libs.molang)
// Integrations
// compileOnlyApi(libs.jei.api)
compileOnlyApi(libs.jei.api)
modCompileOnly(libs.bundles.fabric.integrations.compileOnly) {
isTransitive = false
}
@@ -1,23 +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;
import com.cobblemon.mod.common.entity.npc.NPCEntity;
import java.util.Collection;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.sensing.Sensor;
import net.minecraft.world.entity.ai.sensing.SensorType;
public class GenericsCheatClass {
// For some reason, doing this in the NPCEntity class in Kotlin gives confusing generic errors I could not resolve.
public static Brain.Provider<NPCEntity> createNPCBrain(Collection<MemoryModuleType<?>> memories, Collection<SensorType<? extends Sensor<? super NPCEntity>>> sensors) {
return Brain.provider(memories, sensors);
}
}
@@ -10,18 +10,12 @@ package com.cobblemon.mod.common.duck;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundSource;
public interface SoundSystemDuck {
public interface SoundEngineDuck {
void pauseSounds(@Nullable ResourceLocation id, @Nullable SoundSource category);
void resumeSounds(@Nullable ResourceLocation id, @Nullable SoundSource category);
void stopSounds(@Nullable ResourceLocation id, @Nullable SoundSource category);
Collection<SoundInstance> getSounds(@Nullable SoundSource category);
}
@@ -17,6 +17,4 @@ public interface SoundManagerDuck {
void pauseSounds(@Nullable ResourceLocation id, @Nullable SoundSource category);
void resumeSounds(@Nullable ResourceLocation id, @Nullable SoundSource category);
void stopSounds(@Nullable ResourceLocation id, @Nullable SoundSource category);
}
@@ -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.mixin;
import static com.cobblemon.mod.common.datafixer.CobblemonSchemas.VERSION_KEY;
import com.cobblemon.mod.common.datafixer.CobblemonSchemas;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.mojang.serialization.MapCodec;
import java.util.Optional;
import java.util.function.Supplier;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.IntTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.storage.ChunkStorage;
import net.minecraft.world.level.storage.DimensionDataStorage;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ChunkStorage.class)
public class ChunkStorageMixin {
//Modifies the NBT returned by the vanilla upgradeChunkTag to also incorporate cobblemon fixup stuff
@ModifyExpressionValue(
method = "upgradeChunkTag(Lnet/minecraft/resources/ResourceKey;Ljava/util/function/Supplier;Lnet/minecraft/nbt/CompoundTag;Ljava/util/Optional;)Lnet/minecraft/nbt/CompoundTag;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/datafix/DataFixTypes;updateToCurrentVersion(Lcom/mojang/datafixers/DataFixer;Lnet/minecraft/nbt/CompoundTag;I)Lnet/minecraft/nbt/CompoundTag;"
)
)
public CompoundTag cobblemon$doChunkFix(
CompoundTag vanillaFixed
) {
int curVersion = vanillaFixed.contains(VERSION_KEY) ? vanillaFixed.getInt(VERSION_KEY) : 0;
return DataFixTypes.CHUNK.update(CobblemonSchemas.getDATA_FIXER(), vanillaFixed, curVersion, CobblemonSchemas.DATA_VERSION);
}
@Inject(
method = "upgradeChunkTag(Lnet/minecraft/resources/ResourceKey;Ljava/util/function/Supplier;Lnet/minecraft/nbt/CompoundTag;Ljava/util/Optional;)Lnet/minecraft/nbt/CompoundTag;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/nbt/NbtUtils;addCurrentDataVersion(Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/nbt/CompoundTag;"
)
)
public void cobblemon$addChunkVersion(
ResourceKey<Level> resourceKey,
Supplier<DimensionDataStorage> supplier,
CompoundTag compoundTag,
Optional<ResourceKey<MapCodec<? extends ChunkGenerator>>> optional,
CallbackInfoReturnable<CompoundTag> cir
) {
compoundTag.put(VERSION_KEY, IntTag.valueOf(CobblemonSchemas.DATA_VERSION));
}
}
@@ -19,7 +19,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(CrashReport.class)
public final class CrashReportMixin {
@Inject(method = "getDetails", at = @At(value = "INVOKE", target = "Lnet/minecraft/SystemReport;appendToCrashReportString(Ljava/lang/StringBuilder;)V"))
@Inject(method = "getDetails(Ljava/lang/StringBuilder;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/SystemReport;appendToCrashReportString(Ljava/lang/StringBuilder;)V"))
public void cobblemon$printCobblemonDetails(StringBuilder builder, CallbackInfo callback) {
CrashReportCategory cobblemon = new CrashReportCategory("Cobblemon");
cobblemon.setDetail("Version", CobblemonBuildDetails.VERSION);
@@ -21,11 +21,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(DecoratedPotPatterns.class)
public abstract class DecoratedPotPatternsMixin {
@Inject(method = "getPatternFromItem", at=@At("HEAD"), cancellable = true)
private static void cobblemon$getCobblemonSherdTexture(Item sherd,
CallbackInfoReturnable<ResourceKey<DecoratedPotPattern>> cir) {
private static void cobblemon$getCobblemonSherdTexture(
Item sherd,
CallbackInfoReturnable<ResourceKey<DecoratedPotPattern>> cir
) {
if (CobblemonSherds.INSTANCE.getSherdToPattern().containsKey(sherd)) {
cir.setReturnValue(CobblemonSherds.INSTANCE.getSherdToPattern().get(sherd));
return;
cir.cancel();
}
}
}
@@ -0,0 +1,40 @@
/*
* 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 static com.cobblemon.mod.common.datafixer.CobblemonSchemas.VERSION_KEY;
import com.cobblemon.mod.common.datafixer.CobblemonSchemas;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.IntTag;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.world.level.chunk.storage.EntityStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(EntityStorage.class)
public class EntityStorageMixin {
//Modifies the NBT returned by the vanilla upgradeChunkTag to also incorporate cobblemon fixup stuff
@ModifyExpressionValue(
method = "method_31731(Lnet/minecraft/world/level/ChunkPos;Ljava/util/Optional;)Lnet/minecraft/world/level/entity/ChunkEntities;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/chunk/storage/SimpleRegionStorage;upgradeChunkTag(Lnet/minecraft/nbt/CompoundTag;I)Lnet/minecraft/nbt/CompoundTag;"
)
)
public CompoundTag cobblemon$doEntityFix(
CompoundTag vanillaFixed
) {
int curVersion = vanillaFixed.contains(VERSION_KEY) ? vanillaFixed.getInt(VERSION_KEY) : 0;
CompoundTag newTag = DataFixTypes.ENTITY_CHUNK.update(CobblemonSchemas.getDATA_FIXER(), vanillaFixed, curVersion, CobblemonSchemas.DATA_VERSION);
newTag.put(VERSION_KEY, IntTag.valueOf(CobblemonSchemas.DATA_VERSION));
return newTag;
}
}
@@ -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.mixin;
import com.cobblemon.mod.common.item.PokedexItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ItemInHandRenderer.class)
public class ItemInHandRendererMixin {
@Inject(method = "renderArmWithItem", at = @At(value = "HEAD"), cancellable = true)
private void cobblemon$renderArmWithItem(AbstractClientPlayer abstractClientPlayer, float f, float g, InteractionHand interactionHand, float h, ItemStack itemStack, float i, PoseStack poseStack, MultiBufferSource multiBufferSource, int j, CallbackInfo ci) {
if (abstractClientPlayer.isUsingItem() && abstractClientPlayer.getUseItem().getItem() instanceof PokedexItem) {
ci.cancel();
}
}
}
@@ -6,11 +6,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.pokeball;
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.ModAPI;
import com.cobblemon.mod.common.client.CobblemonBakingOverrides;
import com.cobblemon.mod.common.item.PokeBallItem;
import com.cobblemon.mod.common.item.PokedexItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.ItemModelShaper;
@@ -31,15 +33,40 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/*
I think it would be nice to maybe use the existing mixin we have for custom item rendering [BuiltinModelItemRendererMixin]
Obviously that would require changes. Potentially each item renderer defines what modes it overrides for?
*/
@Mixin(ItemRenderer.class)
public abstract class ItemRendererMixin {
@Unique private static final String MODEL_PATH = Cobblemon.implementation.getModAPI() == ModAPI.FABRIC ? "fabric_resource" : "standalone";
@Unique private final String MODEL_PATH = Cobblemon.implementation.getModAPI() == ModAPI.FABRIC ? "fabric_resource" : "standalone";
@Shadow @Final private ItemModelShaper itemModelShaper;
@Shadow public abstract void render(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, BakedModel model);
@Inject(
method = "render(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemDisplayContext;ZLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;IILnet/minecraft/client/resources/model/BakedModel;)V",
at = @At("HEAD"),
cancellable = true
)
private void cobblemon$overrideItemModel(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource multiBufferSource, int light, int overlay, BakedModel model, CallbackInfo ci) {
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED;
if (!shouldBe2d && stack.getItem() instanceof PokedexItem) {
BakedModel replacementModel = CobblemonBakingOverrides.INSTANCE.getPokedexOverride(((PokedexItem) stack.getItem()).getType()).getModel();
if (!cobblemon$isSameModel(model, replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
}
} else if (shouldBe2d && stack.getItem() instanceof PokeBallItem pokeBallItem) {
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(pokeBallItem.getPokeBall().getModel2d(), "inventory"));
if (!cobblemon$isSameModel(model, replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
}
}
}
@Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
private void cobblemon$bakePokeballModel(ItemStack stack, Level world, LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> cir) {
if (stack.getItem() instanceof PokeBallItem pokeBallItem) {
@@ -50,20 +77,14 @@ public abstract class ItemRendererMixin {
}
}
@Inject(
method = "render(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemDisplayContext;ZLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;IILnet/minecraft/client/resources/model/BakedModel;)V",
at = @At("HEAD"),
cancellable = true
)
private void cobblemon$determinePokeballModel(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) {
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED;
if (shouldBe2d && stack.getItem() instanceof PokeBallItem pokeBallItem) {
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(pokeBallItem.getPokeBall().getModel2d(), "inventory"));
if (!model.equals(replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, vertexConsumers, light, overlay, replacementModel);
}
}
// this method aims to cover an issue with modernfixes and it's "dynamic resource" causing the usual .equals check to always fail, resulting in a StackOverflow
// this falls back to comparing the model contents (e.g. location of the texture, width and height)
@Unique
private static boolean cobblemon$isSameModel(BakedModel original, BakedModel replacement) {
return original.equals(replacement) ||
(original.getParticleIcon().contents().name().equals(replacement.getParticleIcon().contents().name()) &&
original.getParticleIcon().contents().width() == replacement.getParticleIcon().contents().width() &&
original.getParticleIcon().contents().height() == replacement.getParticleIcon().contents().height());
}
}
@@ -0,0 +1,50 @@
/*
* 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.util.DataKeys;
import com.mojang.serialization.Dynamic;
import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.stream.Stream;
@Mixin(ItemStackComponentizationFix.class)
public class ItemStackComponentizationFixMixin
{
@Inject(method = "fixItemStack", at = @At("TAIL"))
private static void fixItemStack(ItemStackComponentizationFix.ItemStackData itemStackData, Dynamic<?> dynamic, CallbackInfo ci) {
cobblemon$attemptPokemonModelDataFix(itemStackData, dynamic);
}
@Unique
private static void cobblemon$attemptPokemonModelDataFix(ItemStackComponentizationFix.ItemStackData itemStackData, Dynamic<?> dynamic)
{
var species = itemStackData.removeTag(DataKeys.POKEMON_ITEM_SPECIES).asString();
var aspects = itemStackData.removeTag(DataKeys.POKEMON_ITEM_ASPECTS).asList(dynamic1 -> dynamic1);
var redTint = itemStackData.removeTag(DataKeys.POKEMON_ITEM_TINT_RED).asNumber();
var greenTint = itemStackData.removeTag(DataKeys.POKEMON_ITEM_TINT_GREEN).asNumber();
var blueTint = itemStackData.removeTag(DataKeys.POKEMON_ITEM_TINT_BLUE).asNumber();
var alphaTint = itemStackData.removeTag(DataKeys.POKEMON_ITEM_TINT_ALPHA).asNumber();
if(species.hasResultOrPartial() && aspects != null) {
var pokeComponent = dynamic.emptyMap().set("species", dynamic.createString(species.getOrThrow()));
pokeComponent = pokeComponent.set("aspects", dynamic.createList(aspects.stream()));
if(redTint.hasResultOrPartial() || blueTint.hasResultOrPartial() || greenTint.hasResultOrPartial() || alphaTint.hasResultOrPartial()) {
pokeComponent = pokeComponent.set("tint", dynamic.createList(Stream.of(redTint, greenTint, blueTint, alphaTint)
.map(x -> x.mapOrElse(Number::floatValue, error -> 0F))
.map(dynamic::createFloat)));
}
itemStackData.setComponent("cobblemon:pokemon_item", pokeComponent);
}
}
}
@@ -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.mixin;
import com.cobblemon.mod.common.block.entity.LecternBlockEntity;
import com.cobblemon.mod.common.CobblemonBlocks;
import com.cobblemon.mod.common.CobblemonSounds;
import com.cobblemon.mod.common.item.PokedexItem;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.ItemInteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.LecternBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
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;
import static net.minecraft.world.level.block.LecternBlock.HAS_BOOK;
@Mixin(LecternBlock.class)
public abstract class LecternBlockMixin {
@Inject(method = "useItemOn", at = @At(value = "HEAD"), cancellable = true)
private void cobblemon$useItemOn(ItemStack itemStack, BlockState blockState, Level world, BlockPos blockPos, Player player, InteractionHand interactionHand, BlockHitResult blockHitResult, CallbackInfoReturnable<ItemInteractionResult> cir) {
if (!world.isClientSide && itemStack.getItem() instanceof PokedexItem) {
BlockEntity blockEntity = world.getBlockEntity(blockPos);
if (!blockState.getValue(HAS_BOOK)
&& blockEntity instanceof net.minecraft.world.level.block.entity.LecternBlockEntity
&& blockState.getBlock() instanceof LecternBlock
) {
ItemStack pokedexItemStack = itemStack.copy();
Direction facing = blockState.getValue(HorizontalDirectionalBlock.FACING);
itemStack.consumeAndReturn(1, player);
blockEntity.setRemoved();
BlockState newBlockState = CobblemonBlocks.LECTERN.defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, facing);
world.setBlockAndUpdate(blockPos, newBlockState);
BlockEntity lecternEntity = world.getBlockEntity(blockPos);
if (lecternEntity instanceof LecternBlockEntity) {
((LecternBlockEntity) lecternEntity).setItemStack((pokedexItemStack));
}
world.playSound(null, blockPos, CobblemonSounds.POKEDEX_CLOSE, SoundSource.BLOCKS, 0.5F, 1.25F);
cir.setReturnValue(itemStack.isEmpty() && interactionHand == InteractionHand.MAIN_HAND ? ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION);
}
}
}
}
@@ -8,7 +8,7 @@
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.client.sound.battle.BattleMusicController;
import com.cobblemon.mod.common.client.sound.BattleMusicController;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.sounds.MusicManager;
@@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MusicManager.class)
public class MusicTrackerMixin {
public class MusicManagerMixin {
@Shadow @Final
private Minecraft minecraft;
@@ -10,8 +10,13 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
import com.cobblemon.mod.common.item.PokedexItem;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import net.minecraft.client.Minecraft;
import net.minecraft.client.MouseHandler;
import net.minecraft.util.Mth;
import org.objectweb.asm.Opcodes;
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;
@@ -23,6 +28,8 @@ public class PartyScrollMixin {
@Shadow
private double accumulatedScrollY;
@Shadow @Final private Minecraft minecraft;
@Inject(
method = "onScroll",
at = @At(
@@ -34,20 +41,37 @@ public class PartyScrollMixin {
),
cancellable = true
)
public void onMouseScroll(long window, double horizontal, double vertical, CallbackInfo ci) {
public void cobblemon$scrollParty(long window, double horizontal, double vertical, CallbackInfo ci) {
if (PartySendBinding.INSTANCE.getWasDown()) {
int i = (int)accumulatedScrollY;
int i = (int) accumulatedScrollY;
if (i > 0) {
while (i-- > 0) CobblemonClient.INSTANCE.getStorage().shiftSelected(false);
accumulatedScrollY -= i;
CobblemonClient.INSTANCE.getStorage().shiftSelected(false);
ci.cancel();
accumulatedScrollY = 0;
PartySendBinding.INSTANCE.actioned();
} else if (i < 0) {
while (i++ < 0) CobblemonClient.INSTANCE.getStorage().shiftSelected(true);
accumulatedScrollY -= i;
CobblemonClient.INSTANCE.getStorage().shiftSelected(true);
ci.cancel();
accumulatedScrollY = 0;
PartySendBinding.INSTANCE.actioned();
}
}
}
@Inject(
method = "onScroll",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/player/Inventory;swapPaint(D)V"
),
cancellable = true
)
public void cobblemon$doPokedexZoom(long window, double horizontal, double vertical, CallbackInfo ci) {
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
if (usageContext.getScanningGuiOpen()) {
usageContext.adjustZoom(vertical);
ci.cancel();
}
}
}
@@ -18,7 +18,18 @@ import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
import com.cobblemon.mod.common.pokemon.Pokemon;
import com.cobblemon.mod.common.util.CompoundTagExtensionsKt;
import com.cobblemon.mod.common.util.DataKeys;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -29,15 +40,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Objects;
import java.util.UUID;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
@Mixin(Player.class)
public abstract class PlayerMixin extends LivingEntity {
@@ -63,7 +65,7 @@ public abstract class PlayerMixin extends LivingEntity {
super(p_20966_, p_20967_);
}
@Inject(method = "respawnEntityOnShoulder", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/world/Level;)Ljava/util/Optional;"), cancellable = true)
@Inject(method = "respawnEntityOnShoulder", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;create(Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/world/level/Level;)Ljava/util/Optional;"), cancellable = true)
private void cobblemon$removePokemon(CompoundTag nbt, CallbackInfo ci) {
if (CompoundTagExtensionsKt.isPokemonEntity(nbt)) {
final UUID uuid = this.getPokemonID(nbt);
@@ -117,14 +119,12 @@ public abstract class PlayerMixin extends LivingEntity {
private void recallPokemon(UUID uuid) {
// We need to do this cause the Entity doesn't store a reference to its storage
try {
final PartyStore party = Cobblemon.INSTANCE.getStorage().getParty(this.uuid);
for (Pokemon pokemon : party) {
if (pokemon.getUuid().equals(uuid)) {
pokemon.recall();
}
final PartyStore party = Cobblemon.INSTANCE.getStorage().getParty(this.getUUID(), this.registryAccess());
for (Pokemon pokemon : party) {
if (pokemon.getUuid().equals(uuid)) {
pokemon.recall();
}
} catch (NoPokemonStoreException ignored) {}
}
}
private boolean isShoulderPokemon(CompoundTag nbt) {
@@ -159,4 +159,16 @@ public abstract class PlayerMixin extends LivingEntity {
}
}
}
@Inject(method = "isInvulnerableTo", at = @At("HEAD"), cancellable = true)
public void isInvulnerableTo(DamageSource source, CallbackInfoReturnable<Boolean> ci) {
if (!level().isClientSide) {
ServerPlayer player = (ServerPlayer)(Object)this;
boolean invulnerableInBattle = this.level().getGameRules().getBoolean(CobblemonGameRules.BATTLE_INVULNERABILITY);
boolean inBattle = Cobblemon.INSTANCE.getBattleRegistry().getBattleByParticipatingPlayer(player) != null;
if (invulnerableInBattle && inBattle) {
ci.setReturnValue(true);
}
}
}
}
@@ -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.mixin;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerRenderer.class)
public class PlayerRendererMixin {
@Inject(
method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V",
at = @At(value = "TAIL")
)
public void renderPlayer(AbstractClientPlayer player, float f, float g, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, CallbackInfo ci) {
CobblemonClient.INSTANCE.getRequests().onRenderPlayer(player, g);
}
}
@@ -8,8 +8,8 @@
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.client.sound.battle.BattleMusicController;
import com.cobblemon.mod.common.duck.SoundSystemDuck;
import com.cobblemon.mod.common.client.sound.BattleMusicController;
import com.cobblemon.mod.common.duck.SoundEngineDuck;
import com.google.common.collect.Multimap;
import com.mojang.blaze3d.audio.Channel;
import net.minecraft.client.resources.sounds.SoundInstance;
@@ -28,7 +28,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(SoundEngine.class)
public abstract class SoundSystemMixin implements SoundSystemDuck {
public abstract class SoundEngineMixin implements SoundEngineDuck {
@Shadow
private boolean loaded;
@@ -91,7 +91,7 @@ public abstract class SoundSystemMixin implements SoundSystemDuck {
/** Allows stopping all SoundInstances that belong to a queried category. */
@Inject(method = "stop(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/sounds/SoundSource;)V", at = @At("HEAD"), cancellable = true)
public void stopSoustopnds(@Nullable ResourceLocation id, @Nullable SoundSource category, CallbackInfo cb) {
public void stopSounds(@Nullable ResourceLocation id, @Nullable SoundSource category, CallbackInfo cb) {
if (id == null && category != null) {
this.instanceBySource.get(category).forEach(this::stop);
cb.cancel();
@@ -8,9 +8,12 @@
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.client.sound.battle.BattleMusicController;
import com.cobblemon.mod.common.client.sound.BlockEntitySoundTracker;
import com.cobblemon.mod.common.client.sound.EntitySoundTracker;
import com.cobblemon.mod.common.client.sound.BattleMusicController;
import com.cobblemon.mod.common.client.sound.SoundTracker;
import com.cobblemon.mod.common.duck.SoundManagerDuck;
import com.cobblemon.mod.common.duck.SoundSystemDuck;
import com.cobblemon.mod.common.duck.SoundEngineDuck;
import net.minecraft.client.resources.sounds.BiomeAmbientSoundsHandler;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.resources.sounds.UnderwaterAmbientSoundInstances;
@@ -55,19 +58,13 @@ public abstract class SoundManagerMixin implements SoundManagerDuck {
/** Pauses the queried SoundInstance(s). If id is null, will pause all sounds belonging to the SoundCategory. */
@Override
public void pauseSounds(@Nullable ResourceLocation id, @Nullable SoundSource category) {
((SoundSystemDuck)soundEngine).pauseSounds(id, category);
((SoundEngineDuck)soundEngine).pauseSounds(id, category);
}
/** Resumes the queried SoundInstance(s). If id is null, will resume all sounds belonging to the SoundCategory. */
@Override
public void resumeSounds(@Nullable ResourceLocation id, @Nullable SoundSource category) {
((SoundSystemDuck)soundEngine).resumeSounds(id, category);
}
/** Stops the queried SoundInstance(s). If id is null, will stop all sounds belonging to the SoundCategory. */
@Override
public void stopSounds(@Nullable ResourceLocation id, @Nullable SoundSource category) {
((SoundSystemDuck)soundEngine).stopSounds(id, category);
((SoundEngineDuck)soundEngine).resumeSounds(id, category);
}
/** Blocks filtered sounds from being played while a BattleMusicInstance is in progress. */
@@ -91,4 +88,10 @@ public abstract class SoundManagerMixin implements SoundManagerDuck {
public void playEnd(SoundInstance sound, int delay, CallbackInfo cb) {
if (ambientLoopCondition(sound)) this.pauseSounds(sound.getLocation(), SoundSource.AMBIENT);
}
/** Clears tracked sounds on the client when disconnected. */
@Inject(method = "stop()V", at = @At("TAIL"))
public void stop(CallbackInfo cb) {
SoundTracker.Companion.clear();
}
}
@@ -9,22 +9,26 @@
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.world.CobblemonStructureIDs;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.structure.PoolElementStructurePiece;
import net.minecraft.world.level.levelgen.structure.pools.JigsawPlacement;
import net.minecraft.world.level.levelgen.structure.pools.LegacySinglePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
import net.minecraft.world.level.levelgen.structure.pools.*;
import net.minecraft.world.level.levelgen.structure.pools.alias.PoolAliasLookup;
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.apache.commons.lang3.mutable.MutableObject;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.*;
@@ -39,11 +43,11 @@ public abstract class StructurePoolGeneratorMixin {
String pokecenter = "pokecenter";
String berry = "berry_farm";
structureGroups.put(CobblemonStructureIDs.PLAINS_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.DESERT_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.SAVANNA_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.SNOWY_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.TAIGA_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.VILLAGE_PLAINS_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.VILLAGE_DESERT_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.VILLAGE_SAVANNA_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.VILLAGE_SNOWY_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.VILLAGE_TAIGA_POKECENTER, Set.of(pokecenter));
structureGroups.put(CobblemonStructureIDs.SAVANNA_BERRY_SMALL, Set.of(berry));
structureGroups.put(CobblemonStructureIDs.SAVANNA_BERRY_LARGE, Set.of(berry));
@@ -117,53 +121,25 @@ public abstract class StructurePoolGeneratorMixin {
return reducedList.iterator();
}
@ModifyVariable(method = "tryPlacingChildren", at = @At("HEAD"), ordinal = 0, argsOnly = true)
private PoolElementStructurePiece injected(PoolElementStructurePiece poolStructurePiece) {
ResourceLocation structureLocationKey = getCobblemonOnlyLocation(poolStructurePiece.getElement());
@Inject(method = "tryPlacingChildren", at = @At(value = "NEW", target = "net/minecraft/world/level/levelgen/structure/PoolElementStructurePiece", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
private void afterTryPlacingChildren(
PoolElementStructurePiece poolElementStructurePiece,
MutableObject<VoxelShape> mutableObject,
int i,
boolean bl,
LevelHeightAccessor levelHeightAccessor,
RandomState randomState,
PoolAliasLookup poolAliasLookup,
LiquidSettings liquidSettings,
CallbackInfo ci,
@Local(ordinal = 1) StructurePoolElement structurePoolElement
) {
ResourceLocation structureLocationKey = getCobblemonOnlyLocation(structurePoolElement);
if (structureLocationKey != null) {
incrementStructureCount(structureLocationKey);
}
return poolStructurePiece;
}
// This doesn't SEEM necessary? It appears to work without.
// @Inject(method = "generatePiece", at = @At("HEAD"))
// private void beforeGeneratePiece(PoolStructurePiece piece, MutableObject<VoxelShape> pieceShape, int minY, boolean modifyBoundingBox, HeightLimitView world, NoiseConfig noiseConfig, CallbackInfo ci) {
//// Identifier structureLocationKey = getCobblemonOnlyLocation(piece.getPoolElement());
////
//// if (structureLocationKey != null) {
//// Integer currentlyGenerated = generatedStructureCounts.get(structureLocationKey);
//// if (currentlyGenerated == null) currentlyGenerated = 0;
//// generatedStructureCounts.put(structureLocationKey, currentlyGenerated + 1);
//// }
////
//// List<StructurePoolBasedGenerator.ShapedPoolStructurePiece> reducedStructurePiecesList = structurePieces.stream().toList();
////
//// for (Identifier maxStructureLocationKey : structureMaxes.keySet()) {
//// Integer maxAllowed = structureMaxes.get(maxStructureLocationKey);
////
//// Integer currentlyGenerated = generatedStructureCounts.get(maxStructureLocationKey);
//// if (currentlyGenerated == null) currentlyGenerated = 0;
//// if (currentlyGenerated < maxAllowed) {
//// continue;
//// }
////
//// //Already have max so need to remove
//// reducedStructurePiecesList = reducedStructurePiecesList.stream()
//// .filter(shapedStructurePiece -> {
//// Identifier locationKey = getCobblemonOnlyLocation(shapedStructurePiece.piece.getPoolElement());
//// if (locationKey == null) {
//// return true;
//// }
////
//// return !locationKey.equals(maxStructureLocationKey);
//// })
//// .collect(Collectors.toList());
//// }
////
//// structurePieces = new ArrayDeque<>(reducedStructurePiecesList);
// }
private static ResourceLocation getCobblemonOnlyLocation(StructurePoolElement structurePoolElement) {
ResourceLocation location = getLocationIfAvailable(structurePoolElement);
if (location == null) return null;
@@ -186,26 +162,4 @@ public abstract class StructurePoolGeneratorMixin {
return null;
}
}
// private List<StructurePoolElement> removeInstanceOfLocationKeyFrom(List<StructurePoolElement> structureList, Integer allowedNumberOfInstances, Identifier locationKey) {
// List<StructurePoolElement> reducedList = new ArrayList<>();
// int instancesFound = 0;
//
// for (StructurePoolElement structurePoolElement: structureList) {
// Identifier structureKey = getCobblemonOnlyLocation(structurePoolElement);
// if (structureKey == null || !structureKey.equals(locationKey)) {
// reducedList.add(structurePoolElement);
// continue;
// }
//
// if (instancesFound >= allowedNumberOfInstances) {
// continue;
// }
//
// reducedList.add(structurePoolElement);
// instancesFound++;
// }
//
// return reducedList;
// }
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;
import org.jetbrains.annotations.Nullable;
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(TargetingConditions.class)
public class TargetingConditionsMixin {
@Inject(method = "test", at = @At("HEAD"), cancellable = true)
public void test(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable<Boolean> ci) {
if (targetEntity instanceof ServerPlayer player) {
boolean canTargetInBattle = player.level().getGameRules().getBoolean(CobblemonGameRules.MOB_TARGET_IN_BATTLE);
boolean targetInBattle = Cobblemon.INSTANCE.getBattleRegistry().getBattleByParticipatingPlayer(player) != null;
if (!canTargetInBattle && targetInBattle) ci.setReturnValue(false);
}
}
}
@@ -0,0 +1,68 @@
/*
* 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.Cobblemon;
import com.cobblemon.mod.common.CobblemonVillagerProfessions;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import kotlin.Pair;
import net.minecraft.ChatFormatting;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.monster.ZombieVillager;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.npc.VillagerProfession;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RenderLayer.class)
public abstract class VillagerProfessionLayerMixin {
@Inject(method = "renderColoredCutoutModel", at = @At(value = "HEAD"), cancellable = true)
private static <T extends LivingEntity> void cobblemon$renderVillagerProfessionLayer(EntityModel<T> entityModel, ResourceLocation resourceLocation, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, T livingEntity, int j, CallbackInfo ci) {
if (resourceLocation.getNamespace().equals(Cobblemon.MODID)) {
VillagerProfession profession = null;
boolean isZombie = false;
if (livingEntity instanceof Villager) profession = ((Villager) livingEntity).getVillagerData().getProfession();
if (livingEntity instanceof ZombieVillager) {
profession = ((ZombieVillager) livingEntity).getVillagerData().getProfession();
isZombie = true;
}
Pair<String, String[]> override = CobblemonVillagerProfessions.INSTANCE.getNameTagOverride(profession);
if (profession != null && override != null) {
String entityName = ChatFormatting.stripFormatting(livingEntity.getName().getString());
boolean nameMatches = false;
for (String name: override.getSecond())
if (entityName.endsWith(name)) {
nameMatches = true;
break;
}
if (nameMatches && resourceLocation.equals(getProfessionResourceLocation(resourceLocation.getNamespace(), ResourceLocation.parse(profession.name()).getPath(), isZombie))) {
ResourceLocation textureLocation = getProfessionResourceLocation(resourceLocation.getNamespace(), override.getFirst(), isZombie);
VertexConsumer vertexConsumer = multiBufferSource.getBuffer(RenderType.entityCutoutNoCull(textureLocation));
entityModel.renderToBuffer(poseStack, vertexConsumer, i, LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0F), j);
ci.cancel();
}
}
}
}
private static ResourceLocation getProfessionResourceLocation(String namespace, String profession, Boolean isZombie) {
return ResourceLocation.fromNamespaceAndPath(namespace, "textures/entity/" + (isZombie ? "zombie_villager" : "villager") + "/profession/" + profession + ".png");
}
}
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.world.level.biome.Biome;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Biome.class)
public interface BiomeAccessor {
@Accessor("climateSettings")
Biome.ClimateSettings getClimateSettings();
}
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.client.gui.components.AbstractSelectionList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AbstractSelectionList.class)
public interface EntryListWidgetAccessor {
@Accessor("renderHeader")
boolean getRenderHeader();
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import net.minecraft.client.player.AbstractClientPlayer;
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(AbstractClientPlayer.class)
public class AbstractClientPlayerMixin {
@Inject(
method = "getFieldOfViewModifier()F",
at = @At(
value = "HEAD"
),
cancellable = true
)
public void cobblemon$getPokedexFovMultiplier(CallbackInfoReturnable<Float> cir) {
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
if (usageContext.getScanningGuiOpen()) {
cir.setReturnValue(usageContext.getFovMultiplier());
}
}
}
@@ -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.mixin.client;
import com.cobblemon.mod.common.client.gui.ScrollingWidget;
import net.minecraft.client.gui.components.AbstractSelectionList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(AbstractSelectionList.class)
public abstract class EntryListWidgetMixin {
@SuppressWarnings("ConstantValue")
@ModifyConstant(method = "getEntryAtPosition", constant = @Constant(intValue = 4))
public int cobblemon$adjustOnlyIfNecessary(int input) {
if(ScrollingWidget.class.isInstance(this)) {
return 0;
}
return input;
}
}
@@ -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.mixin.client;
import com.cobblemon.mod.common.client.CobblemonClient;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiGraphics;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* Mixin to give us a hook to render the PartyOverlay below the Chat
*
* @author Qu
* @since 2022-02-22
*/
@Mixin(Gui.class)
public class GuiMixin {
//This injects into the actual BooleanSupplier lambda for the "this.layers.add(layeredDraw, () -> !minecraft.options.hideGui)" call
// sus af. You have to get the method name by looking at the bytecode of the class. Can do in intellij By clicking View -> Show Bytecode (top left)
@Inject(method = "method_55797", at = @At("HEAD"), cancellable = true)
private static void cobblemon$dontRenderUiInPokedex(Minecraft minecraft, CallbackInfoReturnable<Boolean> cir) {
if (CobblemonClient.INSTANCE.getPokedexUsageContext().getScanningGuiOpen() && minecraft.options.getCameraType().isFirstPerson()) {
cir.setReturnValue(false);
}
}
}
@@ -16,12 +16,7 @@ import com.cobblemon.mod.common.api.drop.CommandDropEntry
import com.cobblemon.mod.common.api.drop.DropEntry
import com.cobblemon.mod.common.api.drop.ItemDropEntry
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.CobblemonEvents.BATTLE_VICTORY
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
import com.cobblemon.mod.common.api.events.CobblemonEvents.EVOLUTION_COMPLETE
import com.cobblemon.mod.common.api.events.CobblemonEvents.LEVEL_UP_EVENT
import com.cobblemon.mod.common.api.events.CobblemonEvents.POKEMON_CAPTURED
import com.cobblemon.mod.common.api.events.CobblemonEvents.TRADE_COMPLETED
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
@@ -48,7 +43,6 @@ import com.cobblemon.mod.common.api.spawning.prospecting.SpawningProspector
import com.cobblemon.mod.common.api.starter.StarterHandler
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
import com.cobblemon.mod.common.api.storage.adapter.flatfile.FileStoreAdapter
import com.cobblemon.mod.common.api.storage.adapter.flatfile.JSONStoreAdapter
import com.cobblemon.mod.common.api.storage.adapter.flatfile.NBTStoreAdapter
@@ -56,9 +50,11 @@ import com.cobblemon.mod.common.api.storage.factory.FileBackedPokemonStoreFactor
import com.cobblemon.mod.common.api.storage.molang.NbtMoLangDataStoreFactory
import com.cobblemon.mod.common.api.storage.pc.PCStore
import com.cobblemon.mod.common.api.storage.pc.link.PCLinkManager
import com.cobblemon.mod.common.api.storage.player.PlayerDataStoreManager
import com.cobblemon.mod.common.api.storage.player.factory.JsonPlayerDataStoreFactory
import com.cobblemon.mod.common.api.storage.player.factory.MongoPlayerDataStoreFactory
import com.cobblemon.mod.common.api.storage.player.PlayerInstancedDataStoreManager
import com.cobblemon.mod.common.api.storage.player.PlayerInstancedDataStoreTypes
import com.cobblemon.mod.common.api.storage.player.adapter.DexDataNbtBackend
import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataJsonBackend
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.BagItems
@@ -68,19 +64,23 @@ 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.command.argument.DexArgumentType
import com.cobblemon.mod.common.command.argument.DialogueArgumentType
import com.cobblemon.mod.common.command.argument.FormArgumentType
import com.cobblemon.mod.common.command.argument.MoveArgumentType
import com.cobblemon.mod.common.command.argument.NPCClassArgumentType
import com.cobblemon.mod.common.command.argument.PartySlotArgumentType
import com.cobblemon.mod.common.command.argument.PokemonArgumentType
import com.cobblemon.mod.common.command.argument.PokemonPropertiesArgumentType
import com.cobblemon.mod.common.command.argument.PokemonStoreArgumentType
import com.cobblemon.mod.common.command.argument.SpawnBucketArgumentType
import com.cobblemon.mod.common.command.argument.SpeciesArgumentType
import com.cobblemon.mod.common.config.CobblemonConfig
import com.cobblemon.mod.common.config.LastChangedVersion
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.PokedexHandler
import com.cobblemon.mod.common.events.ServerTickHandler
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
import com.cobblemon.mod.common.permission.LaxPermissionValidator
@@ -92,7 +92,9 @@ import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
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.properties.tags.PokemonFlagProperty
@@ -103,10 +105,7 @@ import com.cobblemon.mod.common.util.*
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
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
@@ -130,6 +129,7 @@ object Cobblemon {
const val MODID = CobblemonBuildDetails.MOD_ID
const val VERSION = CobblemonBuildDetails.VERSION
const val CONFIG_PATH = "config/$MODID/main.json"
@JvmField
val LOGGER: Logger = LogManager.getLogger()
lateinit var implementation: CobblemonImplementation
@@ -151,7 +151,7 @@ object Cobblemon {
val battleRegistry = BattleRegistry
var storage = PokemonStoreManager()
var molangData = NbtMoLangDataStoreFactory
lateinit var playerData: PlayerDataStoreManager
lateinit var playerDataManager: PlayerInstancedDataStoreManager
lateinit var starterConfig: StarterConfig
val dataProvider: DataProvider = CobblemonDataProvider
var permissionValidator: PermissionValidator by Delegates.observable(LaxPermissionValidator().also { it.initialize() }) { _, _, newValue -> newValue.initialize() }
@@ -162,7 +162,7 @@ object Cobblemon {
this.implementation = implementation
this.LOGGER.info("Launching Cobblemon ${CobblemonBuildDetails.VERSION}${if(CobblemonBuildDetails.SNAPSHOT) "-SNAPSHOT" else ""} ")
if(CobblemonBuildDetails.SNAPSHOT) {
if (CobblemonBuildDetails.SNAPSHOT) {
this.LOGGER.info(" - Git Commit: ${smallCommitHash()} (https://gitlab.com/cable-mc/cobblemon/-/commit/${CobblemonBuildDetails.GIT_COMMIT})")
this.LOGGER.info(" - Branch: ${CobblemonBuildDetails.BRANCH}")
}
@@ -175,6 +175,7 @@ object Cobblemon {
implementation.registerEntityTypes()
implementation.registerEntityAttributes()
implementation.registerBlockEntityTypes()
implementation.registerVillagers()
implementation.registerWorldGenFeatures()
implementation.registerParticles()
implementation.registerEntityDataSerializers()
@@ -199,15 +200,15 @@ object Cobblemon {
DATA_SYNCHRONIZED.subscribe {
storage.onPlayerDataSync(it)
playerData.get(it).sendToPlayer(it)
playerDataManager.syncAllToPlayer(it)
starterHandler.handleJoin(it)
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel).sendToPlayer(it)
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel, this.config.displayEntityNameLabel).sendToPlayer(it)
}
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe {
PCLinkManager.removeLink(it.player.uuid)
BattleRegistry.getBattleByParticipatingPlayer(it.player)?.stop()
BattleRegistry.onPlayerDisconnect(it.player)
storage.onPlayerDisconnect(it.player)
playerData.onPlayerDisconnect(it.player)
playerDataManager.onPlayerDisconnect(it.player)
TradeManager.onLogoff(it.player)
}
PlatformEvents.PLAYER_DEATH.subscribe {
@@ -232,9 +233,6 @@ object Cobblemon {
}
}
// Register the grow_tumblestone advancement
PlatformEvents.RIGHT_CLICK_BLOCK.subscribe { AdvancementHandler.onTumbleStonePlaced(it) }
PlatformEvents.CHANGE_DIMENSION.subscribe {
it.player.party().forEach { pokemon -> pokemon.entity?.recallWithAnimation() }
}
@@ -250,6 +248,8 @@ object Cobblemon {
}
HeldItemProvider.register(CobblemonHeldItemManager, Priority.LOWEST)
}
fun initialize() {
@@ -277,6 +277,8 @@ object Cobblemon {
CustomPokemonProperty.register(HiddenAbilityPropertyType)
CustomPokemonProperty.register(AspectPropertyType)
CustomPokemonProperty.register(UnaspectPropertyType)
CustomPokemonProperty.register(FreezeFrameProperty)
CustomPokemonProperty.register(NoAIProperty)
ifDedicatedServer {
isDedicatedServer = true
@@ -291,16 +293,21 @@ object Cobblemon {
}
PlatformEvents.SERVER_STARTING.subscribe { event ->
val server = event.server
playerData = PlayerDataStoreManager().also { it.setup(server) }
playerDataManager = PlayerInstancedDataStoreManager().also { it.setup(server) }
val mongoClient: MongoClient?
val pokemonStoreRoot = server.getWorldPath(LevelResource.ROOT).resolve("pokemon").toFile()
val storeAdapter = when (config.storageFormat) {
"nbt", "json" -> {
val jsonFactory = JsonPlayerDataStoreFactory()
jsonFactory.setup(server)
playerData.setFactory(jsonFactory)
val generalJsonFactory = CachedPlayerDataStoreFactory(PlayerDataJsonBackend())
generalJsonFactory.setup(server)
val pokedexNbtFactory = CachedPlayerDataStoreFactory(DexDataNbtBackend())
pokedexNbtFactory.setup(server)
playerDataManager.setFactory(generalJsonFactory, PlayerInstancedDataStoreTypes.GENERAL)
playerDataManager.setFactory(pokedexNbtFactory, PlayerInstancedDataStoreTypes.POKEDEX)
if (config.storageFormat == "nbt") {
NBTStoreAdapter(pokemonStoreRoot.absolutePath, useNestedFolders = true, folderPerClass = true)
@@ -313,7 +320,9 @@ object Cobblemon {
}
}
/*
"mongodb" -> {
/*
try {
Class.forName("com.mongodb.client.MongoClient")
@@ -322,14 +331,18 @@ object Cobblemon {
.build()
mongoClient = MongoClients.create(mongoClientSettings)
val mongoFactory = MongoPlayerDataStoreFactory(mongoClient, config.mongoDBDatabaseName)
playerData.setFactory(mongoFactory)
playerData.setFactory(mongoFactory, PlayerInstancedDataStoreType.GENERAL)
MongoDBStoreAdapter(mongoClient, config.mongoDBDatabaseName)
} catch (e: ClassNotFoundException) {
LOGGER.error("MongoDB driver not found.")
throw e
}
*/
}
*/
else -> throw IllegalArgumentException("Unsupported storageFormat: ${config.storageFormat}")
}
.with(ReforgedConversion(server.getWorldPath(LevelResource.ROOT))) as FileStoreAdapter<*>
@@ -345,22 +358,14 @@ object Cobblemon {
}
PlatformEvents.SERVER_STOPPED.subscribe {
storage.unregisterAll()
playerData.saveAll()
storage.unregisterAll(it.server.registryAccess())
playerDataManager.saveAllStores()
}
PlatformEvents.SERVER_STARTED.subscribe {
bestSpawner.onServerStarted()
battleRegistry.onServerStarted()
}
PlatformEvents.SERVER_TICK_POST.subscribe { ServerTickHandler.onTick(it.server) }
POKEMON_CAPTURED.subscribe { AdvancementHandler.onCapture(it) }
// EGG_HATCH.subscribe { AdvancementHandler.onHatch(it) }
BATTLE_VICTORY.subscribe { AdvancementHandler.onWinBattle(it) }
EVOLUTION_COMPLETE.subscribe(Priority.LOWEST) { event ->
AdvancementHandler.onEvolve(event)
}
LEVEL_UP_EVENT.subscribe { AdvancementHandler.onLevelUp(it) }
TRADE_COMPLETED.subscribe { AdvancementHandler.onTradeCompleted(it) }
BagItems.observable.subscribe {
LOGGER.info("Starting dummy Showdown battle to force it to pre-load data.")
@@ -372,8 +377,12 @@ object Cobblemon {
).ifSuccessful { it.mute = true }
}
//To whomever is merging, this is moved out of Cobblemon and into the CobblemonImplementations
//CobblemonSherds.registerSherds()
registerEventHandlers()
}
fun registerEventHandlers() {
AdvancementHandler.registerListeners()
PokedexHandler.registerListeners()
}
fun getLevel(dimension: ResourceKey<Level>): Level? {
@@ -471,13 +480,16 @@ object Cobblemon {
}
private fun registerArgumentTypes() {
this.implementation.registerCommandArgument(cobblemonResource("pokemon"), PokemonArgumentType::class, SingletonArgumentInfo.contextFree(PokemonArgumentType::pokemon))
this.implementation.registerCommandArgument(cobblemonResource("pokemon"), SpeciesArgumentType::class, SingletonArgumentInfo.contextFree(SpeciesArgumentType::species))
this.implementation.registerCommandArgument(cobblemonResource("pokemon_properties"), PokemonPropertiesArgumentType::class, SingletonArgumentInfo.contextFree(PokemonPropertiesArgumentType::properties))
this.implementation.registerCommandArgument(cobblemonResource("spawn_bucket"), SpawnBucketArgumentType::class, SingletonArgumentInfo.contextFree(SpawnBucketArgumentType::spawnBucket))
this.implementation.registerCommandArgument(cobblemonResource("move"), MoveArgumentType::class, SingletonArgumentInfo.contextFree(MoveArgumentType::move))
this.implementation.registerCommandArgument(cobblemonResource("party_slot"), PartySlotArgumentType::class, SingletonArgumentInfo.contextFree(PartySlotArgumentType::partySlot))
this.implementation.registerCommandArgument(cobblemonResource("pokemon_store"), PokemonStoreArgumentType::class, SingletonArgumentInfo.contextFree(PokemonStoreArgumentType::pokemonStore))
this.implementation.registerCommandArgument(cobblemonResource("dialogue"), DialogueArgumentType::class, SingletonArgumentInfo.contextFree(DialogueArgumentType::dialogue))
this.implementation.registerCommandArgument(cobblemonResource("form"), FormArgumentType::class, SingletonArgumentInfo.contextFree(FormArgumentType::form))
this.implementation.registerCommandArgument(cobblemonResource("dex"), DexArgumentType::class, SingletonArgumentInfo.contextFree (DexArgumentType::dex))
this.implementation.registerCommandArgument(cobblemonResource("npc_class"), NPCClassArgumentType::class, SingletonArgumentInfo.contextFree(NPCClassArgumentType::npcClass))
}
}
@@ -14,6 +14,8 @@ object CobblemonActivities {
val activities = mutableListOf<Activity>()
val BATTLING_ACTIVITY = Activity("pokemon_battling")
val NPC_BATTLING = Activity("npc_battling")
val NPC_ACTION_EFFECT = Activity("npc_action_effect")
val NPC_CHATTING = Activity("npc_chatting")
fun register(activity: Activity): Activity {
activities.add(activity)
@@ -36,6 +36,9 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
@JvmField
val PC: BlockEntityType<PCBlockEntity> = this.create("pc", BlockEntityType.Builder.of(::PCBlockEntity, CobblemonBlocks.PC).build(null))
@JvmField
val LECTERN: BlockEntityType<LecternBlockEntity> = this.create("lectern", BlockEntityType.Builder.of(::LecternBlockEntity, CobblemonBlocks.LECTERN).build(null))
@JvmField
val BERRY = this.create("berry", BlockEntityType.Builder.of(::BerryBlockEntity, *CobblemonBlocks.berries().values.toTypedArray()).build(null))
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.block.*
import com.cobblemon.mod.common.block.LecternBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
@@ -263,6 +264,27 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
)
)
@JvmField
val SMOOTH_TUMBLESTONE = this.create("smooth_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
@JvmField
val SMOOTH_TUMBLESTONE_STAIRS = this.create("smooth_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(SMOOTH_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SMOOTH_TUMBLESTONE)))
@JvmField
val SMOOTH_TUMBLESTONE_SLAB = this.create("smooth_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
@JvmField
val TUMBLESTONE_BRICKS = this.create("tumblestone_bricks", Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
@@ -270,8 +292,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
))
@JvmField
val TUMBLESTONE_BRICK_STAIRS = this.create("tumblestone_brick_stairs", StairsBlockInvoker.`cobblemon$create`(TUMBLESTONE_BRICKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(TUMBLESTONE_BRICKS)))
@JvmField
@@ -342,6 +363,27 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
)
)
@JvmField
val SMOOTH_SKY_TUMBLESTONE = this.create("smooth_sky_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
@JvmField
val SMOOTH_SKY_TUMBLESTONE_STAIRS = this.create("smooth_sky_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(SMOOTH_SKY_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SMOOTH_SKY_TUMBLESTONE)))
@JvmField
val SMOOTH_SKY_TUMBLESTONE_SLAB = this.create("smooth_sky_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
@JvmField
val SKY_TUMBLESTONE_BRICKS = this.create("sky_tumblestone_bricks",
Block(
BlockBehaviour.Properties.of()
@@ -422,6 +464,28 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
@JvmField
val SMOOTH_BLACK_TUMBLESTONE = this.create("smooth_black_tumblestone",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
)
)
@JvmField
val SMOOTH_BLACK_TUMBLESTONE_STAIRS = this.create("smooth_black_tumblestone_stairs", StairsBlockInvoker.`cobblemon$create`(SMOOTH_BLACK_TUMBLESTONE.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SMOOTH_BLACK_TUMBLESTONE)))
@JvmField
val SMOOTH_BLACK_TUMBLESTONE_SLAB = this.create("smooth_black_tumblestone_slab", SlabBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_BLACK)
.strength(1.0F)
.sound(CobblemonSounds.TUMBLESTONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BASEDRUM)
))
@JvmField
val BLACK_TUMBLESTONE_BRICKS = this.create("black_tumblestone_bricks",
Block(
@@ -464,6 +528,117 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
)
)
@JvmField
val FIRE_STONE_BLOCK = this.create("fire_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.FIRE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val WATER_STONE_BLOCK = this.create("water_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.WATER)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val THUNDER_STONE_BLOCK = this.create("thunder_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.GLOW_LICHEN)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val LEAF_STONE_BLOCK = this.create("leaf_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_GREEN)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val ICE_STONE_BLOCK = this.create("ice_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.ICE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val SUN_STONE_BLOCK = this.create("sun_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.TERRACOTTA_ORANGE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val MOON_STONE_BLOCK = this.create("moon_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.DEEPSLATE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val SHINY_STONE_BLOCK = this.create("shiny_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.QUARTZ)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val DAWN_STONE_BLOCK = this.create("dawn_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.DIAMOND)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val DUSK_STONE_BLOCK = this.create("dusk_stone_block",
Block(
BlockBehaviour.Properties.of()
.mapColor(MapColor.WARPED_HYPHAE)
.strength(1.0F)
.sound(CobblemonSounds.EVOLUTION_STONE_BLOCK_SOUNDS)
.requiresCorrectToolForDrops()
.instrument(NoteBlockInstrument.BIT)
)
)
@JvmField
val BLACK_APRICORN = apricornBlock("black_apricorn", Apricorn.BLACK)
@JvmField
@@ -486,7 +661,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
BlockBehaviour.Properties.of()
.sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS)
.pushReaction(PushReaction.DESTROY)
.strength(0.4f)
.noOcclusion(), true
)
)
@@ -638,6 +812,19 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
)
)
@JvmField
val LECTERN = create(
"lectern",
LecternBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.WOOD)
.instrument(NoteBlockInstrument.BASS)
.sound(SoundType.WOOD)
.strength(2.5F)
.ignitedByLava()
)
)
@JvmField
val DISPLAY_CASE = create(
"display_case",
@@ -647,7 +834,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
.noOcclusion()
.pushReaction(PushReaction.BLOCK)
.mapColor(MapColor.STONE)
.strength(0.3f)
.strength(0.3F)
)
)
@@ -17,6 +17,7 @@ import net.minecraft.commands.Commands
object CobblemonCommands {
fun register(dispatcher: CommandDispatcher<CommandSourceStack>, registry: CommandBuildContext, selection: Commands.CommandSelection) {
SpawnPokemon.register(dispatcher)
SpawnNPCCommand.register(dispatcher)
GivePokemon.register(dispatcher)
TakePokemon.register(dispatcher)
ChangeScaleAndSize.register(dispatcher)
@@ -39,6 +40,7 @@ object CobblemonCommands {
PcCommand.register(dispatcher)
SpawnPokemonFromPool.register(dispatcher)
PokeboxCommand.register(dispatcher)
PokedexCommand.register(dispatcher)
TestStoreCommand.register(dispatcher)
QueryLearnsetCommand.register(dispatcher)
TestPcSlotCommand.register(dispatcher)
@@ -49,6 +51,9 @@ object CobblemonCommands {
BedrockParticleCommand.register(dispatcher)
OpenDialogueCommand.register(dispatcher)
NPCEditCommand.register(dispatcher)
AbandonMultiTeam.register(dispatcher)
FreezePokemonCommand.register(dispatcher)
ApplyPlayerTextureCommand.register(dispatcher)
// Possibly lock down registration if and only if under dev environment or running in an environment
// with a certain system environment variable set
@@ -97,6 +97,12 @@ interface CobblemonImplementation {
*/
fun registerBlockEntityTypes()
/**
* TODO
*
*/
fun registerVillagers()
/**
* TODO
*
@@ -19,6 +19,7 @@ import com.cobblemon.mod.common.api.text.gray
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.MintBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.client.pokedex.PokedexTypes
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.item.*
import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
@@ -152,6 +153,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val ANCIENT_ORIGIN_BALL = pokeBallItem(PokeBalls.ANCIENT_ORIGIN_BALL)
@JvmField
val POKEDEX_BLACK = create("pokedex_black", PokedexItem(PokedexTypes.BLACK))
@JvmField
val POKEDEX_BLUE = create("pokedex_blue", PokedexItem(PokedexTypes.BLUE))
@JvmField
val POKEDEX_GREEN = create("pokedex_green", PokedexItem(PokedexTypes.GREEN))
@JvmField
val POKEDEX_PINK = create("pokedex_pink", PokedexItem(PokedexTypes.PINK))
@JvmField
val POKEDEX_RED = create("pokedex_red", PokedexItem(PokedexTypes.RED))
@JvmField
val POKEDEX_WHITE = create("pokedex_white", PokedexItem(PokedexTypes.WHITE))
@JvmField
val POKEDEX_YELLOW = create("pokedex_yellow", PokedexItem(PokedexTypes.YELLOW))
@JvmField
val VIVICHOKE = compostableItem("vivichoke")
@@ -256,6 +272,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val PASTURE = blockItem("pasture", CobblemonBlocks.PASTURE)
@JvmField
val DISPLAY_CASE = blockItem("display_case", CobblemonBlocks.DISPLAY_CASE)
@JvmField
val LECTERN = blockItem("lectern", CobblemonBlocks.LECTERN)
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@@ -962,6 +980,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHISELED_POLISHED_TUMBLESTONE = blockItem("chiseled_polished_tumblestone", CobblemonBlocks.CHISELED_POLISHED_TUMBLESTONE)
@JvmField
val SMOOTH_TUMBLESTONE = blockItem("smooth_tumblestone", CobblemonBlocks.SMOOTH_TUMBLESTONE)
@JvmField
val SMOOTH_TUMBLESTONE_STAIRS = blockItem("smooth_tumblestone_stairs", CobblemonBlocks.SMOOTH_TUMBLESTONE_STAIRS)
@JvmField
val SMOOTH_TUMBLESTONE_SLAB = blockItem("smooth_tumblestone_slab", CobblemonBlocks.SMOOTH_TUMBLESTONE_SLAB)
@JvmField
val TUMBLESTONE_BRICKS = blockItem("tumblestone_bricks", CobblemonBlocks.TUMBLESTONE_BRICKS)
@JvmField
val TUMBLESTONE_BRICK_STAIRS = blockItem("tumblestone_brick_stairs", CobblemonBlocks.TUMBLESTONE_BRICK_STAIRS)
@@ -982,6 +1006,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHISELED_POLISHED_SKY_TUMBLESTONE = blockItem("chiseled_polished_sky_tumblestone", CobblemonBlocks.CHISELED_POLISHED_SKY_TUMBLESTONE)
@JvmField
val SMOOTH_SKY_TUMBLESTONE = blockItem("smooth_sky_tumblestone", CobblemonBlocks.SMOOTH_SKY_TUMBLESTONE)
@JvmField
val SMOOTH_SKY_TUMBLESTONE_STAIRS = blockItem("smooth_sky_tumblestone_stairs", CobblemonBlocks.SMOOTH_SKY_TUMBLESTONE_STAIRS)
@JvmField
val SMOOTH_SKY_TUMBLESTONE_SLAB = blockItem("smooth_sky_tumblestone_slab", CobblemonBlocks.SMOOTH_SKY_TUMBLESTONE_SLAB)
@JvmField
val SKY_TUMBLESTONE_BRICKS = blockItem("sky_tumblestone_bricks", CobblemonBlocks.SKY_TUMBLESTONE_BRICKS)
@JvmField
val SKY_TUMBLESTONE_BRICK_STAIRS = blockItem("sky_tumblestone_brick_stairs", CobblemonBlocks.SKY_TUMBLESTONE_BRICK_STAIRS)
@@ -1002,6 +1032,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHISELED_POLISHED_BLACK_TUMBLESTONE = blockItem("chiseled_polished_black_tumblestone", CobblemonBlocks.CHISELED_POLISHED_BLACK_TUMBLESTONE)
@JvmField
val SMOOTH_BLACK_TUMBLESTONE = blockItem("smooth_black_tumblestone", CobblemonBlocks.SMOOTH_BLACK_TUMBLESTONE)
@JvmField
val SMOOTH_BLACK_TUMBLESTONE_STAIRS = blockItem("smooth_black_tumblestone_stairs", CobblemonBlocks.SMOOTH_BLACK_TUMBLESTONE_STAIRS)
@JvmField
val SMOOTH_BLACK_TUMBLESTONE_SLAB = blockItem("smooth_black_tumblestone_slab", CobblemonBlocks.SMOOTH_BLACK_TUMBLESTONE_SLAB)
@JvmField
val BLACK_TUMBLESTONE_BRICKS = blockItem("black_tumblestone_bricks", CobblemonBlocks.BLACK_TUMBLESTONE_BRICKS)
@JvmField
val BLACK_TUMBLESTONE_BRICK_STAIRS = blockItem("black_tumblestone_brick_stairs", CobblemonBlocks.BLACK_TUMBLESTONE_BRICK_STAIRS)
@@ -1012,6 +1048,27 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHISELED_BLACK_TUMBLESTONE_BRICKS = blockItem("chiseled_black_tumblestone_bricks", CobblemonBlocks.CHISELED_BLACK_TUMBLESTONE_BRICKS)
@JvmField
val FIRE_STONE_BLOCK = blockItem("fire_stone_block", CobblemonBlocks.FIRE_STONE_BLOCK)
@JvmField
val WATER_STONE_BLOCK = blockItem("water_stone_block", CobblemonBlocks.WATER_STONE_BLOCK)
@JvmField
val THUNDER_STONE_BLOCK = blockItem("thunder_stone_block", CobblemonBlocks.THUNDER_STONE_BLOCK)
@JvmField
val LEAF_STONE_BLOCK = blockItem("leaf_stone_block", CobblemonBlocks.LEAF_STONE_BLOCK)
@JvmField
val ICE_STONE_BLOCK = blockItem("ice_stone_block", CobblemonBlocks.ICE_STONE_BLOCK)
@JvmField
val SUN_STONE_BLOCK = blockItem("sun_stone_block", CobblemonBlocks.SUN_STONE_BLOCK)
@JvmField
val MOON_STONE_BLOCK = blockItem("moon_stone_block", CobblemonBlocks.MOON_STONE_BLOCK)
@JvmField
val SHINY_STONE_BLOCK = blockItem("shiny_stone_block", CobblemonBlocks.SHINY_STONE_BLOCK)
@JvmField
val DAWN_STONE_BLOCK = blockItem("dawn_stone_block", CobblemonBlocks.DAWN_STONE_BLOCK)
@JvmField
val DUSK_STONE_BLOCK = blockItem("dusk_stone_block", CobblemonBlocks.DUSK_STONE_BLOCK)
@JvmField
val AUTOMATON_ARMOR_TRIM_SMITHING_TEMPLATE: SmithingTemplateItem = this.create(
"automaton_armor_trim_smithing_template",
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.dialogue.ActiveDialogue
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
@@ -20,6 +22,8 @@ object CobblemonMemories {
val BATTLING_POKEMON = register("battling_pokemon", ListCodec(UUIDUtil.CODEC, 0, 31))
val NPC_BATTLING = register("npc_battling", PrimitiveCodec.BOOL)
val DIALOGUES = register<List<ActiveDialogue>>("npc_dialogues")
val ACTIVE_ACTION_EFFECT = register<ActionEffectContext>("active_action_effect")
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
val memoryModule = MemoryModuleType(Optional.of(codec))
@@ -24,6 +24,7 @@ import com.cobblemon.mod.common.client.net.effect.RunPosableMoLangHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
import com.cobblemon.mod.common.client.net.gui.PokedexUIPacketHandler
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
import com.cobblemon.mod.common.client.net.npc.CloseNPCEditorHandler
import com.cobblemon.mod.common.client.net.npc.OpenNPCEditorHandler
@@ -31,6 +32,7 @@ import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
import com.cobblemon.mod.common.client.net.settings.ServerSettingsPacketHandler
import com.cobblemon.mod.common.client.net.sound.UnvalidatedPlaySoundS2CPacketHandler
@@ -85,22 +87,18 @@ import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.Rem
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnGenericBedrockPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnNPCPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
import com.cobblemon.mod.common.net.messages.client.starter.OpenStarterUIPacket
import com.cobblemon.mod.common.net.messages.client.starter.SetClientPlayerDataPacket
import com.cobblemon.mod.common.net.messages.client.SetClientPlayerDataPacket
import com.cobblemon.mod.common.net.messages.client.storage.RemoveClientPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.SwapClientPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.party.InitializePartyPacket
import com.cobblemon.mod.common.net.messages.client.storage.party.MoveClientPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyReferencePacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.OpenPCPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCBoxPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.*
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
@@ -110,13 +108,9 @@ import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotification
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.PokedexUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
import com.cobblemon.mod.common.net.messages.server.*
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
@@ -132,6 +126,7 @@ import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
import com.cobblemon.mod.common.net.messages.server.pasture.PasturePokemonPacket
import com.cobblemon.mod.common.net.messages.server.pasture.UnpastureAllPokemonPacket
import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPacket
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.StartScanningPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
@@ -151,8 +146,7 @@ import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptancePacket
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
import com.cobblemon.mod.common.net.serverhandling.*
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
@@ -191,6 +185,10 @@ import com.cobblemon.mod.common.net.serverhandling.trade.CancelTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHandler
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanningHandler
import com.cobblemon.mod.common.util.server
import net.minecraft.server.level.ServerPlayer
@@ -270,6 +268,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(SummaryUIPacket.ID, SummaryUIPacket::decode, SummaryUIPacketHandler))
list.add(PacketRegisterInfo(InteractPokemonUIPacket.ID, InteractPokemonUIPacket::decode, InteractPokemonUIPacketHandler))
list.add(PacketRegisterInfo(PlayerInteractOptionsPacket.ID, PlayerInteractOptionsPacket::decode, PlayerInteractOptionsHandler))
list.add(PacketRegisterInfo(PokedexUIPacket.ID, PokedexUIPacket::decode, PokedexUIPacketHandler))
// Starter packets
list.add(PacketRegisterInfo(OpenStarterUIPacket.ID, OpenStarterUIPacket::decode, StarterUIPacketHandler))
@@ -284,6 +283,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(BattleHealthChangePacket.ID, BattleHealthChangePacket::decode, BattleHealthChangeHandler))
list.add(PacketRegisterInfo(BattleSetTeamPokemonPacket.ID, BattleSetTeamPokemonPacket::decode, BattleSetTeamPokemonHandler))
list.add(PacketRegisterInfo(BattleSwitchPokemonPacket.ID, BattleSwitchPokemonPacket::decode, BattleSwitchPokemonHandler))
list.add(PacketRegisterInfo(BattleSwapPokemonPacket.ID, BattleSwapPokemonPacket::decode, BattleSwapPokemonHandler))
list.add(PacketRegisterInfo(BattleMessagePacket.ID, BattleMessagePacket::decode, BattleMessageHandler))
list.add(PacketRegisterInfo(BattleCaptureStartPacket.ID, BattleCaptureStartPacket::decode, BattleCaptureStartHandler))
list.add(PacketRegisterInfo(BattleCaptureEndPacket.ID, BattleCaptureEndPacket::decode, BattleCaptureEndHandler))
@@ -298,6 +298,12 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(BattleReplacePokemonPacket.ID, BattleReplacePokemonPacket::decode, BattleReplacePokemonHandler))
list.add(PacketRegisterInfo(BattleTransformPokemonPacket.ID, BattleTransformPokemonPacket::decode, BattleTransformPokemonHandler))
// MultiBattleTeam Packets
list.add(PacketRegisterInfo(TeamRequestNotificationPacket.ID, TeamRequestNotificationPacket::decode, TeamRequestNotificationHandler))
list.add(PacketRegisterInfo(TeamRequestExpiredPacket.ID, TeamRequestExpiredPacket::decode, TeamRequestExpiredHandler))
list.add(PacketRegisterInfo(TeamMemberRemoveNotificationPacket.ID, TeamMemberRemoveNotificationPacket::decode, TeamMemberRemoveNotificationHandler))
list.add(PacketRegisterInfo(TeamJoinNotificationPacket.ID, TeamJoinNotificationPacket::decode, TeamJoinNotificationHandler))
// Settings packets
list.add(PacketRegisterInfo(ServerSettingsPacket.ID, ServerSettingsPacket::decode, ServerSettingsPacketHandler))
@@ -316,6 +322,8 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(NPCRegistrySyncPacket.ID, NPCRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(PokeRodRegistrySyncPacket.ID, PokeRodRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(ScriptRegistrySyncPacket.ID, ScriptRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(PokedexDexSyncPacket.ID, PokedexDexSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(DexEntrySyncPacket.ID, DexEntrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(FishingBaitRegistrySyncPacket.ID, FishingBaitRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
// Effects
@@ -327,8 +335,9 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(UnvalidatedPlaySoundS2CPacket.ID, UnvalidatedPlaySoundS2CPacket::decode, UnvalidatedPlaySoundS2CPacketHandler))
list.add(PacketRegisterInfo(SpawnPokemonPacket.ID, SpawnPokemonPacket::decode, SpawnExtraDataEntityHandler()))
list.add(PacketRegisterInfo(SpawnPokeballPacket.ID, SpawnPokeballPacket::decode, SpawnExtraDataEntityHandler()))
list.add(PacketRegisterInfo(ToastPacket.ID, ToastPacket::decode, ToastPacketHandler))
list.add(PacketRegisterInfo(SpawnGenericBedrockPacket.ID, SpawnGenericBedrockPacket::decode, SpawnExtraDataEntityHandler()))
list.add(PacketRegisterInfo(SpawnNPCPacket.ID, SpawnNPCPacket::decode, SpawnExtraDataEntityHandler()))
list.add(PacketRegisterInfo(ToastPacket.ID, ToastPacket::decode, ToastPacketHandler))
// Trade packets
list.add(PacketRegisterInfo(TradeAcceptanceChangedPacket.ID, TradeAcceptanceChangedPacket::decode, TradeAcceptanceChangedHandler))
@@ -365,6 +374,8 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(CloseNPCEditorPacket.ID, CloseNPCEditorPacket::decode, CloseNPCEditorHandler))
list.add(PacketRegisterInfo(OpenNPCEditorPacket.ID, OpenNPCEditorPacket::decode, OpenNPCEditorHandler))
//Pokedex scanning
list.add(PacketRegisterInfo(ServerConfirmedRegisterPacket.ID, ServerConfirmedRegisterPacket::decode, ServerConfirmedRegisterHandler))
return list
}
@@ -385,6 +396,10 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(RequestMoveSwapPacket.ID, RequestMoveSwapPacket::decode, RequestMoveSwapHandler))
list.add(PacketRegisterInfo(BenchMovePacket.ID, BenchMovePacket::decode, BenchMoveHandler))
list.add(PacketRegisterInfo(BattleChallengePacket.ID, BattleChallengePacket::decode, ChallengeHandler))
list.add(PacketRegisterInfo(BattleChallengeResponsePacket.ID, BattleChallengeResponsePacket::decode, ChallengeResponseHandler))
list.add(PacketRegisterInfo(BattleTeamRequestPacket.ID, BattleTeamRequestPacket::decode, TeamRequestHandler))
list.add(PacketRegisterInfo(BattleTeamResponsePacket.ID, BattleTeamResponsePacket::decode, TeamRequestResponseHandler))
list.add(PacketRegisterInfo(BattleTeamLeavePacket.ID, BattleTeamLeavePacket::decode, TeamLeaveHandler))
list.add(PacketRegisterInfo(MovePCPokemonToPartyPacket.ID, MovePCPokemonToPartyPacket::decode, MovePCPokemonToPartyHandler))
list.add(PacketRegisterInfo(MovePartyPokemonToPCPacket.ID, MovePartyPokemonToPCPacket::decode, MovePartyPokemonToPCHandler))
@@ -416,6 +431,10 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(OfferTradePacket.ID, OfferTradePacket::decode, OfferTradeHandler))
list.add(PacketRegisterInfo(UpdateTradeOfferPacket.ID, UpdateTradeOfferPacket::decode, UpdateTradeOfferHandler))
// Pokedex scanning
list.add(PacketRegisterInfo(StartScanningPacket.ID, StartScanningPacket::decode, StartScanningHandler))
list.add(PacketRegisterInfo(FinishScanningPacket.ID, FinishScanningPacket::decode, FinishScanningHandler))
// Pasture
list.add(PacketRegisterInfo(PasturePokemonPacket.ID, PasturePokemonPacket::decode, PasturePokemonHandler))
list.add(PacketRegisterInfo(UnpasturePokemonPacket.ID, UnpasturePokemonPacket::decode, UnpasturePokemonHandler))
@@ -39,6 +39,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val PC_CLICK = this.create("pc.click")
@JvmField
val VILLAGER_WORK_NURSE = this.create("entity.villager.work_nurse")
@JvmField
val HEALING_MACHINE_ACTIVE = this.create("healing_machine.active")
@@ -51,24 +53,51 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val POKE_BALL_OPEN = this.create("poke_ball.open")
@JvmField
val POKE_BALL_SHINY_OPEN = this.create("poke_ball.shiny_open")
@JvmField
val POKE_BALL_HIT = this.create("poke_ball.hit")
@JvmField
val POKE_BALL_SEND_OUT = this.create("poke_ball.send_out")
@JvmField
val POKE_BALL_SHINY_SEND_OUT = this.create("poke_ball.shiny_send_out")
@JvmField
val POKE_BALL_RECALL = this.create("poke_ball.recall")
@JvmField
val POKE_BALL_THROW = this.create("poke_ball.throw")
@JvmField
val POKE_BALL_TRAIL = this.create("poke_ball.trail")
@JvmField
val POKEDEX_OPEN = this.create("item.pokedex.open")
@JvmField
val POKEDEX_CLOSE = this.create("item.pokedex.close")
@JvmField
val POKEDEX_CLICK = this.create("item.pokedex.click")
@JvmField
val POKEDEX_CLICK_SHORT = this.create("item.pokedex.click_short")
@JvmField
val POKEDEX_SCAN_OPEN = this.create("item.pokedex.scan_open")
@JvmField
val POKEDEX_SCAN_CLOSE = this.create("item.pokedex.scan_close")
@JvmField
val POKEDEX_SCAN_LOOP = this.create("item.pokedex.scan_loop")
@JvmField
val POKEDEX_SCAN_DETAIL = this.create("item.pokedex.scan_detail")
@JvmField
val POKEDEX_SCAN_REGISTER_POKEMON = this.create("item.pokedex.scan_register_pokemon")
@JvmField
val POKEDEX_SCAN_REGISTER_ASPECT = this.create("item.pokedex.scan_register_aspect")
@JvmField
val POKEDEX_SCAN_ZOOM_INCREMENT = this.create("item.pokedex.scan_zoom_increment")
@JvmField
val ITEM_USE = this.create("item.use")
@JvmField
val CAN_EVOLVE = this.create("pokemon.can_evolve")
val EVOLUTION_NOTIFICATION = this.create("evolution.notification")
@JvmField
val EVOLVING = this.create("pokemon.evolving")
val EVOLUTION_UI = this.create("evolution.ui")
@JvmField
val EVOLVE = this.create("evolution.evolve")
val EVOLUTION = this.create("evolution.full")
@JvmField
val PVN_BATTLE = this.create("battle.pvn.default")
@@ -161,6 +190,15 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val TUMBLESTONE_STEP = this.create("tumblestone.step")
@JvmField
val EVOLUTION_STONE_BLOCK_BREAK = this.create("evolution_stone_block.break")
@JvmField
val EVOLUTION_STONE_BLOCK_HIT = this.create("evolution_stone_block.hit")
@JvmField
val EVOLUTION_STONE_BLOCK_PLACE = this.create("evolution_stone_block.place")
@JvmField
val EVOLUTION_STONE_BLOCK_STEP = this.create("evolution_stone_block.step")
@JvmField
val GIMMIGHOUL_GIVE_ITEM_SMALL = this.create("gimmighoul.give_item_small")
@JvmField
@@ -210,7 +248,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
val GILDED_CHEST_PLACE = this.create("gilded_chest.place")
@JvmField
val RELIC_COIN_SACK_SOUNDS = SoundType(1f, 1f,
val RELIC_COIN_SACK_SOUNDS = SoundType(1f, 1.1f,
RELIC_COIN_SACK_BREAK,
RELIC_COIN_SACK_STEP,
RELIC_COIN_SACK_PLACE,
@@ -218,7 +256,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
RELIC_COIN_SACK_STEP
)
@JvmField
val RELIC_COIN_POUCH_SOUNDS = SoundType(1f, 1f,
val RELIC_COIN_POUCH_SOUNDS = SoundType(1f, 1.1f,
RELIC_COIN_POUCH_BREAK,
RELIC_COIN_SACK_STEP,
RELIC_COIN_POUCH_PLACE,
@@ -264,7 +302,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
val IMPACT_WATER = this.create("impact.water")
@JvmField
val TUMBLESTONE_SOUNDS = SoundType(1f, 1f,
val TUMBLESTONE_SOUNDS = SoundType(1f, 1.1f,
TUMBLESTONE_BREAK,
TUMBLESTONE_STEP,
TUMBLESTONE_PLACE,
@@ -273,16 +311,25 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val TUMBLESTONE_BLOCK_SOUNDS = SoundType(1f, 1f,
val TUMBLESTONE_BLOCK_SOUNDS = SoundType(1f, 1.1f,
TUMBLESTONE_BLOCK_BREAK,
TUMBLESTONE_STEP,
TUMBLESTONE_PLACE,
TUMBLESTONE_HIT,
TUMBLESTONE_STEP
)
@JvmField
val EVOLUTION_STONE_BLOCK_SOUNDS = SoundType(1f, 1.1f,
EVOLUTION_STONE_BLOCK_BREAK,
EVOLUTION_STONE_BLOCK_STEP,
EVOLUTION_STONE_BLOCK_PLACE,
EVOLUTION_STONE_BLOCK_HIT,
EVOLUTION_STONE_BLOCK_STEP
)
@JvmField
val BERRY_BUSH_SOUNDS = SoundType(1f, 1f,
val BERRY_BUSH_SOUNDS = SoundType(0.8f, 1.1f,
BERRY_BUSH_BREAK,
SoundEvents.GRASS_STEP,
BERRY_BUSH_PLACE,
@@ -291,25 +338,25 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val BIG_ROOT_SOUNDS = SoundType(1f, 1f,
val BIG_ROOT_SOUNDS = SoundType(0.8f, 1.1f,
BIG_ROOT_BREAK,
SoundEvents.ROOTS_STEP,
SoundEvents.ROOTS_PLACE,
SoundEvents.ROOTS_HIT,
SoundEvents.ROOTS_FALL
)
@JvmField
val ENERGY_ROOT_SOUNDS = SoundType(1f, 1f,
SoundEvents.ROOTS_BREAK,
SoundEvents.ROOTS_STEP,
ENERGY_ROOT_PLACE,
SoundEvents.ROOTS_HIT,
SoundEvents.ROOTS_FALL
)
@JvmField
val MEDICINAL_LEEK_SOUNDS = SoundType(1f, 1f,
val ENERGY_ROOT_SOUNDS = SoundType(0.8f, 1.1f,
BIG_ROOT_BREAK,
SoundEvents.ROOTS_STEP,
ENERGY_ROOT_PLACE,
SoundEvents.ROOTS_HIT,
SoundEvents.ROOTS_FALL
)
@JvmField
val MEDICINAL_LEEK_SOUNDS = SoundType(1f, 1.1f,
MEDICINAL_LEEK_BREAK,
SoundEvents.GRASS_STEP,
MEDICINAL_LEEK_PLACE,
@@ -318,7 +365,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val VIVICHOKE_SOUNDS = SoundType(1f, 1f,
val VIVICHOKE_SOUNDS = SoundType(0.6f, 1.1f,
VIVICHOKE_BREAK,
SoundEvents.GRASS_STEP,
VIVICHOKE_PLACE,
@@ -327,7 +374,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val MINT_SOUNDS = SoundType(1f, 1f,
val MINT_SOUNDS = SoundType(0.6f, 1.1f,
MINT_BREAK,
SoundEvents.GRASS_STEP,
MINT_PLACE,
@@ -336,7 +383,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val REVIVAL_HERB_SOUNDS = SoundType(1f, 1f,
val REVIVAL_HERB_SOUNDS = SoundType(0.6f, 1.1f,
REVIVAL_HERB_BREAK,
SoundEvents.GRASS_STEP,
REVIVAL_HERB_PLACE,
@@ -345,7 +392,7 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
)
@JvmField
val GILDED_CHEST_SOUNDS = SoundType(1f, 1f,
val GILDED_CHEST_SOUNDS = SoundType(1f, 1.1f,
GILDED_CHEST_BREAK,
GILDED_CHEST_STEP,
GILDED_CHEST_PLACE,
@@ -9,9 +9,16 @@
package com.cobblemon.mod.common
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.npc.VillagerData
import net.minecraft.world.entity.npc.VillagerProfession
import net.minecraft.world.entity.npc.VillagerTrades
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.trading.ItemCost
import net.minecraft.world.item.trading.MerchantOffer
import java.util.Optional
/**
* A generator for various trade offers in the mod.
@@ -32,8 +39,41 @@ object CobblemonTradeOffers {
* @return The resulting list.
*/
fun tradeOffersFor(profession: VillagerProfession): List<VillagerTradeOffer> = when (profession) {
VillagerProfession.FARMER -> listOf(
VillagerTradeOffer(VillagerProfession.FARMER, 3, listOf(VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6)))
CobblemonVillagerProfessions.NURSE -> listOf(
// requiredLevel = the level of the villager for the trade to appear for
// Novice = 1, Apprentice = 2, Journeyman = 3, Expert = 4, Master = 5
VillagerTradeOffer(CobblemonVillagerProfessions.NURSE, 1, listOf(
// i = emeraldCost, j = numberOfItems, k = maxUses, l = villagerXp, f = priceMultiplier
VillagerTrades.ItemsForEmeralds(CobblemonItems.ORAN_BERRY, 4, 1, 16, 1),
VillagerTrades.ItemsForEmeralds(CobblemonItems.PERSIM_BERRY, 4, 1, 16, 1),
VillagerTrades.ItemsForEmeralds(CobblemonItems.ENERGY_ROOT, 4, 1, 12, 1),
TradeOffer(ItemCost(CobblemonItems.MEDICINAL_LEEK, 24), ItemStack(Items.EMERALD, 1), 12, 2)
)),
VillagerTradeOffer(CobblemonVillagerProfessions.NURSE, 2, listOf(
TradeOffer(ItemCost(Items.EMERALD, 8), ItemStack(CobblemonItems.MEDICINAL_BREW), 8, 5, Optional.of<ItemCost>(ItemCost(Items.GLASS_BOTTLE))),
VillagerTrades.ItemsForEmeralds(CobblemonItems.BLUE_MINT_LEAF, 2, 1, 8, 5),
VillagerTrades.ItemsForEmeralds(CobblemonItems.CYAN_MINT_LEAF, 2, 1, 8, 5),
VillagerTrades.ItemsForEmeralds(CobblemonItems.GREEN_MINT_LEAF, 2, 1, 8, 5),
VillagerTrades.ItemsForEmeralds(CobblemonItems.PINK_MINT_LEAF, 2, 1, 8, 5),
VillagerTrades.ItemsForEmeralds(CobblemonItems.RED_MINT_LEAF, 2, 1, 8, 5),
VillagerTrades.ItemsForEmeralds(CobblemonItems.WHITE_MINT_LEAF, 2, 1, 8, 5)
)),
VillagerTradeOffer(CobblemonVillagerProfessions.NURSE, 3, listOf(
TradeOffer(ItemCost(CobblemonItems.MULCH_BASE, 4), ItemStack(Items.EMERALD, 2), 16, 20),
VillagerTrades.ItemsForEmeralds(Items.GLASS_BOTTLE, 1, 1, 16, 10)
)),
VillagerTradeOffer(CobblemonVillagerProfessions.NURSE, 4, listOf(
VillagerTrades.ItemsForEmeralds(CobblemonItems.REVIVAL_HERB, 8, 1, 16, 15),
VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 4, 15)
)),
VillagerTradeOffer(CobblemonVillagerProfessions.NURSE, 5, listOf(
TradeOffer(ItemCost(Items.EMERALD, 10), ItemStack(CobblemonItems.ANTIDOTE, 1), 12, 30, Optional.of<ItemCost>(ItemCost(Items.GLASS_BOTTLE))),
TradeOffer(ItemCost(Items.EMERALD, 10), ItemStack(CobblemonItems.AWAKENING, 1), 12, 30, Optional.of<ItemCost>(ItemCost(Items.GLASS_BOTTLE))),
TradeOffer(ItemCost(Items.EMERALD, 10), ItemStack(CobblemonItems.BURN_HEAL, 1), 12, 30, Optional.of<ItemCost>(ItemCost(Items.GLASS_BOTTLE))),
TradeOffer(ItemCost(Items.EMERALD, 10), ItemStack(CobblemonItems.ICE_HEAL, 1), 12, 30, Optional.of<ItemCost>(ItemCost(Items.GLASS_BOTTLE))),
TradeOffer(ItemCost(Items.EMERALD, 10), ItemStack(CobblemonItems.PARALYZE_HEAL, 1), 12, 30, Optional.of<ItemCost>(ItemCost(Items.GLASS_BOTTLE))),
TradeOffer(ItemCost(Items.EMERALD, 22), ItemStack(CobblemonItems.VIVICHOKE_DIP, 1), 4, 30, Optional.of<ItemCost>(ItemCost(Items.BOWL)))
))
)
VillagerProfession.FISHERMAN -> listOf(
VillagerTradeOffer(VillagerProfession.FISHERMAN, 5, listOf(
@@ -53,7 +93,7 @@ object CobblemonTradeOffers {
)
/**
* Represents a trade offer that can be attached to a villager or a wandering trader.
* Represents trade offers that can be attached to a villager or a wandering trader.
*/
interface TradeOfferHolder {
/**
@@ -63,7 +103,7 @@ object CobblemonTradeOffers {
}
/**
* Represents a trade offer from a villager.
* Represents trade offers from a villager.
*
* @property profession The target profession for this trade.
* @property requiredLevel The level required must be a possible level.
@@ -75,7 +115,7 @@ object CobblemonTradeOffers {
val profession: VillagerProfession,
val requiredLevel: Int,
override val tradeOffers: List<VillagerTrades.ItemListing>
) : TradeOfferHolder {
): TradeOfferHolder {
init {
if (this.requiredLevel < VillagerData.MIN_VILLAGER_LEVEL || this.requiredLevel > VillagerData.MAX_VILLAGER_LEVEL) {
@@ -86,7 +126,7 @@ object CobblemonTradeOffers {
}
/**
* Represents a trade offer from a wandering trader.
* Represents trade offers from a wandering trader.
*
* @property isRareTrade If this is rare or common trade.
* @property tradeOffers The list of the possible [TradeOffers.Factory].
@@ -94,6 +134,26 @@ object CobblemonTradeOffers {
data class WandererTradeOffer(
val isRareTrade: Boolean,
override val tradeOffers: List<VillagerTrades.ItemListing>
) : TradeOfferHolder
): TradeOfferHolder
/**
* Represents a trade offer from a villager.
*
* @property offeredItem The item cost offered to the villager.
* @property receivedItem The item received from the villager.
* @property maxUses How many times the trade can be used before the villager resupplies.
* @property villagerXp The experience the villager gains from the trade.
* @property optionalOfferedItem The optional, secondary item cost offered to the villager.
* @property priceMultiplier The amount multiplier of how much the item cost can rise and fall by depending on discounts and penalties
*/
class TradeOffer(
private val offeredItem: ItemCost,
private val receivedItem: ItemStack,
private val maxUses: Int,
private val villagerXp: Int = 1,
private val optionalOfferedItem: Optional<ItemCost> = Optional.empty(),
private val priceMultiplier: Float = 0.05F
): VillagerTrades.ItemListing {
override fun getOffer(entity: Entity?, randomSource: RandomSource?): MerchantOffer = MerchantOffer(offeredItem, optionalOfferedItem, receivedItem, maxUses, villagerXp, priceMultiplier)
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.common.collect.ImmutableSet
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.entity.ai.village.poi.PoiType
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState
object CobblemonVillagerPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Registry<PoiType>>, PoiType>() {
override val registry: Registry<PoiType> = BuiltInRegistries.POINT_OF_INTEREST_TYPE
override val resourceKey: ResourceKey<Registry<PoiType>> = Registries.POINT_OF_INTEREST_TYPE
@JvmField
val NURSE_KEY: ResourceKey<PoiType> = createKey("nurse")
@JvmField
val NURSE = create(NURSE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.HEALING_MACHINE), 1, 1))
private fun createKey(string: String): ResourceKey<PoiType> = ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string))
private fun getBlockStates(block: Block): Set<BlockState> = ImmutableSet.copyOf(block.stateDefinition.possibleStates)
}
@@ -0,0 +1,47 @@
/*
* 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.platform.PlatformRegistry
import com.google.common.collect.ImmutableSet
import net.minecraft.core.Holder
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.sounds.SoundEvent
import net.minecraft.world.entity.ai.village.poi.PoiType
import net.minecraft.world.entity.npc.VillagerProfession
object CobblemonVillagerProfessions: PlatformRegistry<Registry<VillagerProfession>, ResourceKey<Registry<VillagerProfession>>, VillagerProfession>() {
override val registry: Registry<VillagerProfession> = BuiltInRegistries.VILLAGER_PROFESSION
override val resourceKey: ResourceKey<Registry<VillagerProfession>> = Registries.VILLAGER_PROFESSION
@JvmField
val NURSE = profession(CobblemonVillagerPoiTypes.NURSE_KEY, CobblemonSounds.VILLAGER_WORK_NURSE)
/**
* Register a villager profession texture override for Cobblemon villagers of the given [VillagerProfession] for specified names.
*
* @param profession The Cobblemon [VillagerProfession] being overridden.
* @return The profession override texture file name and a list of names that will trigger the override, as a pair.
*/
fun getNameTagOverride(profession: VillagerProfession?): Pair<String, Array<String>>? = when (profession) {
NURSE -> Pair("nurse_joy", arrayOf("ジョーイ", "간호순", "祖兒", "喬伊", "乔伊", "האחות ג'וי", "الممرضة جوي", "Joy", "Joelle", "Joëlle", "Джой", "จอย"))
else -> null
}
private fun profession(resourceKey: ResourceKey<PoiType>, soundEvent: SoundEvent?): VillagerProfession =
create(resourceKey.location().path, VillagerProfession(
resourceKey.location().toString(),
{ holder: Holder<PoiType> -> holder.`is`(resourceKey) },
{ holder: Holder<PoiType> -> holder.`is`(resourceKey) },
ImmutableSet.of(), ImmutableSet.of(), soundEvent
))
}
@@ -59,7 +59,7 @@ class AspectCriterion(
// pokemon = json.get("pokemon").asString.asIdentifierDefaultingNamespace()
// }
//
// override fun matches(player: ServerPlayerEntity, context: MutableMap<Identifier, MutableSet<String>>): Boolean {
// override fun matches(player: ServerPlayer, context: MutableMap<Identifier, MutableSet<String>>): Boolean {
// val caughtAspects = context.getOrDefault(pokemon, mutableSetOf())
// return this.aspects.all { it in caughtAspects }
// }
@@ -34,8 +34,7 @@ class BattleCountableCriterion(
override fun matches(player: ServerPlayer, context: BattleCountableContext): Boolean {
var typeCheck = false
val advancementData = Cobblemon.playerData.get(player).advancementData
val advancementData = Cobblemon.playerDataManager.getGenericData(player).advancementData
if (battleTypes.isEmpty() || battleTypes.contains("any")) {
typeCheck = true
}
@@ -87,7 +86,7 @@ class BattleCountableCriterion(
// json.add("battle_types", battleTypes.toJsonArray())
// }
//
// override fun matches(player: ServerPlayerEntity, context: BattleCountableContext): Boolean {
// override fun matches(player: ServerPlayer, context: BattleCountableContext): Boolean {
// var typeCheck = false
// val advancementData = Cobblemon.playerData.get(player).advancementData
// if (battleTypes.isEmpty() || battleTypes.contains("any")) {
@@ -54,7 +54,7 @@ class CaughtPokemonCriterion(
// type = json.get("type")?.asString ?: "any"
// }
//
// override fun matches(player: ServerPlayerEntity, context: CountablePokemonTypeContext): Boolean {
// override fun matches(player: ServerPlayer, context: CountablePokemonTypeContext): Boolean {
// return super.matches(player, context) && (context.type == type || type == "any")
// }
//}
@@ -50,7 +50,7 @@ open class CountableCriterion<T : CountableContext>(
// json.addProperty("count", count)
// }
//
// override fun matches(player: ServerPlayerEntity, context: T) = context.times >= count
// override fun matches(player: ServerPlayer, context: T) = context.times >= count
//}
//
///**
@@ -64,7 +64,7 @@ open class CountableCriterion<T : CountableContext>(
// * @since November 4th, 2022
// */
//class SimpleCountableCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountableContext>(id, predicate)
//fun SimpleCriterionTrigger<CountableContext, SimpleCountableCriterionCondition>.trigger(player: ServerPlayerEntity, times: Int) = trigger(player, CountableContext(times))
//fun SimpleCriterionTrigger<CountableContext, SimpleCountableCriterionCondition>.trigger(player: ServerPlayer, times: Int) = trigger(player, CountableContext(times))
//
///**
// * Some type of context that has a count associated with it, representing how many times the trigger has occurred.
@@ -55,7 +55,7 @@ class EvolvePokemonCriterion(
// evolution = json.get("evolution")?.asString ?: "any"
// }
//
// override fun matches(player: ServerPlayerEntity, context: EvolvePokemonContext): Boolean {
// override fun matches(player: ServerPlayer, context: EvolvePokemonContext): Boolean {
// return context.times >= count && (context.species == species.asIdentifierDefaultingNamespace() || species == "any") &&
// (context.evolution == evolution.asIdentifierDefaultingNamespace() || evolution == "any")
// }
@@ -57,7 +57,7 @@ class LevelUpCriterion(
evolved = json.get("has_evolved")?.asBoolean ?: true
}
override fun matches(player: ServerPlayerEntity, context: LevelUpContext): Boolean {
override fun matches(player: ServerPlayer, context: LevelUpContext): Boolean {
val preEvo = context.pokemon.preEvolution == null
val hasEvolution = !context.pokemon.evolutions.none()
var evolutionCheck = true
@@ -79,7 +79,7 @@ class PartyCheckCriterion(
}
}
override fun matches(player: ServerPlayerEntity, context: PartyCheckContext): Boolean {
override fun matches(player: ServerPlayer, context: PartyCheckContext): Boolean {
val playerParty = player.party()
val matches = mutableListOf<Identifier>()
party.forEach {
@@ -57,7 +57,7 @@ class PlantTumblestoneCriterion(
// * @param context The context of the criterion
// * @return True if the tumblestone block can grow at the given position, false otherwise
// */
// override fun matches(player: ServerPlayerEntity, context: PlantTumblestoneContext): Boolean {
// override fun matches(player: ServerPlayer, context: PlantTumblestoneContext): Boolean {
// return context.tumbleStoneBlock.canGrow(context.pos, player.level())
// }
//}
@@ -21,20 +21,18 @@ class PokemonInteractContext(val type: ResourceLocation, val item: ResourceLocat
class PokemonInteractCriterion(
playerCtx: Optional<ContextAwarePredicate>,
val type: Optional<String>,
val item: Optional<String>
val type: String,
val item: String
): SimpleCriterionCondition<PokemonInteractContext>(playerCtx) {
companion object {
val CODEC: Codec<PokemonInteractCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(PokemonInteractCriterion::playerCtx),
Codec.STRING.optionalFieldOf("type").forGetter(PokemonInteractCriterion::type),
Codec.STRING.optionalFieldOf("item").forGetter(PokemonInteractCriterion::item)
Codec.STRING.optionalFieldOf("type", "any").forGetter(PokemonInteractCriterion::type),
Codec.STRING.optionalFieldOf("item", "any").forGetter(PokemonInteractCriterion::item)
).apply(it, ::PokemonInteractCriterion) }
}
override fun matches(player: ServerPlayer, context: PokemonInteractContext): Boolean {
val otherType = this.type.orElse("any")
val otherItem = this.item.orElse("any")
return (context.type == otherType.asIdentifierDefaultingNamespace() || otherType == "any") && (context.type == otherItem.asIdentifierDefaultingNamespace() || otherItem == "any")
return (context.type == this.type.asIdentifierDefaultingNamespace() || this.type == "any") && (context.item == this.item.asIdentifierDefaultingNamespace() || this.item == "any")
}
}
@@ -80,7 +80,7 @@ class TradePokemonCriterion(
receivedHeldItem = json.get("received_held_item")?.asString ?: "minecraft:air"
}
override fun matches(player: ServerPlayerEntity, context: TradePokemonContext): Boolean {
override fun matches(player: ServerPlayer, context: TradePokemonContext): Boolean {
val heldItem1 = context.traded.heldItem().item.registryEntry.ResourceKey().value
val heldItem2 = context.received.heldItem().item.registryEntry.ResourceKey().value
return (context.traded.species.resourceIdentifier == traded.asIdentifierDefaultingNamespace() || traded == "any") &&
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.battles.model
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.CobblemonNetwork
@@ -21,6 +22,7 @@ import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
import com.cobblemon.mod.common.api.battles.model.actor.FleeableBattleActor
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
@@ -40,20 +42,27 @@ import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
import com.cobblemon.mod.common.battles.interpreter.ContextManager
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.battles.runner.ShowdownService
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.requirements.DefeatRequirement
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.getPlayer
import net.minecraft.network.chat.Component
import com.cobblemon.mod.common.util.giveOrDropItemStack
import com.cobblemon.mod.common.util.itemRegistry
import net.minecraft.resources.ResourceLocation
import java.io.File
import java.util.UUID
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentLinkedDeque
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.item.ItemStack
/**
* Individual battle instance
@@ -84,6 +93,7 @@ open class PokemonBattle(
.filterIsInstance<LastBattleCriticalHitsEvolutionProgress>()
.forEach { it.reset() }
}
actor.setupStruct()
}
}
@@ -109,7 +119,7 @@ open class PokemonBattle(
var ended = false
// TEMP battle showcase stuff
var announcingRules = false
var turn: Int = 1
var turn: Int = 0
private set
private var ticks: Int = 0
@@ -175,6 +185,11 @@ open class PokemonBattle(
*/
fun getActor(player: ServerPlayer) = actors.firstOrNull { it.isForPlayer(player) }
/**
* Gets the first battle actor whom the given NPC controls, or null if there is no such actor.
*/
fun getActor(npc: NPCEntity) = actors.firstOrNull { it is NPCBattleActor && it.npc == npc }
/**
* Gets a [BattleActor] and an [ActiveBattlePokemon] from a pnx key, e.g. p2a
*
@@ -214,11 +229,12 @@ open class PokemonBattle(
fun turn(newTurnNumber: Int) {
actors.forEach { it.turn() }
// TODO: If a pokemon switches in the same turn another pokemon is KO'd it will not receive exp for the KO
for (side in sides) {
val opposite = side.getOppositeSide()
side.activePokemon.forEach {
val battlePokemon = it.battlePokemon ?: return@forEach
battlePokemon.facedOpponents.addAll(opposite.activePokemon.mapNotNull { it.battlePokemon })
side.activePokemon.filter { it.isAlive() }.forEach { activePokemon ->
val battlePokemon = activePokemon.battlePokemon ?: return@forEach
battlePokemon.facedOpponents.addAll(opposite.activePokemon.filter { opposingActivePokemon -> opposingActivePokemon.isAlive() }.mapNotNull { it.battlePokemon })
}
}
this.turn = newTurnNumber
@@ -261,6 +277,13 @@ open class PokemonBattle(
}
}
}
if(actor.itemsUsed.isNotEmpty() && actor.getPlayerUUIDs().count() > 0) {
val player = actor.getPlayerUUIDs().first().getPlayer()
player?.level()?.itemRegistry.let { registry ->
actor.itemsUsed.mapNotNull { registry?.get(ResourceLocation.tryBySeparator(it.itemName.substringAfter('.'), '.')) }
.forEach { player?.giveOrDropItemStack(ItemStack(it))}
}
}
}
// Heal Mon if wild
actors.filter { it.type == ActorType.WILD }
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.battles.model.actor
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.battles.ActiveBattlePokemon
@@ -17,6 +19,7 @@ import com.cobblemon.mod.common.battles.ShowdownActionResponse
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.exception.IllegalActionChoiceException
import com.cobblemon.mod.common.item.battle.BagItem
import com.cobblemon.mod.common.net.messages.client.battle.BattleApplyPassResponsePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
@@ -33,6 +36,8 @@ abstract class BattleActor(
pokemonList.forEach { it.actor = this }
}
val struct = QueryStruct(hashMapOf())
lateinit var showdownId: String
lateinit var battle: PokemonBattle
@@ -44,6 +49,7 @@ abstract class BattleActor(
val expectingPassActions = mutableListOf<ShowdownActionResponse>()
var mustChoose = false
var itemsUsed = mutableListOf<BagItem>()
/** For when battles start, it's the number of Pokémon that are still in the process of being sent out (animation wise) */
var stillSendingOutCount = 0
@@ -65,11 +71,14 @@ abstract class BattleActor(
open fun isForPlayer(serverPlayerEntity: ServerPlayer) = serverPlayerEntity.uuid in getPlayerUUIDs()
open fun isForPokemon(pokemonEntity: PokemonEntity) = activePokemon.any { it.battlePokemon?.effectedPokemon?.entity == pokemonEntity }
fun turn() {
fun turn() {
val request = request ?: return
responses.clear()
mustChoose = true
sendUpdate(BattleMakeChoicePacket())
if(activePokemon.any { it.isAlive() }) {
mustChoose = true
sendUpdate(BattleMakeChoicePacket())
}
val requestActive = request.active
if (requestActive == null || requestActive.isEmpty() || request.wait) {
@@ -129,6 +138,10 @@ abstract class BattleActor(
battle.writeShowdownAction(">$showdownId ${showdownMessages.joinToString()}")
}
open fun setupStruct() {
struct.addFunction("uuid") { StringValue(uuid.toString()) }
}
abstract fun getName(): MutableComponent
/**
@@ -136,7 +149,7 @@ abstract class BattleActor(
* NPC and player actors expect to append their [getName] while wild Pokémon append nothing.
*
* @param name The name of an object being appended, typically a Pokémon nickname received from showdown.
* @return A [MutableText] of the [name] append with owner prefix.
* @return A [MutableComponent] of the [name] append with owner prefix.
*/
abstract fun nameOwned(name: String): MutableComponent
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.battles.model.actor
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.phys.Vec3
/**
* Allows a [BattleActor] to attach a [LivingEntity] to itself.
@@ -21,5 +22,6 @@ interface EntityBackedBattleActor<T : LivingEntity> {
* The [LivingEntity] attached to the [BattleActor].
*/
val entity: T?
val initialPos: Vec3?
}
@@ -139,7 +139,7 @@ open class PartySelectPokemonDTO(
aspects = pokemon.aspects,
heldItem = pokemon.heldItemNoCopy(),
currentHealth = pokemon.currentHealth,
maxHealth = pokemon.hp,
maxHealth = pokemon.maxHealth,
enabled = enabled
)
@@ -22,8 +22,10 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
import java.util.UUID
import java.util.concurrent.CompletableFuture
import net.minecraft.server.level.ServerPlayer
/**
@@ -34,19 +36,31 @@ import net.minecraft.server.level.ServerPlayer
* @since December 27th, 2023
*/
class ActiveDialogue(var playerEntity: ServerPlayer, var dialogueReference: Dialogue) {
var initialized = false
val dialogueId = UUID.randomUUID()
val runtime = MoLangRuntime().setup()
var npc: NPCEntity? = null
var currentPage = dialogueReference.pages[0]
val playerStruct = playerEntity.asMoLangValue()
var activeInput = ActiveInput(this, currentPage.input)
init {
val completion = CompletableFuture<Unit>()
fun initialize() {
runtime.environment.query.addFunctions(
mapOf(
"dialogue" to java.util.function.Function { _ -> toMoLangStruct() },
"player" to java.util.function.Function { _ -> playerStruct }
)
)
dialogueReference.initializationAction.invoke(this)
if (!completion.isDone) {
val packet = DialogueOpenedPacket(this, true)
playerEntity.sendPacket(packet)
}
initialized = true
}
val currentPageIndex
@@ -85,7 +99,9 @@ class ActiveDialogue(var playerEntity: ServerPlayer, var dialogueReference: Dial
}
}
}
playerEntity.sendPacket(DialogueOpenedPacket(this, false))
if (initialized) {
playerEntity.sendPacket(DialogueOpenedPacket(this, false))
}
}
fun setPage(index: Int) {
@@ -114,7 +130,10 @@ class ActiveDialogue(var playerEntity: ServerPlayer, var dialogueReference: Dial
}
fun close() {
DialogueManager.stopDialogue(playerEntity)
if (initialized) {
DialogueManager.stopDialogue(playerEntity)
}
completion.complete(Unit)
}
fun escape() {
@@ -9,6 +9,8 @@
package com.cobblemon.mod.common.api.dialogue
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.resources.ResourceLocation
/**
* A dialogue that could be sent to players.
@@ -18,29 +20,39 @@ import com.cobblemon.mod.common.api.molang.ExpressionLike
*/
class Dialogue(
val pages: List<DialoguePage> = mutableListOf(),
val background: ResourceLocation = DEFAULT_BACKGROUND,
val escapeAction: DialogueAction = FunctionDialogueAction { dialogue, _ -> dialogue.close() },
val speakers: Map<String, DialogueSpeaker> = emptyMap()
val speakers: Map<String, DialogueSpeaker> = emptyMap(),
val initializationAction: DialogueAction = FunctionDialogueAction { _, _ -> }
) {
companion object {
val DEFAULT_BACKGROUND = cobblemonResource("textures/gui/dialogue/dialogue_box.png")
@JvmOverloads
fun of(
pages: Iterable<DialoguePage>,
background: ResourceLocation = DEFAULT_BACKGROUND,
escapeAction: ExpressionLike,
speakers: Map<String, DialogueSpeaker>
): Dialogue {
return Dialogue(
pages = pages.toList(),
escapeAction = ExpressionLikeDialogueAction(escapeAction),
background = background,
speakers = speakers
)
}
@JvmOverloads
fun of(
pages: Iterable<DialoguePage>,
background: ResourceLocation = DEFAULT_BACKGROUND,
escapeAction: (ActiveDialogue) -> Unit,
speakers: Map<String, DialogueSpeaker>
): Dialogue {
val dialogue = Dialogue(
pages = pages.toList(),
background = background,
escapeAction = FunctionDialogueAction { activeDialogue, _ -> escapeAction(activeDialogue) },
speakers = speakers
)
@@ -8,8 +8,10 @@
package com.cobblemon.mod.common.api.dialogue
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.util.resolve
/**
@@ -39,6 +41,9 @@ class ExpressionLikeDialogueAction(val expression: ExpressionLike) : DialogueAct
if (input != null) {
dialogue.runtime.environment.setSimpleVariable("selected_option", StringValue(input))
}
dialogue.runtime.resolve(expression)
dialogue.runtime.resolve(
expression,
mapOf("player" to dialogue.playerStruct, "npc" to (dialogue.npc?.struct ?: QueryStruct(hashMapOf())))
)
}
}
@@ -20,6 +20,8 @@ import net.minecraft.resources.ResourceLocation
* @since January 1st, 2024
*/
sealed interface DialogueFaceProvider {
val isLeftSide: Boolean
companion object {
val types = mutableMapOf(
"player" to PlayerDialogueFaceProvider::class.java,
@@ -32,15 +34,24 @@ sealed interface DialogueFaceProvider {
class ArtificialDialogueFaceProvider(
val modelType: String = "",
val identifier: ResourceLocation = cobblemonResource("bulbasaur"),
val aspects: Set<String> = setOf()
val aspects: Set<String> = setOf(),
override val isLeftSide: Boolean = true
) : DialogueFaceProvider
class ReferenceDialogueFaceProvider(
val entityId: Int
val entityId: Int,
override val isLeftSide: Boolean = true
): DialogueFaceProvider
class PlayerDialogueFaceProvider(val playerId: UUID) : DialogueFaceProvider
/**
* A face provider that uses the player's skin as the face, as long as there is a player with this UUID online.
*
* What's interesting is that this works for fake players, which is what Taterzens' NPCs use.
*/
class PlayerDialogueFaceProvider(val playerId: UUID = UUID.randomUUID(), override val isLeftSide: Boolean = true) : DialogueFaceProvider
class ExpressionLikeDialogueFaceProvider(
val providerExpression: ExpressionLike
): DialogueFaceProvider
): DialogueFaceProvider {
override val isLeftSide: Boolean = false // Doesn't get used
}
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.entity.npc.NPCEntity
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.util.activeDialogue
import com.cobblemon.mod.common.util.withQueryValue
import com.cobblemon.mod.common.util.withNPCValue
import java.util.UUID
import net.minecraft.server.level.ServerPlayer
@@ -28,20 +28,25 @@ import net.minecraft.server.level.ServerPlayer
object DialogueManager {
val activeDialogues = mutableMapOf<UUID, ActiveDialogue>()
fun startDialogue(playerEntity: ServerPlayer, dialogue: Dialogue) {
startDialogue(ActiveDialogue(playerEntity, dialogue))
fun startDialogue(playerEntity: ServerPlayer, dialogue: Dialogue): ActiveDialogue {
val activeDialogue = ActiveDialogue(playerEntity, dialogue)
startDialogue(activeDialogue)
return activeDialogue
}
fun startDialogue(playerEntity: ServerPlayer, npcEntity: NPCEntity, dialogue: Dialogue) {
fun startDialogue(playerEntity: ServerPlayer, npcEntity: NPCEntity, dialogue: Dialogue): ActiveDialogue {
val activeDialogue = ActiveDialogue(playerEntity, dialogue)
activeDialogue.runtime.withQueryValue("npc") { npcEntity.struct }
activeDialogue.runtime.withNPCValue("npc", npcEntity)
activeDialogue.npc = npcEntity
startDialogue(activeDialogue)
return activeDialogue
}
fun startDialogue(activeDialogue: ActiveDialogue) {
activeDialogues[activeDialogue.playerEntity.uuid] = activeDialogue
val packet = DialogueOpenedPacket(activeDialogue, true)
activeDialogue.playerEntity.sendPacket(packet)
activeDialogue.initialize()
if (!activeDialogue.completion.isDone) {
activeDialogues[activeDialogue.playerEntity.uuid] = activeDialogue
}
}
fun stopDialogue(playerEntity: ServerPlayer) {
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.api.dialogue.input.DialogueInput
import com.cobblemon.mod.common.api.dialogue.input.DialogueNoInput
import com.google.gson.JsonArray
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
/**
* A page of a dialogue. This has lines of text and also some kind of input expected from the player.
@@ -29,6 +30,7 @@ class DialoguePage(
var speaker: String? = null,
var lines: MutableList<DialogueText> = mutableListOf(),
var input: DialogueInput = DialogueNoInput(),
var background: ResourceLocation? = null,
var clientActions: MutableList<Expression> = mutableListOf(),
var escapeAction: DialogueAction? = null,
) {
@@ -40,6 +42,7 @@ class DialoguePage(
speaker: String? = null,
lines: Iterable<MutableComponent>,
input: DialogueInput = DialogueNoInput(),
background: ResourceLocation? = null,
clientActions: Iterable<Expression> = emptyList(),
/** The thing to do when the player presses ESC while on this page. If null, falls back to the same property on [Dialogue]. */
escapeAction: ((ActiveDialogue) -> Unit)? = null,
@@ -49,6 +52,7 @@ class DialoguePage(
speaker = speaker,
lines = lines.map { WrappedDialogueText(it) }.toMutableList(),
input = input,
background = background,
clientActions = clientActions.toMutableList(),
escapeAction = escapeAction?.let { func -> FunctionDialogueAction { activeDialogue, _ -> func(activeDialogue) } }
)
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.entity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import java.util.concurrent.CompletableFuture
/**
@@ -20,6 +21,6 @@ import java.util.concurrent.CompletableFuture
*
*/
interface PokemonSender {
fun sendingOut(): CompletableFuture<Unit>
fun sendingOut(pokemon: Pokemon): CompletableFuture<Unit>
fun recalling(pokemonEntity: PokemonEntity): CompletableFuture<Unit>
}
@@ -11,10 +11,12 @@ package com.cobblemon.mod.common.api.entity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.entity.player.Player
interface PokemonSideDelegate : EntitySideDelegate<PokemonEntity> {
fun changePokemon(pokemon: Pokemon)
fun drop(source: DamageSource?) {}
fun updatePostDeath() {}
fun handleStatus(status: Byte) {}
fun spawnShinyParticle(player: Player) {}
}
@@ -27,6 +27,7 @@ import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent
import com.cobblemon.mod.common.api.events.pokeball.PokeBallCaptureCalculatedEvent
import com.cobblemon.mod.common.api.events.pokeball.PokemonCatchRateEvent
import com.cobblemon.mod.common.api.events.pokeball.ThrownPokeballHitEvent
import com.cobblemon.mod.common.api.events.pokedex.scanning.PokemonScannedEvent
import com.cobblemon.mod.common.api.events.pokemon.*
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionAcceptedEvent
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
@@ -40,6 +41,7 @@ import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
import com.cobblemon.mod.common.api.events.world.BigRootPropagatedEvent
import com.cobblemon.mod.common.api.reactive.CancelableObservable
import com.cobblemon.mod.common.api.reactive.EventObservable
import com.cobblemon.mod.common.api.reactive.Observable
import com.cobblemon.mod.common.api.reactive.Observable.Companion.filter
import com.cobblemon.mod.common.api.reactive.Observable.Companion.map
import com.cobblemon.mod.common.api.reactive.SimpleObservable
@@ -67,8 +69,6 @@ object CobblemonEvents {
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
@JvmField
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
@JvmField
val HELD_ITEM_UPDATED = CancelableObservable<HeldItemUpdatedEvent>()
@JvmField
val THROWN_POKEBALL_HIT = CancelableObservable<ThrownPokeballHitEvent>()
@@ -147,6 +147,9 @@ object CobblemonEvents {
@JvmField
val STARTER_CHOSEN = CancelableObservable<StarterChosenEvent>()
@JvmField
val POKEMON_SCANNED = EventObservable<PokemonScannedEvent>()
@JvmField
val APRICORN_HARVESTED = EventObservable<ApricornHarvestEvent>()
// Berries
@@ -166,4 +169,9 @@ object CobblemonEvents {
val HELD_ITEM_PRE = CancelableObservable<HeldItemEvent.Pre>()
@JvmField
val HELD_ITEM_POST = EventObservable<HeldItemEvent.Post>()
}
@JvmField
val POKEMON_GAINED = EventObservable<PokemonGainedEvent>()
@JvmField
val POKEMON_SEEN = EventObservable<PokemonSeenEvent>()
}
@@ -0,0 +1,21 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.pokedex.scanning
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.level.ServerPlayer
data class PokemonScannedEvent(val player: ServerPlayer, val scannedEntity: PokemonEntity) {
val pokemon: Pokemon
get() = scannedEntity.pokemon
val isOwned: Boolean
get() = pokemon.getOwnerPlayer() == player
}
@@ -10,5 +10,5 @@ package com.cobblemon.mod.common.api.events.pokemon
//data class HatchEggEvent (
// val pokemon: Pokemon,
// val player: ServerPlayerEntity
// val player: ServerPlayer
//)
@@ -6,12 +6,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.storage.player.adapter
package com.cobblemon.mod.common.api.events.pokemon
import com.cobblemon.mod.common.api.storage.player.PlayerData
import java.util.*
import com.cobblemon.mod.common.pokemon.Pokemon
import java.util.UUID
interface PlayerDataStoreAdapter {
fun load(uuid: UUID): PlayerData
fun save(playerData: PlayerData)
data class PokemonGainedEvent(
val playerId: UUID,
val pokemon: Pokemon
) {
}
@@ -0,0 +1,19 @@
/*
* 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.events.pokemon
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.level.ServerPlayer
import java.util.UUID
data class PokemonSeenEvent(
val playerId: UUID,
val pokemon: Pokemon
) {
}
@@ -29,7 +29,7 @@ data class PokeRod(
val pokeBallId: ResourceLocation,
//Hex string of color
val lineColor: String,
var name: ResourceLocation// ?// TODO (techdaan) Why was this nullable?
var name: ResourceLocation
) {
internal fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeIdentifier(name)
@@ -17,4 +17,6 @@ object ColourLibrary {
const val SIDE_1_ALLY_BATTLE_COLOUR = 0x34C2AC
const val SIDE_2_BATTLE_COLOUR = 0xE43838
const val SIDE_2_ALLY_BATTLE_COLOUR = 0xD55ABA
const val BATTLE_COMMAND_COLOUR = 0xEBBA15
}
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.client.render.models.blockbench.repository.Pokem
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.toHex
import com.mojang.authlib.minecraft.client.MinecraftClient
import com.mojang.blaze3d.platform.GlStateManager
import com.mojang.blaze3d.platform.Lighting
import com.mojang.blaze3d.systems.RenderSystem
@@ -96,8 +98,6 @@ fun drawRectangle(
bufferbuilder.addVertex(matrix, endX, endY, blitOffset).setUv(maxU, maxV)
bufferbuilder.addVertex(matrix, endX, y, blitOffset).setUv(maxU, minV)
bufferbuilder.addVertex(matrix, x, y, blitOffset).setUv(minU, minV)
// TODO: Figure out if this is correct replacement.
// OLD: BufferRenderer.draw(bufferbuilder)
BufferUploader.drawWithShader(bufferbuilder.buildOrThrow())
}
@@ -148,6 +148,21 @@ fun drawText(
return isHovered
}
@JvmOverloads
fun drawTextJustifiedRight(
context: GuiGraphics,
font: ResourceLocation? = null,
text: MutableComponent,
x: Number,
y: Number,
colour: Int,
shadow: Boolean = true
) {
val comp = text.let { if (font != null) it.font(font) else it }
val font = Minecraft.getInstance().font
context.drawString(font, comp, x.toInt() - font.width(comp), y.toInt(), colour, shadow)
}
@JvmOverloads
fun drawText(
context: GuiGraphics,
@@ -189,7 +204,6 @@ fun drawString(
@JvmOverloads
fun drawPosablePortrait(
identifier: ResourceLocation,
aspects: Set<String>,
matrixStack: PoseStack,
scale: Float = 13F,
contextScale: Float = 1F,
@@ -201,7 +215,11 @@ fun drawPosablePortrait(
limbSwingAmount: Float = 0F,
ageInTicks: Float = 0F,
headYaw: Float = 0F,
headPitch: Float = 0F
headPitch: Float = 0F,
r: Float = 1F,
g: Float = 1F,
b: Float = 1F,
a: Float = 1F
) {
RenderSystem.applyModelViewMatrix()
matrixStack.pushPose()
@@ -209,21 +227,19 @@ fun drawPosablePortrait(
matrixStack.scale(scale, scale, -scale)
matrixStack.translate(0.0, -PORTRAIT_DIAMETER / 18.0, 0.0)
val sprite = repository.getSprite(identifier, aspects, SpriteType.PORTRAIT);
val sprite = repository.getSprite(identifier, state, SpriteType.PORTRAIT);
if(sprite == null) {
val model = repository.getPoser(identifier, aspects)
state.currentAspects = aspects
if (sprite == null) {
val model = repository.getPoser(identifier, state)
state.currentModel = model
val texture = repository.getTexture(identifier, aspects, state.animationSeconds)
val texture = repository.getTexture(identifier, state)
val context = RenderContext()
model.context = context
repository.getTextureNoSubstitute(identifier, aspects, 0f).let { context.put(RenderContext.TEXTURE, it) }
repository.getTextureNoSubstitute(identifier, state).let { context.put(RenderContext.TEXTURE, it) }
context.put(RenderContext.SCALE, contextScale)
context.put(RenderContext.SPECIES, identifier)
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.ASPECTS, state.currentAspects)
context.put(RenderContext.POSABLE_STATE, state)
val renderType = RenderType.entityCutout(texture)
@@ -243,7 +259,7 @@ fun drawPosablePortrait(
model.portraitTranslation.z - 4
)
matrixStack.scale(model.portraitScale, model.portraitScale, 1 / model.portraitScale)
matrixStack.mulPose(quaternion1) // TODO (techdaan): correct?
matrixStack.mulPose(quaternion1)
matrixStack.mulPose(quaternion2)
val light1 = Vector3f(0.2F, 1.0F, -1.0F)
@@ -255,8 +271,9 @@ fun drawPosablePortrait(
val buffer = immediate.getBuffer(renderType)
val packedLight = LightTexture.pack(11, 7)
model.withLayerContext(immediate, state, repository.getLayers(identifier, aspects)) {
model.render(context, matrixStack, buffer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
val colour = toHex(r, g, b, a)
model.withLayerContext(immediate, state, repository.getLayers(identifier, state)) {
model.render(context, matrixStack, buffer, packedLight, OverlayTexture.NO_OVERLAY, colour)
immediate.endBatch()
}
@@ -273,7 +290,6 @@ fun drawPosablePortrait(
fun drawProfile(
repository: VaryingModelRepository<*>,
resourceIdentifier: ResourceLocation,
aspects: Set<String>,
matrixStack: PoseStack,
state: PosableState,
partialTicks: Float,
@@ -282,22 +298,20 @@ fun drawProfile(
RenderSystem.applyModelViewMatrix()
matrixStack.scale(scale, scale, -scale)
val sprite = repository.getSprite(resourceIdentifier, aspects, SpriteType.PROFILE);
val sprite = repository.getSprite(resourceIdentifier, state, SpriteType.PROFILE)
if(sprite == null) {
if (sprite == null) {
val model = repository.getPoser(resourceIdentifier, aspects)
val texture = repository.getTexture(resourceIdentifier, aspects, state.animationSeconds)
val model = repository.getPoser(resourceIdentifier, state)
val texture = repository.getTexture(resourceIdentifier, state)
val context = RenderContext()
model.context = context
repository.getTextureNoSubstitute(resourceIdentifier, aspects, 0f)
.let { context.put(RenderContext.TEXTURE, it) }
repository.getTextureNoSubstitute(resourceIdentifier, state).let { context.put(RenderContext.TEXTURE, it) }
context.put(RenderContext.SCALE, 1F)
context.put(RenderContext.SPECIES, resourceIdentifier)
context.put(RenderContext.ASPECTS, aspects)
context.put(RenderContext.ASPECTS, state.currentAspects)
context.put(RenderContext.POSABLE_STATE, state)
state.currentAspects = aspects
state.currentModel = model
val renderType = RenderType.entityCutout(texture)//model.getLayer(texture)
@@ -312,7 +326,7 @@ fun drawProfile(
val quaternion2 = Axis.XP.rotationDegrees(5F)
matrixStack.mulPose(quaternion1)
matrixStack.mulPose(quaternion2)
Lighting.setupForEntityInInventory() // TODO (techdaan): Does this map correctly?
Lighting.setupForEntityInInventory()
val entityRenderDispatcher = Minecraft.getInstance().entityRenderDispatcher
entityRenderDispatcher.setRenderShadow(true)
@@ -323,7 +337,7 @@ fun drawProfile(
RenderSystem.setShaderLights(light1, light2)
val packedLight = LightTexture.pack(11, 7)
model.withLayerContext(bufferSource, state, repository.getLayers(resourceIdentifier, aspects)) {
model.withLayerContext(bufferSource, state, repository.getLayers(resourceIdentifier, state)) {
model.render(context, matrixStack, buffer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
bufferSource.endBatch()
}
@@ -41,20 +41,27 @@ class MultiLineLabelK(
fun renderLeftAligned(
context: GuiGraphics,
x: Number, y: Number,
YStartOffset: Number = 0,
ySpacing: Number,
colour: Int,
scale: Float = 1F,
shadow: Boolean = true
) {
context.pose().pushPose()
context.pose().scale(scale, scale, 1F)
comps.forEachIndexed { index, textWithWidth ->
val yOffset = if (index == 0) YStartOffset else 0
drawString(
context = context,
x = x, y = y.toFloat() + ySpacing.toFloat() * index,
x = x.toFloat() / scale,
y = (y.toFloat() + yOffset.toFloat() + ySpacing.toFloat() * index) / scale,
colour = colour,
shadow = shadow,
text = textWithWidth.text.string,
font = font
)
}
context.pose().popPose()
}
class TextWithWidth internal constructor(val text: FormattedText, val width: Int)
@@ -97,8 +97,9 @@ interface PokemonSelectingItem {
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon))
if (!player.isCreative) {
stack.shrink(1)
battlePokemon.actor.itemsUsed.add(bagItem)
}
CobblemonCriteria.POKEMON_INTERACT.trigger(player, PokemonInteractContext(battlePokemon.entity!!.pokemon.species.resourceIdentifier, BuiltInRegistries.ITEM.getKey(stack.item)))
CobblemonCriteria.POKEMON_INTERACT.trigger(player, PokemonInteractContext(battlePokemon.effectedPokemon.species.resourceIdentifier, BuiltInRegistries.ITEM.getKey(stack.item)))
}
}
@@ -10,6 +10,8 @@ package com.cobblemon.mod.common.api.molang
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.util.asExpressionLike
import com.mojang.serialization.Codec
/**
* An object that can be given a [MoLangRuntime] to produce a single [MoValue]. This abstracts
@@ -21,7 +23,7 @@ import com.bedrockk.molang.runtime.value.MoValue
interface ExpressionLike {
override fun toString(): String
/** Produces a [MoValue] for a [MoLangRuntime] to supply an environment. */
fun resolve(runtime: MoLangRuntime, context: Map<String, MoValue> = emptyMap()): MoValue
fun resolve(runtime: MoLangRuntime, context: Map<String, MoValue> = runtime.environment.context?.map ?: hashMapOf()): MoValue
fun getString(): String = toString()
fun resolveDouble(runtime: MoLangRuntime) = resolve(runtime).asDouble()
@@ -31,4 +33,11 @@ interface ExpressionLike {
fun resolveBoolean(runtime: MoLangRuntime) = resolveDouble(runtime) == 1.0
fun resolveObject(runtime: MoLangRuntime) = resolve(runtime) as ObjectValue<*>
companion object {
val CODEC: Codec<ExpressionLike> = Codec.STRING.xmap({
it.asExpressionLike()
}) {
it.getString()
}
}
}
@@ -18,23 +18,25 @@ import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonActivities
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
import com.cobblemon.mod.common.api.dialogue.ReferenceDialogueFaceProvider
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.animations.NPCProvider
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunctions
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.effectiveName
import com.cobblemon.mod.common.util.getBooleanOrNull
import com.cobblemon.mod.common.util.getDoubleOrNull
import com.cobblemon.mod.common.util.isInt
import com.cobblemon.mod.common.util.itemRegistry
import com.cobblemon.mod.common.util.worldRegistry
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.*
import com.mojang.datafixers.util.Either
import net.minecraft.client.gui.components.tabs.Tab
import java.util.UUID
import net.minecraft.commands.arguments.EntityAnchorArgument
import net.minecraft.core.Holder
import net.minecraft.core.Registry
import net.minecraft.core.registries.Registries
@@ -44,10 +46,9 @@ import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceKey
import net.minecraft.server.level.ServerPlayer
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.commands.TagCommand
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.tags.TagKey
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.damagesource.DamageTypes
@@ -57,6 +58,8 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.dimension.DimensionType
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
/**
* Holds a bunch of useful MoLang trickery that can be used or extended in API
@@ -101,6 +104,12 @@ object MoLangFunctions {
runtime.environment.context = params.environment.context
val script = params.getString(0).asIdentifierDefaultingNamespace()
CobblemonScripts.run(script, runtime) ?: DoubleValue(0)
},
"run_command" to java.util.function.Function { params ->
val command = params.getString(0)
server()?.let {
return@Function DoubleValue(it.commands.dispatcher.execute(command, it.createCommandSourceStack()))
} ?: return@Function DoubleValue.ZERO
}
)
val biomeFunctions = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
@@ -116,10 +125,11 @@ object MoLangFunctions {
map.put("save_data") { _ -> if (player is ServerPlayer) Cobblemon.molangData.save(player.uuid) else DoubleValue(0) }
map.put("main_held_item") { _ -> player.level().itemRegistry.wrapAsHolder(player.mainHandItem.item).asMoLangValue(Registries.ITEM) }
map.put("off_held_item") { _ -> player.level().itemRegistry.wrapAsHolder(player.offhandItem.item).asMoLangValue(Registries.ITEM) }
map.put("face") { _ -> ObjectValue(PlayerDialogueFaceProvider(player.uuid)) }
map.put("face") { params -> ObjectValue(PlayerDialogueFaceProvider(player.uuid, params.getBooleanOrNull(0) != false)) }
map.put("swing_hand") { _ -> player.swing(player.usedItemHand) }
map.put("food_level") { _ -> DoubleValue(player.foodData.foodLevel) }
map.put("saturation_level") { _ -> DoubleValue(player.foodData.saturationLevel) }
// map.put("has_permission") { params -> DoubleValue(Cobblemon.permissionValidator.hasPermission(player, Permission)) }
map.put("tell") { params ->
val message = params.getString(0).text()
val overlay = params.getBooleanOrNull(1) ?: false
@@ -141,12 +151,35 @@ object MoLangFunctions {
environment.query = player.asMoLangValue()
environment
}
if (player is ServerPlayer) {
map.put("is_party_at_full_health") { _ ->
DoubleValue(player.party().none(Pokemon::canBeHealed)) }
map.put("can_heal_at_healer") { params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer = player.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null) ?: return@put DoubleValue.ZERO
val party = player.party()
return@put DoubleValue(healer.canHeal(party))
}
map.put("put_pokemon_in_healer") { params ->
val healer = player.level()
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
.orElse(null) ?: return@put DoubleValue.ZERO
val party = player.party()
if (healer.canHeal(party)) {
healer.activate(player.uuid, party)
return@put DoubleValue.ONE
} else {
return@put DoubleValue.ZERO
}
}
}
map
}
)
val entityFunctions = mutableListOf<(LivingEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ entity ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("uuid") { _ -> StringValue(entity.uuid.toString()) }
map.put("damage") { params ->
val amount = params.getDouble(0)
val source = DamageSource(entity.level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolder(DamageTypes.GENERIC).get())
@@ -178,15 +211,34 @@ object MoLangFunctions {
map.put("is_on_ground") { _ -> DoubleValue(entity.onGround()) }
map.put("world") { _ -> entity.level().worldRegistry.wrapAsHolder(entity.level()).asWorldMoLangValue() }
map.put("biome") { _ -> entity.level().getBiome(entity.blockPosition()).asBiomeMoLangValue() }
map.put("is_healer_in_use") { params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer = entity.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null) ?: return@put DoubleValue.ONE
return@put DoubleValue(healer.isInUse)
}
map.put("find_nearby_block") { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft")
val isTag = type.path.startsWith("#")
val range = params.getDoubleOrNull(1) ?: 10
val blockPos = entity.level().getBlockStatesWithPos(AABB.ofSize(entity.position(), range.toDouble(), range.toDouble(), range.toDouble()))
.filter { it.first.blockHolder.let { if (isTag) it.`is`(TagKey.create(Registries.BLOCK, type)) else it.`is`(type) } }
.minByOrNull { it.second.distSqr(entity.blockPosition()) }
?.second
if (blockPos != null) {
return@put ArrayStruct(mapOf("0" to DoubleValue(blockPos.x), "1" to DoubleValue(blockPos.y), "2" to DoubleValue(blockPos.z)))
} else {
return@put DoubleValue.ZERO
}
}
map
}
)
val npcFunctions = mutableListOf<(NPCEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ npc ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("class") { StringValue(npc.npc.resourceIdentifier.toString()) }
map.put("class") { StringValue(npc.npc.id.toString()) }
map.put("name") { StringValue(npc.name.string) }
map.put("face") { ObjectValue(ReferenceDialogueFaceProvider(npc.id)) }
map.put("face") { params -> ObjectValue(ReferenceDialogueFaceProvider(npc.id, params.getBooleanOrNull(0) != false)) }
map.put("in_battle") { DoubleValue(npc.isInBattle()) }
map.put("run_script_on_client") { params ->
val world = npc.level()
@@ -199,13 +251,50 @@ object MoLangFunctions {
}
map.put("run_script") { params ->
val script = params.getString(0).asIdentifierDefaultingNamespace()
val environment = params.environment
val runtime = MoLangRuntime()
runtime.environment.query = environment.query
runtime.environment.variable = environment.variable
runtime.environment.context = environment.context
runtime.environment.cloneFrom(params.environment)
CobblemonScripts.run(script, runtime) ?: DoubleValue(0)
}
map.put("run_action_effect") { params ->
val runtime = MoLangRuntime().setup()
runtime.environment.cloneFrom(params.environment)
runtime.withNPCValue(value = npc)
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
if (actionEffect != null) {
val context = ActionEffectContext(
actionEffect = actionEffect,
providers = mutableListOf(NPCProvider(npc)),
runtime = runtime
)
npc.actionEffect = context
npc.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
npc.brain.setActiveActivityIfPossible(CobblemonActivities.NPC_ACTION_EFFECT)
actionEffect.run(context).thenRun {
val npcActionEffect = npc.brain.getMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT).orElse(null)
if (npcActionEffect == context && npc.brain.isActive(CobblemonActivities.NPC_ACTION_EFFECT)) {
npc.brain.eraseMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT)
npc.actionEffect = null
}
}
return@put DoubleValue(1)
}
return@put DoubleValue(0)
}
map.put("put_pokemon_in_healer") { params ->
val healer = npc.level().getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE).orElse(null) ?: return@put DoubleValue.ZERO
val party = npc.staticParty ?: return@put DoubleValue.ZERO
if (healer.canHeal(party)) {
healer.activate(npc.uuid, party)
return@put DoubleValue.ONE
} else {
return@put DoubleValue.ZERO
}
}
map.put("look_at_position") { params ->
val pos = Vec3(params.getDouble(0), params.getDouble(1), params.getDouble(2))
npc.lookAt(EntityAnchorArgument.Anchor.EYES, pos)
}
map.put("environment") { _ -> npc.runtime.environment }
map
}
@@ -220,6 +309,11 @@ object MoLangFunctions {
map.put("is_pvw") { DoubleValue(battle.isPvW) }
map.put("battle_type") { StringValue(battle.format.toString()) }
map.put("environment") { battle.runtime.environment }
map.put("get_actor") { params ->
val uuid = UUID.fromString(params.getString(0))
val actor = battle.actors.find { it.uuid == uuid } ?: return@put DoubleValue.ZERO
return@put actor.struct
}
map
}
)
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.molang
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
/**
@@ -20,7 +21,7 @@ import com.bedrockk.molang.runtime.value.MoValue
class ObjectValue<T>(
var obj: T,
val stringify: (T) -> String = { it.toString() },
val doublify: (T) -> Double = { throw NotImplementedError("Doublify not implemented for this object value, are you doing weird molang") }
val doublify: (T) -> Double = { DoubleValue.ONE.value }
) : QueryStruct(hashMapOf()) {
override fun value() = this
override fun asDouble() = doublify(obj)
@@ -118,6 +118,8 @@ open class Move(
return json
}
fun copy() = loadFromJSON(saveToJSON(JsonObject()))
fun saveToBuffer(buffer: RegistryFriendlyByteBuf) {
buffer.writeString(name)
buffer.writeSizedInt(IntSize.U_BYTE, currentPp)
@@ -35,10 +35,8 @@ class MoveSet : Iterable<Move> {
/**
* Gets all Moves from the Pokémon but skips null Moves
*/
fun getMoves(): List<Move> {
return moves.filterNotNull()
}
fun getMoves() = moves.filterNotNull()
fun getMovesWithNulls() = moves.toList()
fun hasSpace() = moves.any { it == null }
/**
@@ -56,7 +54,7 @@ class MoveSet : Iterable<Move> {
fun copyFrom(other: MoveSet) {
doWithoutEmitting {
clear()
other.getMoves().forEach { add(it) }
other.getMoves().forEach { add(it.copy()) }
}
update()
}
@@ -125,6 +123,7 @@ class MoveSet : Iterable<Move> {
for (i in 0 until MOVE_COUNT) {
if (moves[i] == null) {
moves[i] = move
move.observable.subscribe { this.update() }
update()
return
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.moves.animations
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.keyframes.ActionEffectKeyframe
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import net.minecraft.world.entity.Entity
@@ -38,7 +39,7 @@ class ActionEffectTimeline(
CompletableFuture.completedFuture(Unit)
} else {
val finalFuture = CompletableFuture<Unit>()
// .toList copy because I'm paranoid about iterators being trying to share between identical effects playing
// .toList copy because I'm paranoid about iterators trying to share between identical effects playing
chainKeyframes(context, timeline.toList().iterator(), finalFuture)
finalFuture
}.exceptionallyCompose {
@@ -71,8 +72,6 @@ class ActionEffectContext(
var currentKeyframes: MutableList<ActionEffectKeyframe> = mutableListOf()
) {
inline fun <reified T> findOneProvider() = providers.filterIsInstance<T>().firstOrNull()
}
class UsersProvider(users: List<Entity>): EntityProvider {
@@ -85,12 +84,16 @@ class TargetsProvider(targets: List<Entity>): EntityProvider {
constructor(vararg targets: Entity): this(targets.toList())
}
class NPCProvider(npc: NPCEntity): EntityProvider {
override val entities = listOf(npc)
}
interface EntityProvider {
val entities: List<Entity>
}
//class MoveAnimationKeyframe(
// val sound: Identifier? = null,
// val sound: ResourceLocation? = null,
// val animation: List<AnimationWithMoments> = listOf(),
// val effects: List<ActionEffect> = listOf()
//)
@@ -31,7 +31,7 @@ class AnimationActionEffectKeyframe : ConditionalActionEffectKeyframe(), EntityC
.filterIsInstance<EntityProvider>()
.flatMap { prov -> prov.entities.filter { test(context, it, isUser = prov is UsersProvider) } }
val expressions = variables.map { it.originalString }.toSet()
val expressions = variables.map { it.originalString }
// Treat them as expressions if possible but otherwise yeah just send them as strings
val animation = animation.map {
@@ -13,7 +13,7 @@ import java.util.concurrent.CompletableFuture
class CannotInterruptActionEffectKeyframe : ConditionalActionEffectKeyframe() {
override fun playWhenTrue(context: ActionEffectContext): CompletableFuture<Unit> {
context.canBeInterrupted = true
context.canBeInterrupted = false
return CompletableFuture.completedFuture(Unit)
}
}
@@ -13,6 +13,7 @@ import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.entity.PosableEntity
import net.minecraft.world.entity.Entity
/**
@@ -24,12 +25,16 @@ import net.minecraft.world.entity.Entity
interface EntityConditionalActionEffectKeyframe {
val entityCondition: ExpressionLike
fun test(context: ActionEffectContext, entity: Entity, isUser: Boolean): Boolean {
// TODO this should use the entity's own query struct
context.runtime.environment.query.addFunction("entity") {
QueryStruct(hashMapOf())
.addFunction("uuid") { StringValue(entity.stringUUID) }
.addFunction("is_user") { DoubleValue(isUser) }
}
context.runtime.environment.query
.addFunction("entity") {
if (entity is PosableEntity) {
entity.struct
} else {
QueryStruct(hashMapOf())
}.addFunction("is_user") { DoubleValue(isUser) } // Deprecated tbh
}
.addFunction("is_user") { DoubleValue(isUser) }
return entityCondition.resolveBoolean(context.runtime)
}
}
@@ -45,7 +45,7 @@ class EntityParticlesActionEffectKeyframe : ConditionalActionEffectKeyframe(), E
}?.asIdentifierDefaultingNamespace() ?: return skip()
entities.filter { it is PosableEntity }.forEach { entity ->
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, locator)
val packet = SpawnSnowstormEntityParticlePacket(effectIdentifier, entity.id, listOf(locator))
val players = (entity.level() as ServerLevel).getPlayers { it.distanceTo(entity) <= visibilityRange }
packet.sendToPlayers(players)
}
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.moves.animations.keyframes
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.scheduling.delayedFuture
@@ -59,6 +59,8 @@ abstract class MultiblockEntity(
}
}
override fun isValidBlockState(blockState: BlockState) = blockState.block is MultiblockBlock
abstract override fun loadAdditional(nbt: CompoundTag, registryLookup: HolderLookup.Provider)
}
@@ -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.net.serializers
import com.cobblemon.mod.common.entity.npc.NPCPlayerModelType
import com.cobblemon.mod.common.entity.npc.NPCPlayerTexture
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.writeEnumConstant
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.codec.StreamCodec
import net.minecraft.network.syncher.EntityDataSerializer
object NPCPlayerTextureSerializer : EntityDataSerializer<NPCPlayerTexture> {
val ID = cobblemonResource("npcplayertexture")
fun write(buffer: RegistryFriendlyByteBuf, texture: NPCPlayerTexture) {
buffer.writeEnumConstant(texture.model)
if (texture.model == NPCPlayerModelType.NONE) {
return
}
buffer.writeByteArray(texture.texture)
}
fun read(buffer: RegistryFriendlyByteBuf): NPCPlayerTexture {
val model = buffer.readEnumConstant(NPCPlayerModelType::class.java)
val texture = if (model == NPCPlayerModelType.NONE) ByteArray(1) else buffer.readByteArray()
return NPCPlayerTexture(texture, model)
}
override fun codec() = StreamCodec.of(::write, ::read)
override fun copy(texture: NPCPlayerTexture) = NPCPlayerTexture(texture.texture, texture.model)
}
@@ -11,13 +11,15 @@ package com.cobblemon.mod.common.api.npc
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.npc.configuration.NPCBattleConfiguration
import com.cobblemon.mod.common.api.npc.configuration.NPCConfigVariable
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
import com.cobblemon.mod.common.api.npc.variation.RandomNPCVariationProvider
import com.cobblemon.mod.common.net.IntSize
import com.cobblemon.mod.common.util.*
import com.mojang.datafixers.util.Either
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.EntityDimensions
@@ -30,24 +32,49 @@ import net.minecraft.world.entity.EntityDimensions
*/
class NPCClass {
@Transient
lateinit var resourceIdentifier: ResourceLocation
lateinit var id: ResourceLocation
var names = mutableListOf(lang("npc.name.default"))
var resourceIdentifier: ResourceLocation = cobblemonResource("dummy")
var names: MutableList<Component> = mutableListOf()
var aspects: MutableSet<String> = mutableSetOf() // These only make sense when applied via presets
var hitbox = EntityDimensions.scalable(0.6F, 1.8F)
var battleConfiguration = NPCBattleConfiguration()
var aiScripts: MutableList<ResourceLocation> = mutableListOf()
var interaction: NPCInteractConfiguration? = null
var variables = mutableMapOf<String, MoValue>()
var variations: MutableMap<String, NPCVariationProvider> = mutableMapOf()
var config: MutableList<NPCConfigVariable> = mutableListOf()
var variables = mutableMapOf<String, MoValue>() // Questionable whether this should be here.
var party: NPCPartyProvider? = null
var skill: Int = 0
// If you're adding stuff here, add it to NPCPreset and NPCClassAdapter too
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeString(resourceIdentifier.toString())
buffer.writeCollection(names) { _, v -> buffer.writeText(v) }
buffer.writeFloat(this.hitbox.width)
buffer.writeFloat(this.hitbox.height)
buffer.writeBoolean(this.hitbox.fixed)
battleConfiguration.encode(buffer)
buffer.writeCollection(aiScripts) { _, v -> buffer.writeString(v.toString()) }
buffer.writeNullable(interaction) { _, value ->
buffer.writeString(value.type)
value.encode(buffer)
}
buffer.writeSizedInt(IntSize.U_BYTE, variations.size)
for ((key, value) in variations) {
buffer.writeString(key)
val aspects = value.aspects
buffer.writeCollection(aspects) { _, v -> buffer.writeString(v) }
}
buffer.writeCollection(config) { _, v ->
buffer.writeString(v.variableName)
buffer.writeText(v.displayName)
buffer.writeText(v.description)
buffer.writeEnumConstant(v.type)
buffer.writeString(v.defaultValue)
}
buffer.writeInt(skill)
buffer.writeMapK(size = IntSize.U_BYTE, map = variables) { (key, value) ->
buffer.writeString(key)
buffer.writeString(value.asString())
@@ -55,6 +82,7 @@ class NPCClass {
}
fun decode(buffer: RegistryFriendlyByteBuf) {
resourceIdentifier = ResourceLocation.parse(buffer.readString().toString())
names = buffer.readList { buffer.readText().copy() }.toMutableList()
val length = buffer.readFloat()
val width = buffer.readFloat()
@@ -62,6 +90,7 @@ class NPCClass {
hitbox = if (fixed) EntityDimensions.fixed(length, width) else EntityDimensions.scalable(length, width)
battleConfiguration = NPCBattleConfiguration()
battleConfiguration.decode(buffer)
aiScripts = buffer.readList { ResourceLocation.parse(buffer.readString()) }.toMutableList()
interaction = buffer.readNullable {
val type = buffer.readString()
val configType = NPCInteractConfiguration.types[type] ?: return@readNullable null
@@ -69,6 +98,22 @@ class NPCClass {
instance.decode(buffer)
instance
}
val variationSize = buffer.readSizedInt(IntSize.U_BYTE)
for (i in 0 until variationSize) {
val key = buffer.readString()
val aspects = buffer.readList { buffer.readString() }.toSet()
val provider = RandomNPCVariationProvider(aspects)
variations[key] = provider
}
config = buffer.readList {
val variableName = buffer.readString()
val displayName = buffer.readText()
val description = buffer.readText()
val type = buffer.readEnumConstant(NPCConfigVariable.NPCVariableType::class.java)
val defaultValue = buffer.readString()
NPCConfigVariable(variableName, displayName, description, type, defaultValue)
}.toMutableList()
skill = buffer.readInt()
buffer.readMapK(size = IntSize.U_BYTE, map = variables) {
val key = buffer.readString()
val value = buffer.readString()
@@ -18,6 +18,8 @@ import com.cobblemon.mod.common.api.drop.ItemDropMethod
import com.cobblemon.mod.common.api.entity.EntityDimensionsAdapter
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
import com.cobblemon.mod.common.api.npc.variation.WeightedAspect
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.spawning.TimeRange
@@ -30,6 +32,7 @@ import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.mojang.datafixers.util.Either
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
@@ -57,7 +60,12 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
.registerTypeAdapter(CompoundTag::class.java, NbtCompoundAdapter)
.registerTypeAdapter(NPCPartyProvider::class.java, NPCPartyProviderAdapter)
.registerTypeAdapter(NPCInteractConfiguration::class.java, NPCInteractConfigurationAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(MoValue::class.java, MoValueAdapter)
.registerTypeAdapter(NPCClass::class.java, NPCClassAdapter)
.registerTypeAdapter(Component::class.java, TextAdapter)
.registerTypeAdapter(NPCVariationProvider::class.java, NPCVariationProviderAdapter)
.registerTypeAdapter(WeightedAspect::class.java, WeightedAspectAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
@@ -95,7 +103,7 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
/**
* Finds an [NPCClass] by its unique [ResourceLocation].
*
* @param identifier The unique [NPCClass.resourceIdentifier] of the [NPCClass].
* @param identifier The unique [NPCClass.id] of the [NPCClass].
* @return The [NPCClass] if existing.
*/
fun getByIdentifier(identifier: ResourceLocation) = this.npcClassesByIdentifier[identifier]
@@ -116,10 +124,20 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
*/
fun random(): NPCClass = this.npcClassesByIdentifier.values.random()
fun dummy(): NPCClass {
val dummy = NPCClass()
dummy.id = cobblemonResource("dummy")
return dummy
}
override fun reload(data: Map<ResourceLocation, NPCClass>) {
this.npcClassesByIdentifier.clear()
data.forEach { (identifier, species) ->
species.resourceIdentifier = identifier
species.id = identifier
// shortcut so they don't have to state the resource identifier if they don't wanna
if (species.resourceIdentifier.path == "dummy") {
species.resourceIdentifier = identifier
}
this.npcClassesByIdentifier[identifier] = species
}
}
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.npc
import com.cobblemon.mod.common.api.npc.partyproviders.DynamicPartyProvider
import com.cobblemon.mod.common.api.npc.partyproviders.NPCParty
import com.cobblemon.mod.common.api.npc.partyproviders.SimplePartyProvider
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.entity.npc.NPCEntity
@@ -26,16 +28,12 @@ import net.minecraft.server.level.ServerPlayer
interface NPCPartyProvider {
companion object {
val types = mutableMapOf<String, (String) -> NPCPartyProvider>(
SimplePartyProvider.TYPE to { SimplePartyProvider() }
SimplePartyProvider.TYPE to { SimplePartyProvider() },
DynamicPartyProvider.TYPE to { DynamicPartyProvider() }
)
}
val type: String
fun provide(npc: NPCEntity, challengers: List<ServerPlayer>): PartyStore
fun encode(buffer: RegistryFriendlyByteBuf)
fun decode(buffer: RegistryFriendlyByteBuf)
fun saveToNBT(nbt: CompoundTag)
fun loadFromNBT(nbt: CompoundTag)
fun provide(npc: NPCEntity, level: Int): NPCParty
fun loadFromJSON(json: JsonElement)
}
@@ -8,11 +8,40 @@
package com.cobblemon.mod.common.api.npc
import com.cobblemon.mod.common.api.npc.configuration.NPCConfigVariable
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.EntityDimensions
class NPCPreset {
lateinit var id: ResourceLocation
var resourceIdentifier: ResourceLocation? = null
var aspects: Set<String>? = null
var variations: Map<String, NPCVariationProvider>? = null
var config: List<NPCConfigVariable>? = null
var party: NPCPartyProvider? = null
// var mergeMode = MergeMode.KEEP
var aiScripts: List<ResourceLocation>? = null
var interaction: NPCInteractConfiguration? = null
var names: MutableSet<Component>? = null
var hitbox: EntityDimensions? = null
var skill: Int? = null
fun applyTo(npcClass: NPCClass) {
resourceIdentifier?.let { npcClass.resourceIdentifier = it }
aspects?.let { npcClass.aspects.addAll(it) }
config?.forEach {
val variableName = it.variableName
npcClass.config.removeIf { it.variableName == variableName }
npcClass.config.add(it)
}
variations?.entries?.forEach { (key, value) -> npcClass.variations[key] = value }
party?.let { npcClass.party = it }
aiScripts?.let { npcClass.aiScripts.addAll(it) }
interaction?.let { npcClass.interaction = it }
names?.let { npcClass.names.addAll(it) }
hitbox?.let { npcClass.hitbox = it }
skill?.let { npcClass.skill = it }
}
}
@@ -0,0 +1,87 @@
/*
* 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.npc
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.ai.SleepDepth
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.drop.DropEntry
import com.cobblemon.mod.common.api.drop.ItemDropMethod
import com.cobblemon.mod.common.api.entity.EntityDimensionsAdapter
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.spawning.TimeRange
import com.cobblemon.mod.common.util.adapters.*
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.mojang.datafixers.util.Either
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.entity.EntityDimensions
import net.minecraft.world.item.Item
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
import net.minecraft.world.phys.AABB
object NPCPresets : JsonDataRegistry<NPCPreset> {
override val id = cobblemonResource("npc_preset")
override val type = PackType.SERVER_DATA
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(EntityDimensions::class.java, EntityDimensionsAdapter)
.registerTypeAdapter(AABB::class.java, BoxAdapter)
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(TimeRange::class.java, IntRangesAdapter(TimeRange.timeRanges) { TimeRange(*it) })
.registerTypeAdapter(ItemDropMethod::class.java, ItemDropMethod.adapter)
.registerTypeAdapter(SleepDepth::class.java, SleepDepth.adapter)
.registerTypeAdapter(DropEntry::class.java, DropEntryAdapter)
.registerTypeAdapter(CompoundTag::class.java, NbtCompoundAdapter)
.registerTypeAdapter(NPCPartyProvider::class.java, NPCPartyProviderAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(NPCInteractConfiguration::class.java, NPCInteractConfigurationAdapter)
.registerTypeAdapter(MoValue::class.java, MoValueAdapter)
.registerTypeAdapter(Component::class.java, TextAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(Either::class.java, ResourceLocation::class.java, ExpressionLike::class.java).type, NPCScriptAdapter)
.disableHtmlEscaping()
.enableComplexMapKeySerialization()
.create()
override val typeToken: TypeToken<NPCPreset> = TypeToken.get(NPCPreset::class.java)
override val resourcePath = "npcs"
override val observable = SimpleObservable<NPCPresets>()
private val npcPresetsByIdentifier = mutableMapOf<ResourceLocation, NPCPreset>()
override fun sync(player: ServerPlayer) {
// TODO probably do want to sync the presets
}
override fun reload(data: Map<ResourceLocation, NPCPreset>) {
npcPresetsByIdentifier.clear()
npcPresetsByIdentifier.putAll(data)
observable.emit(this)
}
fun getPreset(identifier: ResourceLocation): NPCPreset? {
return npcPresetsByIdentifier[identifier]
}
}
@@ -0,0 +1,273 @@
# Cobbled NPCs
NPC's are AI-driven entities that are built on the same identifier-aspects rendering platform
as Cobblemon's Pokémon entities. Every NPC in the world is based on an [NPC class](#npc-classes).
## NPC Classes
An NPC class is a datapacked JSON (inside the <code>npcs</code> folder) that defines many properties of an NPC in a way that's reusable
across any number of individual NPC entities. The possible properties are explained in [NPC Properties](#npc-properties)
## NPC Class Presets
For many properties or sets of properties of an NPC class, there may be logical grouping of settings.
As an example, many types of trainer NPC classes could share the logic of challenging nearby players
that they are able to see. This could become tedious if the same AI script and range config needed to
be defined on every NPC class. Not only is it tedious, but if there was some tweak that was made in the
underlying logic of that AI, it would need to be updated in every single NPC class JSON that uses it.
The solution to this is NPC Class Presets, a datapack folder (<code>npc_presets</code>) with JSON files that have an almost identical
format to [NPC Classes](#npc-classes), but with every property being nullable. An NPC class can reference
any number of presets and the properties of those presets will be merged into the NPC class as it loads.
## NPC Properties
{
"hitbox": "player",
"resourceIdentifier": "cobblemon:bug_catcher",
"presets": [
"cobblemon:npc-standard"
],
"variations": {
"dirt": [
"clean",
"slightly_dirty",
"dirty",
"filthy"
],
"net": {
"type": "weighted",
"options": [
{
"aspect": "green-net",
"weight": 10
},
{
"aspect": "blue-net",
"weight": 5
},
{
"aspect": "red-net",
"weight": 1
}
]
}
},
"config": [
{
"variableName": "challenge_distance",
"displayName": "cobblemon.npc.challenge_distance",
"description": "cobblemon.npc.challenge_distance.description",
"type": "number",
"default": "5"
}
],
"names": [
"Vera",
"Hiro",
"John Cobblemon"
],
"interaction": {
"type": "dialogue",
"dialogue": "cobblemon:npc-example"
},
"battleConfiguration": {
"canChallenge": true
},
"skill": 5,
"party": {
"type": "simple",
"pokemon": [
"spiritomb level=1 moves=splash,firepunch,flamethrower,swift",
"porygonz level=1 speed_ev=252",
"togekiss level=1 nature=timid",
"lucario level=1 held_item=cobblemon:focus_sash",
"milotic level=1 ability=marvelscale ",
"garchomp level=1 hp_iv=31 attack_iv=31"
]
}
}
### hitbox
The hitbox of the NPC, relevant to combat and pathing. This can be defined as an object
or as a shortcut string that is predefined in the code. The only currently hardcoded
hitbox name is "player", which is the standard Steve Minecraft hitbox and is the same as
this fully defined hitbox:
"hitbox": {
"width": 0.6,
"height": 1.8
}
### resourceIdentifier
An optional property representing the 'identifier' that will be used for rendering the NPC.
In a way, this is the same as the "species" of a Pokémon. It is this value combined with
whatever aspects have been defined for the NPC that completely handles the appearance of the
NPC. This identifier is referenced in the variation JSONs on the client.
If left blank, it will fallback to the identifier used for the NPC class itself. The reason why
this is useful is that it allows several NPC classes to appear the same despite having differences
in AI, parties, interactions, etc.
### presets
A list of strings representing the identifiers of [NPC Class Presets](#npc-class-presets) that form the foundation of
this NPC class. Any property defined in this class will override the same property in the presets.
### variations
A map of variations that generate the aspects that control the appearance of the NPC. The keys of this
map should represent the kind of variation that is being defined, and the values are some kind of [NPC Variation](#npc-variation).
Variations can be defined in presets and flow through to the NPC class, but they can also be defined
in the NPC class. If the same name is used in both a preset and an NPC class, that which is on the NPC
class will override that from the preset. If the variation names are different, they will be merged together.
#### NPC Variation
An NPC variation is some way in which aspects can be generated for the NPC. The types of variation can
be added using the API, but the type most anticipated is the weighted choice aspects.
This can be defined as a list of strings, in which case the aspect will be chosen randomly from the list
with uniform distribution.
"dirt": [
"clean",
"slightly_dirty",
"dirty",
"filthy"
]
The weighted variation can also be defined more fully, which is necessary if you want some options to be
more likely than others.
"net": {
"type": "weighted",
"options": [
{
"aspect": "green-net",
"weight": 10
},
{
"aspect": "blue-net",
"weight": 5
},
{
"aspect": "red-net",
"weight": 1
}
]
}
In this example, the "net" value will be "green-net" most of the time, 10 times out of 16. The "blue-net"
aspect will be chosen 5 times out of 16, and the "red-net" aspect will be chosen 1 time out of 16.
When using a type of NPC variation that is not "weighted", the value of "type" must specify it and the
other values (instead of "options") will be in whatever format is dictated by that type.
### config
A list of NPC config values that are predefined as being necessary for this class. An NPC config
variable's value is used in the MoLang environment of the NPC and can be accessed in any MoLang
environment that has the NPC.
This class property is a way to present clear options to the user if configuring an NPC in-game using
the NPC Edit command. This does not mean that NPC variables can only be created when they were defined
in the class, but it makes it easier for the user to know what variables should be set and will set
the initial values when an NPC is initialized.
An example situation of using this is if there is an NPC class preset that defines an AI script for
challenging a player when they come within a certain range. Inside that class preset, the AI script may
need to know at what distance the player will be engaged. This can be defined in the NPC class preset as
a config variable, and therefore any NPC class that relies on this preset will have that config variable
and present it to users when they setup an NPC of that class.
"config": [
{
"variableName": "challenge_distance",
"displayName": "cobblemon.npc.challenge_distance",
"description": "cobblemon.npc.challenge_distance.description",
"type": "number",
"default": "5"
}
]
The "type" of variable is one of: `string`, `number`, or `boolean`. The type is used to preset a more
appropriate input field for the user when they are setting up the NPC.
### names
A list of strings that represent the names that the NPC can have. The name of the NPC is chosen randomly
when initialized. These can either be simple names or translation keys so provide localization support.
### interaction
An object that defines how the NPC will handle being interacted with by players. The type of interaction
is defined by the "type" property, and different types of interaction have different properties.
#### dialogue
The "dialogue" interaction type is a simple way to have an NPC say something when interacted with. The
"dialogue" property should be the identifier of a datapacked dialogue JSON file. The dialogue that is
created will have `c.npc` as a contextual property in any script that occurs as part of that dialogue,
allowing the dialogue to work with the NPC (including the NPC config values, such as
`c.npc.config.challenge_distance`).
"interaction": {
"type": "dialogue",
"dialogue": "cobblemon:npc-example"
}
#### script
The "script" interaction type is a way to have an NPC run a predefined script when interacted with. The
script field is an identifier of a datapacked MoLang script file (in the `scripts` folder).
"interaction": {
"type": "script",
"script": "cobblemon:npc-example"
}
#### custom_script
The "custom_script" interaction type is a way to have an NPC run the MoLang script defined specifically
in this file. The script property can be a single string or an array of strings to do multiline MoLang scripts.
"interaction": {
"type": "custom_script",
"script": "c.player.tell('My name is ' + c.npc.name);"
}
### battleConfiguration
I don't really know whether this is going to stay tbh
### skill
The skill level when this NPC is used in battle. This is a number from 1 to 5, with 5 being most difficult
to beat. This does not control their Pokémon's levels or moves, but it does control how well they use them.
### party
A party provider which generates the party of Pokémon that this NPC will have when in battle. The type of
party is defined by the "type", and different types of party have different properties. An NPC party is
intended to be initialized when an NPC is spawned and uses a 'seed level'. When spawned using the world
spawning system, it will use a seed level that is based on the player's party's average level. When
spawned using the NPC command, the seed level can be defined in the command and is otherwise set to 1.
A party provider produces either 'static' or 'dynamic' parties. A static party is one that is generated
when the NPC is initialized and will not change. A dynamic party is one that may be configured using the
seed level but can be different any time the NPC is challenged.
A dynamic party prevents the NPC from doing several actions, such as using healing machines, having
persistent health of their party that changes between battles, and keeping their Pokémon out of their
balls. This is because the NPC's party is not stored in the world.
#### simple
The "simple" party type is a way to define a party of Pokémon in a simple list format. Each string in the
list should be a set of Pokémon properties, as used in commands and spawn files.
This party provider type is considered 'static'. Any level that is not mentioned in the Pokémon properties
will be set to the seed level.
"party": {
"type": "simple",
"pokemon": [
"spiritomb moves=splash,firepunch,flamethrower,swift",
"porygonz speed_ev=252",
"togekiss nature=timid",
"lucario held_item=cobblemon:focus_sash",
"milotic ability=marvelscale ",
"garchomp level=100 hp_iv=31 attack_iv=31"
]
}
#### dynamic
To be implemented
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.api.npc.configuration
import com.cobblemon.mod.common.api.npc.NPCPartyProvider
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.writeString
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -25,50 +23,50 @@ class NPCBattleConfiguration {
buffer.writeBoolean(canChallenge)
buffer.writeBoolean(simultaneousBattles)
buffer.writeBoolean(healAfterwards)
buffer.writeNullable(party) { _, provider ->
buffer.writeString(provider.type)
provider.encode(buffer)
}
// buffer.writeNullable(party) { _, provider ->
// buffer.writeString(provider.type)
// provider.encode(buffer)
// }
}
fun decode(buffer: RegistryFriendlyByteBuf) {
canChallenge = buffer.readBoolean()
simultaneousBattles = buffer.readBoolean()
healAfterwards = buffer.readBoolean()
party = buffer.readNullable {
val type = buffer.readString()
val providerBuilder = NPCPartyProvider.types[type]
?: throw IllegalArgumentException("Failed to load NPC party provider of type: $type")
val decodedParty = providerBuilder(type)
decodedParty.decode(buffer)
decodedParty
}
// party = buffer.readNullable {
// val type = buffer.readString()
// val providerBuilder = NPCPartyProvider.types[type]
// ?: throw IllegalArgumentException("Failed to load NPC party provider of type: $type")
//
// val decodedParty = providerBuilder(type)
// decodedParty.decode(buffer)
// decodedParty
// }
}
fun saveToNBT(nbt: CompoundTag) {
nbt.putBoolean(DataKeys.NPC_CAN_CHALLENGE, canChallenge)
nbt.putBoolean(DataKeys.NPC_SIMULTANEOUS_BATTLES, simultaneousBattles)
nbt.putBoolean(DataKeys.NPC_HEAL_AFTERWARDS, healAfterwards)
val party = party
if (party != null) {
val partyNBT = CompoundTag()
partyNBT.putString(DataKeys.NPC_PARTY_TYPE, party.type)
party.saveToNBT(partyNBT)
nbt.put(DataKeys.NPC_PARTY, partyNBT)
}
// val party = party
// if (party != null) {
// val partyNBT = CompoundTag()
// partyNBT.putString(DataKeys.NPC_PARTY_TYPE, party.type)
// party.saveToNBT(partyNBT)
// nbt.put(DataKeys.NPC_PARTY, partyNBT)
// }
}
fun loadFromNBT(nbt: CompoundTag) {
canChallenge = nbt.getBoolean(DataKeys.NPC_CAN_CHALLENGE)
simultaneousBattles = nbt.getBoolean(DataKeys.NPC_SIMULTANEOUS_BATTLES)
healAfterwards = nbt.getBoolean(DataKeys.NPC_HEAL_AFTERWARDS)
val partyNBT = nbt.getCompound(DataKeys.NPC_PARTY)
if (!partyNBT.isEmpty) {
val type = partyNBT.getString(DataKeys.NPC_PARTY_TYPE)
val providerBuilder = NPCPartyProvider.types[type]
?: throw IllegalArgumentException("Failed to load NPC party provider of type: $type")
party = providerBuilder(type).also { it.loadFromNBT(partyNBT) }
}
// val partyNBT = nbt.getCompound(DataKeys.NPC_PARTY)
// if (!partyNBT.isEmpty) {
// val type = partyNBT.getString(DataKeys.NPC_PARTY_TYPE)
// val providerBuilder = NPCPartyProvider.types[type]
// ?: throw IllegalArgumentException("Failed to load NPC party provider of type: $type")
// party = providerBuilder(type).also { it.loadFromNBT(partyNBT) }
// }
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.npc.configuration
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.util.asTranslated
import net.minecraft.network.chat.Component
/**
* A predefined variable that will be declared and filled in on any NPC that extends from the class or preset
* that specifies this variable. This gives the client a cleaner way to represent a variable that should exist
* on the NPC.
*
* @author Hiroku
* @since August 14th, 2023
*/
class NPCConfigVariable(
val variableName: String = "variable",
val displayName: Component = "Variable".asTranslated(),
val description: Component = "A variable that can be used in the NPC's configuration.".asTranslated(),
val type: NPCVariableType = NPCVariableType.NUMBER,
val defaultValue: String = "0",
) {
enum class NPCVariableType {
NUMBER,
STRING,
BOOLEAN
}
fun apply(npc: NPCEntity, value: MoValue) {
npc.config.setDirectly(variableName, value)
}
fun applyDefault(npc: NPCEntity) {
val value = when (type) {
NPCVariableType.STRING -> StringValue(defaultValue)
NPCVariableType.BOOLEAN -> DoubleValue(defaultValue.toBoolean())
else -> DoubleValue(defaultValue.toDouble())
}
npc.config.set(variableName.split(".").iterator(), value)
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.npc.configuration.interaction
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.dialogue.ActiveDialogue
import com.cobblemon.mod.common.api.dialogue.DialogueManager
import com.cobblemon.mod.common.api.dialogue.Dialogues
@@ -31,10 +32,24 @@ class DialogueNPCInteractionConfiguration : NPCInteractConfiguration {
override fun interact(npc: NPCEntity, player: ServerPlayer): Boolean {
val dialogue = Dialogues.dialogues[this.dialogue] ?: return false
DialogueManager.startDialogue(ActiveDialogue(player, dialogue))
val currentDialogues = npc.brain.getMemory(CobblemonMemories.DIALOGUES).orElse(mutableListOf())
val activeDialogue = DialogueManager.startDialogue(player, npc, dialogue)
val newDialogues = currentDialogues + activeDialogue
npc.brain.setMemory(CobblemonMemories.DIALOGUES, newDialogues)
activeDialogue.completion.thenRun { onDialogueStopped(npc, activeDialogue) }
return true
}
fun onDialogueStopped(npc: NPCEntity, activeDialogue: ActiveDialogue) {
val currentDialogues = npc.brain.getMemory(CobblemonMemories.DIALOGUES).orElse(mutableListOf())
val newDialogues = currentDialogues - activeDialogue
if (newDialogues.isEmpty()) {
npc.brain.eraseMemory(CobblemonMemories.DIALOGUES)
} else {
npc.brain.setMemory(CobblemonMemories.DIALOGUES, newDialogues)
}
}
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(dialogue)
}
@@ -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.npc.partyproviders
import com.cobblemon.mod.common.api.npc.NPCPartyProvider
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.google.gson.JsonElement
import net.minecraft.resources.ResourceLocation
/**
* A provider of a party for battling the NPC. It generates a [StaticNPCParty] but using a more complex process
* that takes an input level and makes a randomized selection of Pokémon and movesets.
*
* @author Hiroku
* @since July 12th, 2024
*/
class DynamicPartyProvider : NPCPartyProvider {
companion object {
val TYPE = "dynamic"
}
class DynamicPool {
val id = ResourceLocation.parse("cobblemon:pool")
val pokemon: MutableList<DynamicPokemon> = mutableListOf()
}
class DynamicPokemon(
val pokemon: PokemonProperties,
val possibleLevels: IntRange,
val selectableTimes: IntRange,
val guaranteed: Boolean = false
)
override val type = "dynamic"
override fun loadFromJSON(json: JsonElement) {
TODO("Not yet implemented")
}
override fun provide(npc: NPCEntity, level: Int): NPCParty {
TODO("Not yet implemented")
}
}
@@ -0,0 +1,91 @@
/*
* 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.npc.partyproviders
import com.cobblemon.mod.common.api.storage.party.NPCPartyStore
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.net.IntSize
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.readSizedInt
import com.cobblemon.mod.common.util.writeSizedInt
import net.minecraft.core.RegistryAccess
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.server.level.ServerPlayer
/**
* Represents a party of Pokemon that an NPC can have. This isn't directly a party of Pokémon so that
* a dynamically generated party can exist where a party is generated at the time of a challenge.
*
* This interface is sealed. Implementations should be either [StaticNPCParty] or [DynamicNPCParty].
* If you want a custom type then you should implement [DynamicNPCParty] and register it in the
* [DynamicNPCParty.types] map.
*
* @author Hiroku
* @since July 12th, 2024
*/
sealed interface NPCParty {
fun getParty(player: ServerPlayer, npc: NPCEntity): PartyStore?
fun encode(buffer: RegistryFriendlyByteBuf)
fun decode(buffer: RegistryFriendlyByteBuf)
fun saveToNBT(nbt: CompoundTag, registryAccess: RegistryAccess)
fun loadFromNBT(nbt: CompoundTag, registryAccess: RegistryAccess)
}
/**
* A simple wrapping around a [NPCPartyStore]. This is a straightforward party that is always the same.
*
* @author Hiroku
* @since July 12th, 2024
*/
class StaticNPCParty(val party: NPCPartyStore) : NPCParty {
override fun getParty(player: ServerPlayer, npc: NPCEntity) = party
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeSizedInt(IntSize.U_BYTE, party.size())
for (pokemon in party) {
Pokemon.S2C_CODEC.encode(buffer, pokemon)
}
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
repeat(times = buffer.readSizedInt(IntSize.U_BYTE)) {
party.add(Pokemon.S2C_CODEC.decode(buffer))
}
}
override fun saveToNBT(nbt: CompoundTag, registryAccess: RegistryAccess) {
for ((index, pokemon) in party.withIndex()) {
nbt.put(DataKeys.NPC_PARTY_POKEMON + index, pokemon.saveToNBT(registryAccess))
}
}
override fun loadFromNBT(nbt: CompoundTag, registryAccess: RegistryAccess) {
var index = 0
while (nbt.contains(DataKeys.NPC_PARTY_POKEMON + index)) {
this.party.add(Pokemon().loadFromNBT(registryAccess, nbt.getCompound(DataKeys.NPC_PARTY_POKEMON + index)))
index++
}
}
}
/**
* A dynamic party that is generated at the time of a challenge.
*
* @author Hiroku
* @since July 12th, 2024
*/
interface DynamicNPCParty : NPCParty {
companion object {
val types = mutableMapOf<String, Class<out NPCParty>>()
init {}
}
}

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