diff --git a/README.md b/README.md index d04fe3d..cda7f87 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 版本 1.21.3 0.0.3.9.6 提前介绍c[最终版本对于0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】 +# 版本 1.21.3 0.0.3.9.9 ## 简介 现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧( @@ -54,15 +54,4 @@ * `LP.KeepLeashNotDropTime` - 此规则决定,当拴绳关系创建时一段时间里,即是距离已经达到了断裂距离,也保持其不断裂 [默认值: 240ticks ,可设置范围[80, 1200]ticks] -* `LP.DisableMoveCheck` - 此规则启用将会禁止服务器对玩家进行速度过快修正 [默认值: True] - -Please use a paste site for large blocks of code/logs, instead of dumping it in chat or taking a screenshot. - -Here's a list of some paste sites and their size limits: -https://gist.github.com/: [Free] [SignUp] 100MB -https://paste.gemwire.uk/: [Free] 10MB -https://paste.ee/: [Free] 1MB, [SignUp] 6MB -https://pastebin.com/: [Free] 512KB, [SignUp] [Paid] 10MB -https://hastebin.com/: [Free] 400KB -https://gist.github.com/: [Free] [SignUp] 100MB \ No newline at end of file diff --git a/build.gradle b/build.gradle index c82e379..3867bad 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'eclipse' id 'idea' id 'maven-publish' - id 'net.neoforged.gradle.userdev' version '7.0.165' + id 'net.neoforged.gradle.userdev' version '7.0.180' } tasks.named('wrapper', Wrapper).configure { @@ -28,7 +28,7 @@ base { // Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21. java.toolchain.languageVersion = JavaLanguageVersion.of(21) -minecraft.accessTransformers.file file('src/main/resources/META-INF/accesstransformer.cfg') +minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg') //minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager // Default run configurations. @@ -53,13 +53,12 @@ runs { client { // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. - systemProperty 'forge.enabledGameTestNamespaces', project.mod_id + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id } server { - systemProperty 'forge.enabledGameTestNamespaces', project.mod_id - programArgument '--nogui' + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id } // This run config launches GameTestServer and runs all registered gametests, then exits. @@ -72,9 +71,9 @@ runs { data { // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it // workingDirectory project.file('run-data') - systemProperty('gradle.task', 'runData') + systemProperty 'gradle.task', 'runData' // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() + arguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() } } @@ -155,7 +154,7 @@ publishing { } repositories { maven { - url "file://${project.projectDir}/repo" + url = "file://${project.projectDir}/repo" } } } @@ -163,9 +162,7 @@ publishing { tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation } -minecraft { - accessTransformers.file("src/main/resources/META-INF/accesstransformer.cfg") -} + // IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior. idea { module { diff --git a/gradle.properties b/gradle.properties index 46be9f5..d5c7a0c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ parchment_mappings_version=2024.07.28 #read more on this at https://github.com/neoforged/NeoGradle/blob/NG_7.0/README.md#apply-parchment-mappings # you can also find the latest versions at: https://parchmentmc.org/docs/getting-started -neogradle.subsystems.parchment.minecraftVersion=1.21 -neogradle.subsystems.parchment.mappingsVersion=2024.07.28 +neogradle.subsystems.parchment.minecraftVersion=1.21.3 +neogradle.subsystems.parchment.mappingsVersion=2024.12.07 # Environment Properties # You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge # The Minecraft version must agree with the Neo version to get a valid artifact @@ -22,15 +22,14 @@ minecraft_version=1.21.3 # The Minecraft version range can use any release version of Minecraft as bounds. # Snapshots, pre-releases, and release candidates are not guaranteed to sort properly # as they do not follow standard versioning conventions. -minecraft_version_range=[1.21.1,1.22) +minecraft_version_range=[1.21.3] enable_accesstransformers=true # The Neo version must agree with the Minecraft version to get a valid artifact -neo_version=21.3.0-beta +neo_version=21.3.58 # The Neo version range can use any version of Neo as bounds -neo_version_range=[21.1.0,) +neo_version_range=[21.3.58,) # The loader version range can only use the major version of FML as bounds -loader_version_range=[4,) -neoform_version=1.21.3-20241023.131943 +loader_version_range=[1,) ## Mod Properties @@ -42,7 +41,7 @@ mod_name=Leashed Player # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=1.21.3 0.0.3.9.6 +mod_version=1.21.3_0.0.3.9.9 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0..4c3891f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle b/settings.gradle index ada876e..90ae98f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,5 +7,5 @@ pluginManagement { } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0' } diff --git a/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c b/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c index 400d27a..21c8f4b 100644 --- a/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c +++ b/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c @@ -1,4 +1,4 @@ -// 1.21.3 2024-10-31T23:28:04.7117269 Item Models: leashedplayer +// 1.21.3 2025-01-27T17:55:02.7810616 Item Models: leashedplayer 766c487fbf0c59e9045eeaf81daf583eb679b0e1 assets/leashedplayer/models/item/amethyst_shears.json 5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json 845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json @@ -7,3 +7,4 @@ bb0d76077719c83c8a8bd4346a24ea1766175125 assets/leashedplayer/models/item/fabric.json 114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json c4748995a5fe190d20e3bd16f4b2244164ec0f83 assets/leashedplayer/models/item/spectral_leash_rope_arrow.json +c4ef06f3162fe85f152c5b4a25ecdb4c2c56f945 assets/leashedplayer/models/item/tipped_leash_rope_arrow.json diff --git a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 index 10886c0..2792b25 100644 --- a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 +++ b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 @@ -1,2 +1,3 @@ -// 1.21.3 2024-10-27T23:14:21.047502 Registries +// 1.21.3 2025-01-27T17:42:59.0511618 Registries +f2536789df7f06362718a59ba4a96890e2f9b8aa data/leashedplayer/jukebox_song/what_does_the_fox_say.json 84106976f4f71012fc5bd1784303a0d135623c77 data/leashedplayer/painting_variant/group_photo.json diff --git a/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 b/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 index b793cfd..b835577 100644 --- a/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 +++ b/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 @@ -1,2 +1,8 @@ -// 1.21.3 2024-10-31T20:50:40.9982605 Tags for minecraft:item mod id leashedplayer -36c1cccc1dfa448620c4e9cbc4a7d73986ff9e47 data/minecraft/tags/item/arrows.json +// 1.21.3 2025-01-27T21:03:10.3134854 Tags for minecraft:item mod id leashedplayer +84707301f1fe2490a899deb51302d413cfff5a89 data/c/tags/item/tools/shear.json +bde6ca31173d1f22d5f6fe355dc90c9faa35b239 data/minecraft/tags/item/amethyst_tool_materials.json +63e4ad58dc8397171f84264d53dfe4fb503c7b1e data/minecraft/tags/item/arrows.json +84707301f1fe2490a899deb51302d413cfff5a89 data/minecraft/tags/item/enchantable/durability.json +84707301f1fe2490a899deb51302d413cfff5a89 data/minecraft/tags/item/enchantable/mining.json +84707301f1fe2490a899deb51302d413cfff5a89 data/minecraft/tags/item/enchantable/vanishing.json +5cf114c796db4c2235df11ee7f656bba09d72a7a data/minecraft/tags/item/head_armor.json diff --git a/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff b/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff index da9be63..949861d 100644 --- a/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff +++ b/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff @@ -1,2 +1,2 @@ -// 1.21.3 2024-10-31T23:28:04.7137271 Languages: en_us for mod: leashedplayer -05969780f698fcb4d6b63800dcdb76e4b0cad090 assets/leashedplayer/lang/en_us.json +// 1.21.3 2025-01-27T21:03:10.3134854 Languages: en_us for mod: leashedplayer +2c7f061dfc276db13135adce15c68cfc145ccf37 assets/leashedplayer/lang/en_us.json diff --git a/src/generated/resources/.cache/735031f3addf80804addae5e3f53249900116f1e b/src/generated/resources/.cache/735031f3addf80804addae5e3f53249900116f1e new file mode 100644 index 0000000..6d02856 --- /dev/null +++ b/src/generated/resources/.cache/735031f3addf80804addae5e3f53249900116f1e @@ -0,0 +1,2 @@ +// 1.21.3 2025-01-27T17:42:59.0511618 Sound Definitions +81f1cc9f404c2670bf7cc679107177ffb0b48c77 assets/leashedplayer/sounds.json diff --git a/src/generated/resources/.cache/853329c6e706e45295e80307b8a95a5709025422 b/src/generated/resources/.cache/853329c6e706e45295e80307b8a95a5709025422 index 78110c5..400d6bd 100644 --- a/src/generated/resources/.cache/853329c6e706e45295e80307b8a95a5709025422 +++ b/src/generated/resources/.cache/853329c6e706e45295e80307b8a95a5709025422 @@ -1,2 +1,2 @@ -// 1.21.3 2024-10-27T23:14:21.0429914 Languages: lzh for mod: leashedplayer -bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f assets/leashedplayer/lang/lzh.json +// 1.21.3 2025-01-26T22:13:41.4090272 Languages: lzh for mod: leashedplayer +7536eb6d1c69695c06ebb9da5b57a391174b02cb assets/leashedplayer/lang/lzh.json diff --git a/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb b/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb index e902f5a..cc08223 100644 --- a/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb +++ b/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb @@ -1,2 +1,2 @@ -// 1.21.3 2024-10-31T23:28:04.710726 Languages: zh_cn for mod: leashedplayer -98ca8da6ea1688abc5d4beda986cfe0406255f1c assets/leashedplayer/lang/zh_cn.json +// 1.21.3 2025-01-27T21:03:10.3134854 Languages: zh_cn for mod: leashedplayer +f7bcf89907a8ca5f575e4b519d53cd0628bb1e6b assets/leashedplayer/lang/zh_cn.json diff --git a/src/generated/resources/.cache/da5d1419e6989284234546978c1a8a79f621dba7 b/src/generated/resources/.cache/da5d1419e6989284234546978c1a8a79f621dba7 index a71742d..7170d41 100644 --- a/src/generated/resources/.cache/da5d1419e6989284234546978c1a8a79f621dba7 +++ b/src/generated/resources/.cache/da5d1419e6989284234546978c1a8a79f621dba7 @@ -1,4 +1,4 @@ -// 1.21.3 2024-10-31T23:50:18.2165227 LeashedPlayer Recipes +// 1.21.3 2025-01-27T17:42:59.0511618 LeashedPlayer Recipes 13ebe9a580731296eb10c05d1844657d58e07cc1 data/leashedplayer/advancement/recipes/misc/amethyst_shears.json 1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json a26d63c2360b32df0b636a5dec96dd919139e022 data/leashedplayer/advancement/recipes/misc/spectral_leash_rope_arrow.json @@ -7,3 +7,5 @@ db45be6e2bbddc49e60a6c1b12e2ef44afad30d8 data/leashedplayer/recipe/leash_rope_ar db37bd69a700eaae69bff48c77ed49ca55fb9bf1 data/leashedplayer/recipe/spectral_leash_rope_arrow.json 935d8732ca65dd73e4668a197cda60480053fbcd data/minecraft/advancement/recipes/misc/leash_rope_arrow_shape.json 5811048f18527a45b36b8b927de4e5d7c12a75eb data/minecraft/recipe/leash_rope_arrow_shape.json +4dffdb7a2a537b409d1ec2630d9b74300649e1d8 data/minecraft/recipe/tipped_leash_rope_arrow_a.json +7810cb5e8c165f479fc6cd030bd1cf7bc508993b data/minecraft/recipe/tipped_leash_rope_arrow_b.json diff --git a/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 b/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 index ca1925e..97c81fb 100644 --- a/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 +++ b/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 @@ -1,4 +1,4 @@ -// 1.21.3 2024-10-31T23:28:04.7147278 Advancements +// 1.21.3 2025-01-26T22:13:41.4090272 Advancements 4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json @@ -7,4 +7,6 @@ bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_a a69a455855fb6dd8a8ac131a55099de5de45d7c4 data/leashedplayer/advancement/leash_arrow.json 133f844ffafd37b9ba57cafa96350f035cac57f9 data/leashedplayer/advancement/leash_start.json 2d8bce7fd078f9cc6b73b77f2fbab30e6cc197f4 data/leashedplayer/advancement/leash_terminator.json +4e567c22e18462ad367fe1817140d1ffa13a6294 data/leashedplayer/advancement/neo_fox.json 4b0bcf6b372f52e954edcef37a6b04435ec2b4e8 data/leashedplayer/advancement/no_leash.json +72f40eb5816d1e8c296bdf4df6b599c15ba7e7e9 data/leashedplayer/advancement/tipped_leash_arrow.json diff --git a/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d b/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d index 21f795a..1fedf8f 100644 --- a/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d +++ b/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d @@ -1,2 +1,2 @@ -// 1.21.3 2024-10-31T23:28:04.7097257 Languages: zh_tw for mod: leashedplayer -be94545852f60710429320d1e25f77d633940f36 assets/leashedplayer/lang/zh_tw.json +// 1.21.3 2025-01-27T21:03:10.3134854 Languages: zh_tw for mod: leashedplayer +c23825af72a73bc54b72ad3817acb5a03d299375 assets/leashedplayer/lang/zh_tw.json diff --git a/src/generated/resources/assets/leashedplayer/lang/en_us.json b/src/generated/resources/assets/leashedplayer/lang/en_us.json index 6a9d06f..ffd7fd8 100644 --- a/src/generated/resources/assets/leashedplayer/lang/en_us.json +++ b/src/generated/resources/assets/leashedplayer/lang/en_us.json @@ -15,29 +15,49 @@ "advancement.leashedplayer.leashed_friend.desc": "Be Bond by player with lead", "advancement.leashedplayer.leashed_self": "Stable Connection", "advancement.leashedplayer.leashed_self.desc": "“Restrain oneself with a rope", + "advancement.leashedplayer.neo_fox": "NEOFORGE!", + "advancement.leashedplayer.neo_fox.desc": "It seems can be equipped.", "advancement.leashedplayer.no_leash": "Don't tie me up", "advancement.leashedplayer.no_leash.desc": "You cannot be leashed by ANY", + "advancement.leashedplayer.tipped_leash_arrow": "God said there should be more arrows", + "advancement.leashedplayer.tipped_leash_arrow.desc": "A dazzling array of Leash Rope arrows", "creativetab.leashedplayer.leashedplayer_tab": "Leashed Player", "effect.leashedplayer.no_leash": "No Leash", + "entity.leashedplayer.kid_player": "Kid", "entity.leashedplayer.leash_rope_arrow": "Leash Rope Arrow", + "entity.leashedplayer.nestle_rope_arrow": "Nestle Rope Arrow", "entity.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence", - "gamerule.LP.DisablePlayerMoveCheck": "Disable Player Move Check", - "gamerule.LP.DisablePlayerMoveCheck.description": "Disable the player's movement Check And Correct it.", "gamerule.LP.KeepLeashNotDropTime": "Keep leash alive Time", "gamerule.LP.KeepLeashNotDropTime.description": "The time of Keep new leash which has far distance alive (Tick)", "gamerule.LP.TeleportWithLeashedPlayers": "Teleport leashed player with player holder", "gamerule.LP.TeleportWithLeashedPlayers.description": "Holder will teleport with their leashed players ", + "item.leash_rope_arrow.desc.1": "§7This arrow will carry the owner along with its flight:", + "item.leash_rope_arrow.desc.2": "§c1.§r If it hits a fence or an entity, it will leash the owner to it and drop as a normal arrow.", + "item.leash_rope_arrow.desc.3": "§c2.§r Crouching near the arrow allows for faster retrieval. If the arrow's owner is not the player, the owner will be leashed to the player who picks it up.", + "item.leash_rope_arrow.desc.4": "§c3.§r When fired from its launcher, the first entity hit will become the arrow's owner and will fly along with it.", + "item.leash_rope_arrow.desc.5": "§c4.§r Under the §c§l\"no_leash\"§r effect, the behavior of the arrow when fired will follow the launcher’s behavior.", "item.leash_rope_arrow.description": "Arrows with ropes attached?", "item.leashedplayer.amethyst_shears": "Amethyst Shears", "item.leashedplayer.fabric": "Fabric", "item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow", + "item.leashedplayer.neoforge": "NeoForge", "item.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow", "item.minecraft.lingering_potion.effect.no_leash": "Splash No Leash Potion", "item.minecraft.potion.effect.no_leash": "No Leash Potion", "item.minecraft.splash_potion.effect.no_leash": "Splash No Leash Potion", "item.minecraft.tipped_arrow.effect.no_leash": "Arrow of No Leash", + "item.spectral_leash_rope_arrow.desc": "§c2.§r Strike the entity to give it a §e§lGlowing§r effect.", + "item.tipped_leash_rope_arrow.desc": "§c2.§rStrike the entity to give it a Potion effect.", + "item.tipped_leash_rope_arrow.name": "Tipped Leash Rope Arrow Soaked By %1$s", + "item.variant.leash_rope_arrow.desc.1": "§7A variant of Leash Rope Arrow", + "item.variant.leash_rope_arrow.desc.2": "§c1.§r The function is the same as its original one。", + "jukebox_song.leashedplayer.what_does_the_fox_say": "What does the fox say?", + "key.leashedplayer.category": "Leashed Player", + "key.leashedplayer.leash_length.add": "Increase the Length of Leash Rope", + "key.leashedplayer.leash_length.not_support_to_not_player_entity": "Only work on Players", + "key.leashedplayer.leash_length.sub": "Decrease the Length of Leash Rope", "leashedplayer.command.leash.message.leash.data.clear": "%1$s's LeashData(LeashHolderEntity: %2$s) now is clear", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s has no LeashData can be clear", "leashedplayer.command.leash.message.leash.data.null": "%1$s has no LeashDataEntity", @@ -53,6 +73,16 @@ "leashedplayer.command.motion.message.adder.successful": "§bAdd Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r", "leashedplayer.command.motion.message.multiply.successful": "§bMultiply Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r", "leashedplayer.command.motion.message.setter.successful": "§bSet Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r", + "leashedplayer.lead_breaker.item.desc": "§7can break the link of leash", + "leashedplayer.lead_breaker.item.use_fai": "§cFailed to break §f%1$s§c 's Leashed Link to §f%2$s", + "leashedplayer.lead_breaker.item.use_suf": "§aSuccessfully break §f%1$s§a 's Leashed Link to §f%2$s ", + "leashedplayer.leash_rope.length.decrease": "§Decrease the §f%s §cLength of Leash Rope§7(§bLength§7:§e%d§7)", + "leashedplayer.leash_rope.length.decrease.self": "§cDecrease the Length of Leash Rope§7(§bLength§7:§e%d§7)", + "leashedplayer.leash_rope.length.failed": "§cFailed", + "leashedplayer.leash_rope.length.increase": "§aIncrease the §f%s §aLength of Leash Rope§7(§bLength§7:§e%d§7)", + "leashedplayer.leash_rope.length.increase.self": "§aIncrease the Length of Leash Rope§7(§bLength§7:§e%d§7)", + "leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§aPush §f§lShift§a to pick up quickly", "painting.leashedplayer.group_photo.author": "§9Leisure §4Time §eDock§r", - "painting.leashedplayer.group_photo.title": "§dGroup Photo §7[§6memorable§7]§r" + "painting.leashedplayer.group_photo.title": "§dGroup Photo §7[§6memorable§7]§r", + "sound.leashedplayer.subtitle.what_does_the_fox_say": "Great Chu will rise again! Chen She will be king!" } \ No newline at end of file diff --git a/src/generated/resources/assets/leashedplayer/lang/lzh.json b/src/generated/resources/assets/leashedplayer/lang/lzh.json index 9e26dfe..84c328a 100644 --- a/src/generated/resources/assets/leashedplayer/lang/lzh.json +++ b/src/generated/resources/assets/leashedplayer/lang/lzh.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "entity.leashedplayer.kid_player": "幼" +} \ No newline at end of file diff --git a/src/generated/resources/assets/leashedplayer/lang/zh_cn.json b/src/generated/resources/assets/leashedplayer/lang/zh_cn.json index 91a4f97..d4d056f 100644 --- a/src/generated/resources/assets/leashedplayer/lang/zh_cn.json +++ b/src/generated/resources/assets/leashedplayer/lang/zh_cn.json @@ -15,29 +15,49 @@ "advancement.leashedplayer.leashed_friend.desc": "被玩家用拴绳链接", "advancement.leashedplayer.leashed_self": "稳固联结", "advancement.leashedplayer.leashed_self.desc": "用拴绳拴住自己", + "advancement.leashedplayer.neo_fox": "NEOFORGE!", + "advancement.leashedplayer.neo_fox.desc": "似乎可以戴头上", "advancement.leashedplayer.no_leash": "勿拴我", "advancement.leashedplayer.no_leash.desc": "你不会被任何东西拴住", + "advancement.leashedplayer.tipped_leash_arrow": "神说要有更多箭矢", + "advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅满目啊", "creativetab.leashedplayer.leashedplayer_tab": "可拴玩家", "effect.leashedplayer.no_leash": "禁拴", + "entity.leashedplayer.kid_player": "小孩", "entity.leashedplayer.leash_rope_arrow": "拴绳箭", + "entity.leashedplayer.nestle_rope_arrow": "贴贴拴绳箭", "entity.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它", - "gamerule.LP.DisablePlayerMoveCheck": "禁止检查玩家移动", - "gamerule.LP.DisablePlayerMoveCheck.description": "禁止检查玩家移动并且纠正它", "gamerule.LP.KeepLeashNotDropTime": "保持拴绳不掉落的时间", "gamerule.LP.KeepLeashNotDropTime.description": "当距离过远时,保持新建拴绳不掉落的时间 (刻)", "gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者传送", "gamerule.LP.TeleportWithLeashedPlayers.description": "传送时将被拴玩家与持有者一起传送", + "item.leash_rope_arrow.desc.1": "§7该箭将会携带拥有者随其飞行", + "item.leash_rope_arrow.desc.2": "§c1.§r 若击中栅栏或生物时,将持有者拴在其上并已普通箭形式掉落;", + "item.leash_rope_arrow.desc.3": "§c2.§r 靠近该箭下蹲可以更快拾取该箭,如果该箭持有者不是自己,则持有者将被拾取者拴住;", + "item.leash_rope_arrow.desc.4": "§c3.§r 当前其发射器里发射,第一个射中的生物将成为此箭的持有者并随箭飞行;", + "item.leash_rope_arrow.desc.5": "§c4.§r 在§c§l禁拴§7(§c§lno_leash§7)§r效果下,射出的箭行为同发射器。", "item.leash_rope_arrow.description": "带有拴绳的箭矢?", "item.leashedplayer.amethyst_shears": "紫水晶剪刀", "item.leashedplayer.fabric": "Fabric", "item.leashedplayer.leash_rope_arrow": "拴绳箭", + "item.leashedplayer.neoforge": "NeoForge", "item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭", "item.minecraft.lingering_potion.effect.no_leash": "滞留型禁拴药水", "item.minecraft.potion.effect.no_leash": "禁拴药水", "item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水", "item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭", + "item.spectral_leash_rope_arrow.desc": "§c2.§r 击中实体给与其§e§l发光§7(§e§lGlowing§7)§r效果", + "item.tipped_leash_rope_arrow.desc": "§c2.§r 击中实体给与其药水效果", + "item.tipped_leash_rope_arrow.name": "用%1$s浸泡过的拴绳箭", + "item.variant.leash_rope_arrow.desc.1": "§7拴绳箭的一个变种", + "item.variant.leash_rope_arrow.desc.2": "§c1.§r 功能同其本体;", + "jukebox_song.leashedplayer.what_does_the_fox_say": "狐狸是怎么叫的?", + "key.leashedplayer.category": "可拴玩家", + "key.leashedplayer.leash_length.add": "增加拴绳长度", + "key.leashedplayer.leash_length.not_support_to_not_player_entity": "只在玩家身上有效", + "key.leashedplayer.leash_length.sub": "减小拴绳长度", "leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴绳数据(拴绳持有者实体:%2$s)现在已清除", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴绳数据可清除", "leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴绳数据实体", @@ -53,6 +73,16 @@ "leashedplayer.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", "leashedplayer.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", "leashedplayer.command.motion.message.setter.successful": "§b设置成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", + "leashedplayer.lead_breaker.item.desc": "§7可以破坏拴绳链接", + "leashedplayer.lead_breaker.item.use_fai": "§c无法剪断§f%2$s§c对§f%1$s§c拴绳链接", + "leashedplayer.lead_breaker.item.use_suf": "§a成功剪断§f%2$s§a对§f%1$s§a拴绳链接", + "leashedplayer.leash_rope.length.decrease": "§c减少§f%s的拴绳长度§c§7(§b长度§7:§e%d§7)", + "leashedplayer.leash_rope.length.decrease.self": "§c减少拴绳长度§c§7(§b长度§7:§e%d§7)", + "leashedplayer.leash_rope.length.failed": "§c失败", + "leashedplayer.leash_rope.length.increase": "§a增加§f%s的拴绳长度§a§7(§b长度§7:§e%d§7)", + "leashedplayer.leash_rope.length.increase.self": "§a增加拴绳长度§a§7(§b长度§7:§e%d§7)", + "leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§a按下§f§lShift键§a以加快拾取", "painting.leashedplayer.group_photo.author": "§9闲趣§4时§e坞§r", - "painting.leashedplayer.group_photo.title": "§d集体照 §7[§6纪念§7]§r" + "painting.leashedplayer.group_photo.title": "§d集体照 §7[§6纪念§7]§r", + "sound.leashedplayer.subtitle.what_does_the_fox_say": "大楚兴~ 陈胜王~~" } \ No newline at end of file diff --git a/src/generated/resources/assets/leashedplayer/lang/zh_tw.json b/src/generated/resources/assets/leashedplayer/lang/zh_tw.json index d9617f4..75d45b0 100644 --- a/src/generated/resources/assets/leashedplayer/lang/zh_tw.json +++ b/src/generated/resources/assets/leashedplayer/lang/zh_tw.json @@ -15,29 +15,49 @@ "advancement.leashedplayer.leashed_friend.desc": "被玩家用拴繩鏈接", "advancement.leashedplayer.leashed_self": "穩固聯結", "advancement.leashedplayer.leashed_self.desc": "用栓繩拴住自己", + "advancement.leashedplayer.neo_fox": "NEOFORGE!", + "advancement.leashedplayer.neo_fox.desc": "似乎可以戴著", "advancement.leashedplayer.no_leash": "請恁勿拴唔", "advancement.leashedplayer.no_leash.desc": "恁不會被任何拴住", + "advancement.leashedplayer.tipped_leash_arrow": "神說要有更多箭矢", + "advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅滿目啊", "creativetab.leashedplayer.leashedplayer_tab": "可拴玩家", "effect.leashedplayer.no_leash": "禁拴", + "entity.leashedplayer.kid_player": "小孩", "entity.leashedplayer.leash_rope_arrow": "拴繩箭", + "entity.leashedplayer.nestle_rope_arrow": "貼貼拴繩箭", "entity.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它", - "gamerule.LP.DisablePlayerMoveCheck": "禁止檢查玩家移動", - "gamerule.LP.DisablePlayerMoveCheck.description": "禁止檢查玩家移動並糾正他它", "gamerule.LP.KeepLeashNotDropTime": "保持其不掉落的時間", "gamerule.LP.KeepLeashNotDropTime.description": "儅距離過遠時,保持其不掉落的時間(刻)", "gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者傳送", "gamerule.LP.TeleportWithLeashedPlayers.description": "將被拴玩家將隨持有者一起傳送", + "item.leash_rope_arrow.desc.1": "§7該箭將會攜帶擁有者隨其飛行:", + "item.leash_rope_arrow.desc.2": "§c1.§r 若擊中柵欄或生物時,將持有者拴在其上並以普通箭的形式掉落;", + "item.leash_rope_arrow.desc.3": "§c2.§r 靠近該箭下蹲可以更快拾取該箭,如果該箭的持有者不是自己,則持有者將被拾取者拴住;", + "item.leash_rope_arrow.desc.4": "§c3.§r 當箭從發射器發射時,第一個射中的生物將成為此箭的持有者並隨箭飛行;", + "item.leash_rope_arrow.desc.5": "§c4.§r 在§c§l禁拴§7(§c§lno_leash§7)§r效果下,射出的箭行為將與發射器的行為相同。", "item.leash_rope_arrow.description": "帶有拴繩的箭矢?", "item.leashedplayer.amethyst_shears": "紫水晶剪刀", "item.leashedplayer.fabric": "Fabric", "item.leashedplayer.leash_rope_arrow": "拴繩箭", + "item.leashedplayer.neoforge": "NeoForge", "item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭", "item.minecraft.lingering_potion.effect.no_leash": "滯留型禁拴藥水", "item.minecraft.potion.effect.no_leash": "禁拴藥水", "item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水", "item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭", + "item.spectral_leash_rope_arrow.desc": "擊中實體給予其§e§l發光§7(§e§lGlowing§7)§r效果", + "item.tipped_leash_rope_arrow.desc": "擊中實體給予其药水效果", + "item.tipped_leash_rope_arrow.name": "蘸有%1$s的拴繩箭", + "item.variant.leash_rope_arrow.desc.1": "§7拴繩箭矢的一個變種", + "item.variant.leash_rope_arrow.desc.2": "§c1.§r 功能與本體一致;", + "jukebox_song.leashedplayer.what_does_the_fox_say": "狐狸是怎麽叫的?", + "key.leashedplayer.category": "可拴玩家", + "key.leashedplayer.leash_length.add": "增加拴繩長度", + "key.leashedplayer.leash_length.not_support_to_not_player_entity": "僅對玩家有效", + "key.leashedplayer.leash_length.sub": "減小拴繩長度", "leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴繩數據(拴繩持有者實體:%2$s)現在已清除", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴繩數據實體可被清除", "leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴繩數據實體", @@ -53,6 +73,16 @@ "leashedplayer.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", "leashedplayer.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", "leashedplayer.command.motion.message.setter.successful": "§b設置成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", + "leashedplayer.lead_breaker.item.desc": "§7可以破壞拴繩鏈接", + "leashedplayer.lead_breaker.item.use_fai": "§c未能剪斷§f%2$s§c對§f%1$s§c拴繩鏈接", + "leashedplayer.lead_breaker.item.use_suf": "§a成功剪斷§f%2$s§a對§f%1$s§a拴繩鏈接", + "leashedplayer.leash_rope.length.decrease": "§c減少§f%s§c的拴繩長度§7(§長度§7:§e%d§7)", + "leashedplayer.leash_rope.length.decrease.self": "§c減少拴繩長度§7(§長度§7:§e%d§7)", + "leashedplayer.leash_rope.length.failed": "§c失敗", + "leashedplayer.leash_rope.length.increase": "§a增加§f%s§a的拴繩長度§7(§長度§7:§e%d§7)", + "leashedplayer.leash_rope.length.increase.self": "§a增加拴繩長度§7(§長度§7:§e%d§7)", + "leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§a按下§f§lShift鍵§a以加速拾取", "painting.leashedplayer.group_photo.author": "§9閑趣§4時§e塢§r", - "painting.leashedplayer.group_photo.title": "§d集體照 §7[§6紀念§7]§r" + "painting.leashedplayer.group_photo.title": "§d集體照 §7[§6紀念§7]§r", + "sound.leashedplayer.subtitle.what_does_the_fox_say": "大楚興~ 陳勝王~~" } \ No newline at end of file diff --git a/src/generated/resources/assets/leashedplayer/models/item/tipped_leash_rope_arrow.json b/src/generated/resources/assets/leashedplayer/models/item/tipped_leash_rope_arrow.json new file mode 100644 index 0000000..6d4aa6b --- /dev/null +++ b/src/generated/resources/assets/leashedplayer/models/item/tipped_leash_rope_arrow.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "minecraft:item/tipped_arrow_head", + "layer1": "leashedplayer:item/tipped_leash_rope_arrow_base" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/leashedplayer/sounds.json b/src/generated/resources/assets/leashedplayer/sounds.json new file mode 100644 index 0000000..7f87818 --- /dev/null +++ b/src/generated/resources/assets/leashedplayer/sounds.json @@ -0,0 +1,8 @@ +{ + "music/what_does_the_fox_say": { + "sounds": [ + "leashedplayer:music/what_does_the_fox_say" + ], + "subtitle": "sound.leashedplayer.subtitle.what_does_the_fox_say" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/shear.json b/src/generated/resources/data/c/tags/item/tools/shear.json new file mode 100644 index 0000000..069fe5f --- /dev/null +++ b/src/generated/resources/data/c/tags/item/tools/shear.json @@ -0,0 +1,5 @@ +{ + "values": [ + "leashedplayer:amethyst_shears" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/leashedplayer/advancement/neo_fox.json b/src/generated/resources/data/leashedplayer/advancement/neo_fox.json new file mode 100644 index 0000000..c6a2bc5 --- /dev/null +++ b/src/generated/resources/data/leashedplayer/advancement/neo_fox.json @@ -0,0 +1,36 @@ +{ + "parent": "leashedplayer:leash_start", + "criteria": { + "has_neo_fox": { + "conditions": { + "items": [ + { + "items": "leashedplayer:neoforge" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "display": { + "announce_to_chat": false, + "description": { + "translate": "advancement.leashedplayer.neo_fox.desc" + }, + "frame": "goal", + "hidden": true, + "icon": { + "count": 1, + "id": "leashedplayer:neoforge" + }, + "title": { + "translate": "advancement.leashedplayer.neo_fox" + } + }, + "requirements": [ + [ + "has_neo_fox" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/leashedplayer/advancement/tipped_leash_arrow.json b/src/generated/resources/data/leashedplayer/advancement/tipped_leash_arrow.json new file mode 100644 index 0000000..9353cfd --- /dev/null +++ b/src/generated/resources/data/leashedplayer/advancement/tipped_leash_arrow.json @@ -0,0 +1,35 @@ +{ + "parent": "leashedplayer:leash_arrow", + "criteria": { + "has_tipped_leash_arrow": { + "conditions": { + "items": [ + { + "items": "leashedplayer:tipped_leash_rope_arrow" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "display": { + "description": { + "translate": "advancement.leashedplayer.tipped_leash_arrow.desc" + }, + "frame": "goal", + "hidden": true, + "icon": { + "count": 1, + "id": "leashedplayer:tipped_leash_rope_arrow" + }, + "title": { + "translate": "advancement.leashedplayer.tipped_leash_arrow" + } + }, + "requirements": [ + [ + "has_tipped_leash_arrow" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/leashedplayer/jukebox_song/what_does_the_fox_say.json b/src/generated/resources/data/leashedplayer/jukebox_song/what_does_the_fox_say.json new file mode 100644 index 0000000..ca1236d --- /dev/null +++ b/src/generated/resources/data/leashedplayer/jukebox_song/what_does_the_fox_say.json @@ -0,0 +1,8 @@ +{ + "comparator_output": 15, + "description": { + "translate": "jukebox_song.leashedplayer.what_does_the_fox_say" + }, + "length_in_seconds": 121.0, + "sound_event": "leashedplayer:what_does_the_fox_say" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/tipped_leash_rope_arrow_a.json b/src/generated/resources/data/minecraft/recipe/tipped_leash_rope_arrow_a.json new file mode 100644 index 0000000..a7d4eec --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/tipped_leash_rope_arrow_a.json @@ -0,0 +1,4 @@ +{ + "type": "leashedplayer:tipped_leash_rope_arrow_a_recipe", + "category": "misc" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/tipped_leash_rope_arrow_b.json b/src/generated/resources/data/minecraft/recipe/tipped_leash_rope_arrow_b.json new file mode 100644 index 0000000..3a34fd9 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/tipped_leash_rope_arrow_b.json @@ -0,0 +1,4 @@ +{ + "type": "leashedplayer:tipped_leash_rope_arrow_b_recipe", + "category": "misc" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/amethyst_tool_materials.json b/src/generated/resources/data/minecraft/tags/item/amethyst_tool_materials.json new file mode 100644 index 0000000..742ef89 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/item/amethyst_tool_materials.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:amethyst_shard" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/arrows.json b/src/generated/resources/data/minecraft/tags/item/arrows.json index 6f87cfe..1ce5212 100644 --- a/src/generated/resources/data/minecraft/tags/item/arrows.json +++ b/src/generated/resources/data/minecraft/tags/item/arrows.json @@ -1,6 +1,7 @@ { "values": [ "leashedplayer:leash_rope_arrow", - "leashedplayer:spectral_leash_rope_arrow" + "leashedplayer:spectral_leash_rope_arrow", + "leashedplayer:tipped_leash_rope_arrow" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json b/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json new file mode 100644 index 0000000..069fe5f --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/item/enchantable/durability.json @@ -0,0 +1,5 @@ +{ + "values": [ + "leashedplayer:amethyst_shears" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/enchantable/mining.json b/src/generated/resources/data/minecraft/tags/item/enchantable/mining.json new file mode 100644 index 0000000..069fe5f --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/item/enchantable/mining.json @@ -0,0 +1,5 @@ +{ + "values": [ + "leashedplayer:amethyst_shears" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/enchantable/vanishing.json b/src/generated/resources/data/minecraft/tags/item/enchantable/vanishing.json new file mode 100644 index 0000000..069fe5f --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/item/enchantable/vanishing.json @@ -0,0 +1,5 @@ +{ + "values": [ + "leashedplayer:amethyst_shears" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/head_armor.json b/src/generated/resources/data/minecraft/tags/item/head_armor.json new file mode 100644 index 0000000..456ea0c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/item/head_armor.json @@ -0,0 +1,6 @@ +{ + "values": [ + "leashedplayer:neoforge", + "minecraft:lead" + ] +} \ No newline at end of file diff --git a/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java b/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java index 7ed6b90..6e71aa4 100644 --- a/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java @@ -1,26 +1,43 @@ package com.r3944realms.leashedplayer; import com.r3944realms.leashedplayer.client.renders.LeashRendererUtil; +import com.r3944realms.leashedplayer.client.renders.PlayerLeashState; +import com.r3944realms.leashedplayer.client.renders.entities.ChestItemLayerRenderer; import com.r3944realms.leashedplayer.client.renders.entities.LeashRopeArrowRenderer; import com.r3944realms.leashedplayer.client.renders.entities.SpectralLeashRopeArrowRenderer; +import com.r3944realms.leashedplayer.content.ModKeyMapping; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; -import com.r3944realms.leashedplayer.content.items.ModCreativeTab; import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow; import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension; +import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; +import com.r3944realms.leashedplayer.network.server.Code; +import com.r3944realms.leashedplayer.network.server.DecreaseLeashRopeLength; +import com.r3944realms.leashedplayer.network.server.IncreaseLeashRopeLength; +import com.r3944realms.leashedplayer.utils.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.state.PlayerRenderState; import net.minecraft.client.renderer.item.ItemProperties; +import net.minecraft.client.resources.PlayerSkin; import net.minecraft.core.component.DataComponents; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionContents; import net.minecraft.world.item.component.ChargedProjectiles; +import net.minecraft.world.phys.HitResult; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.neoforge.client.event.EntityRenderersEvent; -import net.neoforged.neoforge.client.event.RenderPlayerEvent; +import net.neoforged.neoforge.client.event.*; +import net.neoforged.neoforge.network.PacketDistributor; + +import java.util.List; public class ClientEventHandler { @@ -29,13 +46,72 @@ public class ClientEventHandler { @SubscribeEvent public static void onPlayerRendererEventPre(RenderPlayerEvent.Post event) { PlayerRenderState renderState = event.getRenderState(); - if(((IPlayerRenderStateExtension)renderState).getPlayerLeashState() != null) { - LeashRendererUtil.renderLeash(event.getPoseStack(), event.getMultiBufferSource(), renderState); + PlayerLeashState playerLeashState = ((IPlayerRenderStateExtension) renderState).getPlayerLeashState(); + if(playerLeashState != null) { + if (playerLeashState.vanilaLeashState != null) + LeashRendererUtil.renderLeash(event.getPoseStack(), event.getMultiBufferSource(), playerLeashState.vanilaLeashState); + else + LeashRendererUtil.renderLeash(event.getPoseStack(), event.getMultiBufferSource(), renderState); + } + } + @SubscribeEvent + public static void onKetBoardInput(InputEvent.Key event) { + Minecraft minecraft = Minecraft.getInstance(); + LocalPlayer player = minecraft.player; + assert player != null; + if (ModKeyMapping.KEY_ADD_LEASH_LENGTH.isDown()) { + PlayerLeashable playerLeashable = (PlayerLeashable) player; + if (playerLeashable.getLeashDataFromEntityData() == null) { + assert minecraft.level != null; + List refLookAtEntityHitResult = Util.getRefLookAtEntityHitResult(player, minecraft.level, 32, entity -> entity instanceof LivingEntity); + Entity theNearestEntityFromHitResultList = Util.getTheNearestEntityFromHitResultList(player, refLookAtEntityHitResult); + if(theNearestEntityFromHitResultList != null) { + if (theNearestEntityFromHitResultList instanceof Player refPlayer) { + PacketDistributor.sendToServer(new IncreaseLeashRopeLength(Code.OTHER_ST, refPlayer.getStringUUID())); + } + } + } + if (playerLeashable.getLeashDataFromEntityData() != null) { + PacketDistributor.sendToServer(new IncreaseLeashRopeLength(Code.SELF, player.getStringUUID())); + } + } + if (ModKeyMapping.KEY_SUB_LEASH_LENGTH.isDown()) { + PlayerLeashable playerLeashable = (PlayerLeashable) player; + if (playerLeashable.getLeashDataFromEntityData() == null) { + assert minecraft.level != null; + List refLookAtEntityHitResult = Util.getRefLookAtEntityHitResult(player, minecraft.level, 32, entity -> entity instanceof LivingEntity); + Entity theNearestEntityFromHitResultList = Util.getTheNearestEntityFromHitResultList(player, refLookAtEntityHitResult); + if(theNearestEntityFromHitResultList != null) { + if (theNearestEntityFromHitResultList instanceof Player refPlayer) { + PacketDistributor.sendToServer(new DecreaseLeashRopeLength(Code.OTHER_ST, refPlayer.getStringUUID())); + } + } + } + if (playerLeashable.getLeashDataFromEntityData() != null) { + PacketDistributor.sendToServer(new DecreaseLeashRopeLength(Code.SELF, player.getStringUUID())); + } } } } + @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID) public static class Mod { + @SubscribeEvent + public static void registerKeyMapping(RegisterKeyMappingsEvent event) { + event.register(ModKeyMapping.KEY_ADD_LEASH_LENGTH); + event.register(ModKeyMapping.KEY_SUB_LEASH_LENGTH); + } + @SubscribeEvent + public static void onAddLayers (EntityRenderersEvent.AddLayers event){ + PlayerRenderer renderer = event.getSkin(PlayerSkin.Model.WIDE); + if (renderer instanceof PlayerRenderer playerRenderer) { + playerRenderer.addLayer(new ChestItemLayerRenderer<>(playerRenderer, event.getContext().getEntityRenderDispatcher().getItemInHandRenderer())); + } + PlayerRenderer slimRenderer = event.getSkin(PlayerSkin.Model.SLIM); + if (slimRenderer instanceof PlayerRenderer slimPlayerRenderer) { + slimPlayerRenderer.addLayer(new ChestItemLayerRenderer<>(slimPlayerRenderer, event.getContext().getEntityRenderDispatcher().getItemInHandRenderer())); + } + } @SubscribeEvent public static void onRegisterItemProperties(FMLClientSetupEvent event) { event.enqueueWork(() -> { @@ -49,13 +125,21 @@ public class ClientEventHandler { (pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F )); }); - } @SubscribeEvent public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) { event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new); event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new); } + @SubscribeEvent + public static void onRegisterItemColorHandlers (RegisterColorHandlersEvent.Item event){ + event.register( + (color, i) -> i > 0 + ? -1 + : color.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).getColor() | 0xFF000000, + ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get() + ); + } } diff --git a/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java b/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java index c4a6283..bd55ea3 100644 --- a/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java @@ -4,24 +4,29 @@ import com.mojang.brigadier.CommandDispatcher; import com.r3944realms.leashedplayer.content.commands.LeashCommand; import com.r3944realms.leashedplayer.content.commands.MotionCommand; import com.r3944realms.leashedplayer.content.commands.TickCommand; -import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; import com.r3944realms.leashedplayer.content.effects.ModPotionRegister; -import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior; -import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; +import com.r3944realms.leashedplayer.utils.Util; +import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.tags.ItemTags; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.Leashable; -import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.animal.Fox; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.alchemy.Potions; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.DispenserBlock; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.event.AnvilUpdateEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent; import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent; import net.neoforged.neoforge.event.tick.EntityTickEvent; @@ -45,36 +50,56 @@ public class CommonEventHandler { @SubscribeEvent public static void OnLivingTickEvent(EntityTickEvent.Post event) { Entity entity = event.getEntity(); - if (entity.level().isClientSide()) { + Level level = entity.level(); + if (level.isClientSide()) { return; } - if (entity instanceof LivingEntity living) { - MobEffectInstance effect = living.getEffect(ModEffectRegister.NO_LEASH_EFFECT); - if(effect != null && effect.getDuration() != 0){ - if (entity instanceof PlayerLeashable player) { - if (player.getLeashHolder() != null) { - if (player.getLeashHolder() instanceof LeashRopeArrow arrow) - arrow.setOwner(null); - player.dropLeash(true, !(player.getLeashHolder() instanceof LeashRopeArrow)); - } - } else if (entity instanceof Leashable leashable) { - if (leashable.getLeashHolder() != null) { - if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow) - arrow.setOwner(null); - leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow)); - } - } + if (entity instanceof Fox fox) { + if (fox.getMainHandItem().is(ItemTags.ANVIL)) { + fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); + Util.throwItemTowardsLook(fox, ModItemRegister.NEOFORGE.get(), 0.3f, 0.1f); + fox.playSound(SoundEvents.FOX_EAT); + } else if (fox.getMainHandItem().is(ModItemRegister.NEOFORGE.get())) { + // 繞圈參數 + float rotationSpeed = 10.0f; // 每 tick 旋轉的角度 + // 計算新的旋轉角度 + fox.yBodyRot += rotationSpeed; // 身體旋轉 + fox.yHeadRot += rotationSpeed; // 頭部旋轉 + fox.yRotO += rotationSpeed; // 當前旋轉角度 + fox.yHeadRotO += rotationSpeed; // 頭部的當前旋轉角度 + + // 確保旋轉角度不超出 360 度,重置為 0 以便持續旋轉 + if (fox.yBodyRot >= 360) fox.yBodyRot -= 360; + if (fox.yHeadRot >= 360) fox.yHeadRot -= 360; + } } } + @SubscribeEvent + public static void OnAnvilUpdated(AnvilUpdateEvent event) { + String name = event.getName(); + ItemStack left = event.getLeft(); + if (left.is(Items.ANVIL) && name != null && name.equals("NeoForge")) { + event.setCost(1); + event.setOutput(ModItemRegister.NEOFORGE.get().getDefaultInstance()); + } else if (left.is(ModItemRegister.NEOFORGE.get().asItem()) && name != null && name.equals("Forge")) { + ItemStack instance = Items.ANVIL.getDefaultInstance(); + instance.set(DataComponents.CUSTOM_NAME, Component.literal("Forge").withStyle(ChatFormatting.BOLD).withStyle(ChatFormatting.AQUA)); + event.setOutput(instance); + event.setCost(1); + } + } } @EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD) public static class Mod extends CommonEventHandler { @SubscribeEvent public static void onCommonSetup(FMLCommonSetupEvent event) { - DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get()); - DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); - DispenserBlock.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior()); + event.enqueueWork(() -> { + DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get()); + DispenserBlock.registerProjectileBehavior(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get()); + DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); + DispenserBlock.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior()); + }); } } diff --git a/src/main/java/com/r3944realms/leashedplayer/LeashedPlayer.java b/src/main/java/com/r3944realms/leashedplayer/LeashedPlayer.java index a6b6d8e..e07a65f 100644 --- a/src/main/java/com/r3944realms/leashedplayer/LeashedPlayer.java +++ b/src/main/java/com/r3944realms/leashedplayer/LeashedPlayer.java @@ -7,7 +7,9 @@ import com.r3944realms.leashedplayer.content.effects.ModPotionRegister; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.items.ModCreativeTab; import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import com.r3944realms.leashedplayer.content.items.repcipe.ModRecipeRegister; import com.r3944realms.leashedplayer.content.paintings.ModPaintingsRegister; +import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister; import com.r3944realms.leashedplayer.utils.Util; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.ModLoadingContext; @@ -20,8 +22,12 @@ public class LeashedPlayer { public static final String MOD_ID = "leashedplayer"; private static Double M1;//拴繩掉落距離倍基數 private static Double M2;//繩箭拴繩掉落距離倍基數 + private static Integer M3; //拴绳最小长度 + private static Integer M4; //拴绳最大长度 public LeashedPlayer(IEventBus event) { ModItemRegister.register(event); + ModRecipeRegister.register(event); + ModSoundRegister.register(event); ModPaintingsRegister.register(event); ModEffectRegister.register(event); ModPotionRegister.register(event); @@ -48,6 +54,17 @@ public class LeashedPlayer { } return M2; } - + public static Integer M3() { + if(M3 == null) { + M3 = LeashPlayerCommonConfig.MinimumLeashLengthCanBeSet.get(); + } + return M3; + } + public static Integer M4() { + if(M4 == null) { + M4 = LeashPlayerCommonConfig.MaximumLeashLengthCanBeSet.get(); + } + return M4; + } } diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRendererUtil.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRendererUtil.java index a2452fe..9859a80 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRendererUtil.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRendererUtil.java @@ -7,9 +7,7 @@ import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension; -import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; -import com.r3944realms.leashedplayer.utils.Logger; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -17,7 +15,7 @@ import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.player.PlayerRenderer; +import net.minecraft.client.renderer.entity.state.EntityRenderState; import net.minecraft.client.renderer.entity.state.PlayerRenderState; import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; @@ -30,12 +28,71 @@ import net.minecraft.world.entity.vehicle.NewMinecartBehavior; import net.minecraft.world.level.LightLayer; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; import org.joml.Matrix4f; import java.util.List; import java.util.UUID; +@OnlyIn(Dist.CLIENT) public class LeashRendererUtil { + public static void renderLeash(PoseStack poseStack, MultiBufferSource buffer, EntityRenderState.LeashState leashState) { + float f = 0.025F; + + float f1 = (float)(leashState.end.x - leashState.start.x); + float f2 = (float)(leashState.end.y - leashState.start.y + 0.2); + float f3 = (float)(leashState.end.z - leashState.start.z); + float f4 = Mth.invSqrt(f1 * f1 + f3 * f3) * 0.025F / 2.0F; + float f5 = f3 * f4; + float f6 = f1 * f4; + poseStack.pushPose(); + poseStack.translate(leashState.offset.add(0, -0.2, -0.2)); + VertexConsumer vertexconsumer = buffer.getBuffer(RenderType.leash()); + Matrix4f matrix4f = poseStack.last().pose(); + + for (int i = 0; i <= 24; i++) { + addVertexPair( + vertexconsumer, + matrix4f, + f1, + f2, + f3, + leashState.startBlockLight, + leashState.endBlockLight, + leashState.startSkyLight, + leashState.endSkyLight, + 0.025F, + 0.025F, + f5, + f6, + i, + false + ); + } + + for (int j = 24; j >= 0; j--) { + addVertexPair( + vertexconsumer, + matrix4f, + f1, + f2, + f3, + leashState.startBlockLight, + leashState.endBlockLight, + leashState.startSkyLight, + leashState.endSkyLight, + 0.025F, + 0.0F, + f5, + f6, + j, + true + ); + } + + poseStack.popPose(); + } /** *

1. 角度与弧度转换

* {@snippet lang=java : @@ -292,8 +349,6 @@ public class LeashRendererUtil { if (entity instanceof AbstractClientPlayer abstractClientPlayer) { if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue; Minecraft mc = Minecraft.getInstance(); - PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(abstractClientPlayer); - IPlayerRendererExtension playerRendererExtension = (IPlayerRendererExtension) playerRenderer; if (mc.options.getCameraType().isFirstPerson()) { Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData(); if(leashDataFromEntityData == null) continue; @@ -365,4 +420,108 @@ public class LeashRendererUtil { } return ret; } + + public static void createPlayerLeashState(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, float partialTick) { + Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData(); + Leashable.LeashData leashData = ((PlayerLeashable) abstractClientPlayer).getLeashData(); + PlayerRenderState playerRs = (PlayerRenderState)playerRenderState; + if (leashDataFromEntityData != null) { + Entity leashHolder = leashDataFromEntityData.leashHolder; + Either delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo; + PlayerLeashState playerLeashState = new PlayerLeashState(); + if (delayedLeashInfo != null) { + createPlayerLeashState_(abstractClientPlayer, playerRenderState, leashDataFromEntityData, delayedLeashInfo, playerLeashState, partialTick); + } else if(leashHolder != null) { + createPlayerLeashState__(abstractClientPlayer, playerRenderState, leashHolder, playerLeashState, partialTick); + } else { + playerRenderState.setPlayerLeashState(null); + } + } else if(leashData != null) { + playerRs.leashState = null; + Entity leashHolder = ((PlayerLeashable) abstractClientPlayer).getLeashHolder(); + PlayerLeashState playerLeashState = playerRenderState.getPlayerLeashState(); + if (leashHolder != null & playerLeashState != null) { + float f = leashHolder.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0); + Vec3 vec3 = abstractClientPlayer.getLeashOffset(partialTick).yRot(-f); + BlockPos blockpos1 = BlockPos.containing(abstractClientPlayer.getEyePosition(partialTick)); + BlockPos blockpos = BlockPos.containing(leashHolder.getEyePosition(partialTick)); + playerLeashState.vanilaLeashState = new EntityRenderState.LeashState(); + + EntityRenderState.LeashState entityrenderstate$leashstate = playerLeashState.vanilaLeashState; + entityrenderstate$leashstate.offset = vec3; + entityrenderstate$leashstate.start = abstractClientPlayer.getPosition(partialTick).add(vec3); + entityrenderstate$leashstate.end = leashHolder.getRopeHoldPosition(partialTick); + entityrenderstate$leashstate.startBlockLight = getBlockLightLevel(abstractClientPlayer, blockpos1); + entityrenderstate$leashstate.endBlockLight = getBlockLightLevel(leashHolder, blockpos); + entityrenderstate$leashstate.startSkyLight = abstractClientPlayer.level().getBrightness(LightLayer.SKY, blockpos1); + entityrenderstate$leashstate.endSkyLight = abstractClientPlayer.level().getBrightness(LightLayer.SKY, blockpos); + } else { + playerRenderState.setPlayerLeashState(null); + } + } else { + playerRenderState.setPlayerLeashState(null); + } + } + private static int getBlockLightLevel(T entity, BlockPos pos) { + return entity.isOnFire() ? 15 : entity.level().getBrightness(LightLayer.BLOCK, pos); + } + + + private static void createPlayerLeashState__(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, Entity leashHolder, PlayerLeashState playerLeashState, float partialTick) { + playerLeashState.pos = leashHolder.position().add(0.0, leashHolder.getEyeHeight() * 0.6, -0.2); + playerLeashState.o = abstractClientPlayer.getPosition(partialTick); + playerLeashState.yRotO = abstractClientPlayer.yRotO; + playerLeashState.yRot = abstractClientPlayer.getYRot(); + playerLeashState.eyeHeight = abstractClientPlayer.getEyeHeight(); + playerRenderState.setPlayerLeashState(playerLeashState); + } + + private static void createPlayerLeashState_(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, Leashable.LeashData leashDataFromEntityData, Either delayedLeashInfo, PlayerLeashState playerLeashState, float partialTick) { + Minecraft mc = Minecraft.getInstance(); + ClientLevel level = mc.level; + if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) { + assert level != null; + playerLeashState.pos = delayedLeashInfo.right().get().getCenter(); + } else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) { + assert level != null; + Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get()); + if (playerByUUID != null) { + playerLeashState.pos = playerByUUID.position().add(0.0, playerByUUID.getEyeHeight() * 0.6, 0); + } else { + double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1(); + double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * breakDistanceTime; + List entities = level.getEntities( + null, + new AABB( + abstractClientPlayer.getX() - MaxLeashLength * LeashedPlayer.M2(), + abstractClientPlayer.getY() - MaxLeashLength * LeashedPlayer.M2(), + abstractClientPlayer.getZ() - MaxLeashLength * LeashedPlayer.M2(), + abstractClientPlayer.getX() + MaxLeashLength * LeashedPlayer.M2(), + abstractClientPlayer.getY() + MaxLeashLength * LeashedPlayer.M2(), + abstractClientPlayer.getZ() + MaxLeashLength * LeashedPlayer.M2() + ) + ); + Entity holder = null; + for (Entity entity_ : entities) { + if (entity_.getUUID().equals(delayedLeashInfo.left().get())) { + holder = entity_; + break; + } + } + if (holder != null) { + playerLeashState.pos = holder.position().add(0.0, holder.getEyeHeight() * 0.6, 0);//TODO: 待擴展Vec3 + } else { + playerLeashState.pos = abstractClientPlayer.position(); + } + } + } + + playerLeashState.o = abstractClientPlayer.getPosition(partialTick); + playerLeashState.yRotO = abstractClientPlayer.yRotO; + playerLeashState.yRot = abstractClientPlayer.getYRot(); + playerLeashState.eyeHeight = abstractClientPlayer.getEyeHeight(); + playerRenderState.setPlayerLeashState(playerLeashState); + } + + } diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerLeashState.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerLeashState.java index bde2c45..b8d6b74 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerLeashState.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerLeashState.java @@ -1,8 +1,14 @@ package com.r3944realms.leashedplayer.client.renders; +import net.minecraft.client.renderer.entity.state.EntityRenderState; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import javax.annotation.Nullable; + +@OnlyIn(Dist.CLIENT) public class PlayerLeashState { public Vec3 o, pos, offset; public float yRotO, yRot; @@ -11,6 +17,8 @@ public class PlayerLeashState { public int endBlockLight; public int startSkyLight; public int endSkyLight; + @Nullable + public EntityRenderState.LeashState vanilaLeashState; public float getPreciseBodyRotation(float pPartialTick) { return Mth.lerp(pPartialTick, this.yRotO, this.yRot); @@ -28,5 +36,6 @@ public class PlayerLeashState { this.endBlockLight = 0; this.startSkyLight = 15; this.endSkyLight = 15; + this.vanilaLeashState = null; } } diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerSlotItemLayerState.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerSlotItemLayerState.java new file mode 100644 index 0000000..6ca368b --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/PlayerSlotItemLayerState.java @@ -0,0 +1,13 @@ +package com.r3944realms.leashedplayer.client.renders; + +import net.minecraft.world.entity.LivingEntity; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class PlayerSlotItemLayerState { + public LivingEntity entity; + public PlayerSlotItemLayerState(LivingEntity entity) { + this.entity = entity; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/ChestItemLayerRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/ChestItemLayerRenderer.java new file mode 100644 index 0000000..3bde929 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/ChestItemLayerRenderer.java @@ -0,0 +1,120 @@ +package com.r3944realms.leashedplayer.client.renders.entities; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.PlayerModel; +import net.minecraft.client.renderer.ItemInHandRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.client.renderer.entity.state.PlayerRenderState; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class ChestItemLayerRenderer> extends RenderLayer { + + private final ItemInHandRenderer heldItemRenderer; + + public ChestItemLayerRenderer(RenderLayerParent context, ItemInHandRenderer heldItemRenderer) { + super(context); + this.heldItemRenderer = heldItemRenderer; + } + + + @Override + public void render(@NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, @NotNull S renderState, float yRot, float xRot) { + ItemDisplayContext mode = ItemDisplayContext.FIXED; + IPlayerRenderStateExtension rs = (IPlayerRenderStateExtension) renderState; + LivingEntity entity = rs.getPlayerSlotItemLayerState().entity; + ItemStack chestStack = entity.getItemBySlot(EquipmentSlot.CHEST); + if (!chestStack.isEmpty()) { + if (!(entity.getEquipmentSlotForItem(chestStack).equals(EquipmentSlot.CHEST))) { + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).body.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.translate(0, -0.24f, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, chestStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.scale(1.01f, 1.01f, 1.01f); + poseStack.translate(0, -1 / 4f, 0); + this.heldItemRenderer.renderItem(entity, chestStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).rightArm.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.scale(2/3f, 2/3f, 2/3f); + poseStack.translate(-1/12f, 0, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, chestStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.scale(0.99f, 0.99f, 0.99f); + poseStack.translate(0, -1/2f, 0); + this.heldItemRenderer.renderItem(entity, chestStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).leftArm.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.scale(2/3f, 2/3f, 2/3f); + poseStack.translate(1/12f, 0, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, chestStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.scale(0.99f, 0.99f, 0.99f); + poseStack.translate(0, -1/2f, 0); + this.heldItemRenderer.renderItem(entity, chestStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + } + } + ItemStack legsStack = entity.getItemBySlot(EquipmentSlot.LEGS); + if (!legsStack.isEmpty()) { + if (!(entity.getEquipmentSlotForItem(legsStack).equals(EquipmentSlot.LEGS))) { + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).rightLeg.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.scale(2/3f, 2/3f, 2/3f); + poseStack.translate(0, -1/6f, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, legsStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.scale(1.01f, 1.01f, 1.01f); + poseStack.translate(0, -1/3f, 0); + this.heldItemRenderer.renderItem(entity, legsStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).leftLeg.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.scale(2/3f, 2/3f, 2/3f); + poseStack.translate(0, -1/6f, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, legsStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.scale(1.01f, 1.01f, 1.01f); + poseStack.translate(0, -1/3f, 0); + this.heldItemRenderer.renderItem(entity, legsStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + } + } + ItemStack feetStack = entity.getItemBySlot(EquipmentSlot.FEET); + if (!feetStack.isEmpty()) { + if (!(entity.getEquipmentSlotForItem(feetStack).equals(EquipmentSlot.FEET))) { + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).rightLeg.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.scale(0.75f, 0.75f, 0.75f); + poseStack.translate(0, -0.8f, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, feetStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + poseStack.pushPose(); + ((PlayerModel) this.getParentModel()).leftLeg.translateAndRotate(poseStack); + poseStack.mulPose(Axis.XP.rotationDegrees(180)); + poseStack.scale(0.75f, 0.75f, 0.75f); + poseStack.translate(0, -0.8f, 0); + poseStack.mulPose(Axis.YP.rotationDegrees(180)); + this.heldItemRenderer.renderItem(entity, feetStack, mode, false, poseStack, bufferSource, packedLight); + poseStack.popPose(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java b/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java index 0d9c0d6..5c93369 100644 --- a/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java +++ b/src/main/java/com/r3944realms/leashedplayer/config/LeashPlayerCommonConfig.java @@ -27,7 +27,7 @@ public class LeashPlayerCommonConfig { BUILDER.push("Misc"); BUILDER.comment("Leash Player Length"); BUILDER.push("LeashLength"); - TheLeashBreakLengthTimesBase = BUILDER.comment("When it exceeds how many times, the leash will drop"," [ Default:2.0f, Invalid Range:[2.0f, 5.0f] ]").defineInRange("BreakLengthTimeBase", 3.0f, 3.0f ,6.0f); + TheLeashBreakLengthTimesBase = BUILDER.comment("When it exceeds how many times, the leash will drop"," [ Default:3.0f, Valid Range:[3.0f, 6.0f] ]").defineInRange("BreakLengthTimeBase", 3.0f, 3.0f ,6.0f); MinimumLeashLengthCanBeSet = BUILDER.comment("The minimum integer's length of Leash", " [ Default:5, Invalid Range:[2,10] ]").defineInRange("MinLeashLength", 5, 2, 10); MaximumLeashLengthCanBeSet = BUILDER.comment("The maximum integer's length of Leash", " [ Default:1024, Invalid Range:[32, 1024] ]").defineInRange("MaxLeashLength", 1024, 32, 1024); BUILDER.pop().pop(); diff --git a/src/main/java/com/r3944realms/leashedplayer/content/ModKeyMapping.java b/src/main/java/com/r3944realms/leashedplayer/content/ModKeyMapping.java new file mode 100644 index 0000000..868dd5f --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/ModKeyMapping.java @@ -0,0 +1,37 @@ +package com.r3944realms.leashedplayer.content; + +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; +import net.neoforged.neoforge.client.settings.KeyConflictContext; +import net.neoforged.neoforge.client.settings.KeyModifier; +import org.lwjgl.glfw.GLFW; + +public class ModKeyMapping { + static String KEY_ROOT_ = "key.leashedplayer."; + public static String CATEGORY = "key.leashedplayer.category"; + public static String + ADD_LEASH_LENGTH_KEY = KEY_ROOT_ + "leash_length.add", + SUB_LEASH_LENGTH_KEY = KEY_ROOT_ + "leash_length.sub", + NOT_SUPPORT_TO_NOT_PLAYER_ENTITY = KEY_ROOT_ + "leash_length.not_support_to_not_player_entity"; + + + public static final KeyMapping KEY_ADD_LEASH_LENGTH = + new KeyMapping( + ADD_LEASH_LENGTH_KEY, + KeyConflictContext.IN_GAME, + KeyModifier.CONTROL, + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_UP, + CATEGORY + ); + public static final KeyMapping KEY_SUB_LEASH_LENGTH = + new KeyMapping( + SUB_LEASH_LENGTH_KEY, + KeyConflictContext.IN_GAME, + KeyModifier.CONTROL, + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_DOWN, + CATEGORY + ); +} + diff --git a/src/main/java/com/r3944realms/leashedplayer/content/commands/MotionCommand.java b/src/main/java/com/r3944realms/leashedplayer/content/commands/MotionCommand.java index f4678b0..1d11a65 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/commands/MotionCommand.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/commands/MotionCommand.java @@ -41,6 +41,7 @@ public class MotionCommand { ); if(entity instanceof ServerPlayer player) { PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.ADD, motionVec.x, motionVec.y, motionVec.z)); + player.addDeltaMovement(new Vec3(motionVec.x, motionVec.y, motionVec.z)); } else { entity.addDeltaMovement(motionVec); } @@ -59,6 +60,7 @@ public class MotionCommand { ); if(entity instanceof ServerPlayer player) { PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.SET, motionVec.x, motionVec.y, motionVec.z)); + player.setDeltaMovement(new Vec3(motionVec.x, motionVec.y, motionVec.z)); } else { entity.setDeltaMovement(motionVec); } @@ -77,6 +79,7 @@ public class MotionCommand { ); if(entity instanceof ServerPlayer player) { PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.MULTIPLY, motionFactorVec.x, motionFactorVec.y, motionFactorVec.z)); + player.setDeltaMovement(entity.getDeltaMovement().multiply(motionFactorVec)); } else { entity.setDeltaMovement(entity.getDeltaMovement().multiply(motionFactorVec)); } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java index c72ce79..0188783 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/effects/ModEffectRegister.java @@ -1,6 +1,7 @@ package com.r3944realms.leashedplayer.content.effects; import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.content.effects.type.NoLeashEffect; import net.minecraft.core.registries.Registries; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; @@ -14,7 +15,7 @@ public class ModEffectRegister { public static DeferredRegister MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID); public static DeferredHolder NO_LEASH_EFFECT = register( "no_leash", - () -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764) + () -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764) ); public static DeferredHolder register(String name, Supplier effect) { return MOB_EFFECT.register(name, effect); diff --git a/src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java b/src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java new file mode 100644 index 0000000..fd1eed2 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/effects/type/NoLeashEffect.java @@ -0,0 +1,37 @@ +package com.r3944realms.leashedplayer.content.effects.type; + +import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; +import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.Leashable; +import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.NotNull; + +public class NoLeashEffect extends MobEffect { + public NoLeashEffect(MobEffectCategory pCategory, int pColor) { + super(pCategory, pColor); + } + + @Override + public boolean applyEffectTick(@NotNull ServerLevel level, @NotNull LivingEntity pLivingEntity, int pAmplifier) { + MobEffectInstance effect = pLivingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT); + if(effect != null && effect.getDuration() != 0) { + if (pLivingEntity instanceof Leashable leashable) { + if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow) { + arrow.dropLeashHandler(); + leashable.dropLeash(true, false); + } + leashable.dropLeash(true, true); + } + } + return true; + } + + @Override + public boolean shouldApplyEffectTickThisTick(int pDuration, int pAmplifier) { + return true; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java index 31ac64f..94b99ca 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java @@ -7,8 +7,16 @@ import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTi import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.particles.ColorParticleOption; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.network.chat.Component; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; import net.minecraft.tags.BlockTags; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; @@ -21,6 +29,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionContents; import net.minecraft.world.level.Level; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; @@ -28,79 +37,118 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class LeashRopeArrow extends AbstractArrow { - private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get(); - protected LeashRopeArrow(EntityType entityType,Level pLevel) { - super(entityType, pLevel); - } + public static final String PUSH_SHIFT_TO_PICKUP_QUICKLY = "leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip"; + private static final int EXPOSED_POTION_DECAY_TIME = 600; + private static final int NO_EFFECT_COLOR = -1; + private static final EntityDataAccessor ID_EFFECT_COLOR = SynchedEntityData.defineId(LeashRopeArrow.class, EntityDataSerializers.INT); + private static final byte EVENT_POTION_PUFF = 0; + private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get(); + protected LeashRopeArrow(EntityType entityType,Level pLevel) { + super(entityType, pLevel); - public LeashRopeArrow(EntityType entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { - super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon); - if(serverPlayer != null && !level().isClientSide) { - Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level()); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); - } - ((PlayerLeashable)serverPlayer).setLeashedTo(this, true); + } + private PotionContents getPotionContents() { + ItemStack pickupItemStackOrigin = this.getPickupItemStackOrigin(); + pickupItemStackOrigin.setCount(1); + return pickupItemStackOrigin.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); + } + + public void addEffect(MobEffectInstance pEffectInstance) { + this.setPotionContents(this.getPotionContents().withEffectAdded(pEffectInstance)); + } + + private void setPotionContents(PotionContents pPotionContents) { + this.getPickupItemStackOrigin().set(DataComponents.POTION_CONTENTS, pPotionContents); + this.updateColor(); + } + + private void updateColor() { + PotionContents potioncontents = this.getPotionContents(); + this.entityData.set(ID_EFFECT_COLOR, potioncontents.equals(PotionContents.EMPTY) ? -1 : potioncontents.getColor()); + } + + @Override + protected void defineSynchedData(SynchedEntityData.@NotNull Builder pBuilder) { + super.defineSynchedData(pBuilder); + pBuilder.define(ID_EFFECT_COLOR, -1); + } + + + @Override + protected void setPickupItemStack(@NotNull ItemStack pPickupItemStack) { + super.setPickupItemStack(pPickupItemStack); + this.updateColor(); + } + + public LeashRopeArrow(EntityType entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { + super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon); + this.updateColor(); + if(serverPlayer != null && !level().isClientSide) { + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level()); + if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + leashRopeArrow.setOwner(null);//将先前的箭矢置空 } + ((PlayerLeashable)serverPlayer).setLeashedTo(this, true); } + } - public LeashRopeArrow(EntityType entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { - super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); - if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { - Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level()); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); - } - lPlayer.setLeashedTo(this, true); + public LeashRopeArrow(EntityType entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { + super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); + this.updateColor(); + if (pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level()); + if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + leashRopeArrow.setOwner(null); } + lPlayer.setLeashedTo(this, true); } + } - @Override - protected @NotNull ItemStack getDefaultPickupItem() { - return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance(); - } + @Override + protected @NotNull ItemStack getDefaultPickupItem() { + return new ItemStack(ModItemRegister.LEASH_ROPE_ARROW.get()); + } - @Override - public void setOwner(@Nullable Entity pEntity) { -// super.setOwner(pEntity); - boolean isNull = pEntity == null; - this.ownerUUID = isNull ? null : pEntity.getUUID(); - this.cachedOwner = isNull ? null : pEntity; - this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED; - } + @Override + public void setOwner(@Nullable Entity pEntity) { + boolean isNull = pEntity == null; + this.ownerUUID = isNull ? null : pEntity.getUUID(); + this.cachedOwner = isNull ? null : pEntity; + this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED; + } - @Override - protected boolean tryPickup(@NotNull Player pPlayer) { - //时间1.40 禁止 - //时间2.240 + @Override + protected boolean tryPickup(@NotNull Player pPlayer) { + //时间1.40 禁止 + //时间2.240 // 如果(非仅创造拾取) - // 如果 (按Shift ) - // 如果(拥有者) -> 拾取到完整箭,取消绑定(super给父类处理) - // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定(当前拥有者的Holder是否为本箭,“是”才重绑定) - // 否则: 禁止 - // 否则: - // 如果 (按Shift ) - // 如果(拥有者) -> 且拾取到完整箭,取消绑定 - // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定 - // 否则: 禁止 - //时间3 + // 如果 (按Shift ) + // 如果(拥有者) -> 拾取到完整箭,取消绑定(super给父类处理) + // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定(当前拥有者的Holder是否为本箭,“是”才重绑定) + // 否则: 禁止 + // 否则: + // 如果 (按Shift ) + // 如果(拥有者) -> 且拾取到完整箭,取消绑定 + // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定 + // 否则: 禁止 + //时间3 // 如果(拥有者) -> 拾取到完整箭,取消绑定 // 否则:不能获取完整的箭,重绑定 - if(life <= 40 ) { - return false; - } - else { - PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; - if(this.getOwner() == null) {//未有Owner始终可检 - return true; - } + if(life <= 40 ) { + return false; + } else { + PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; + if(this.getOwner() != null) {//未有Owner始终可检 if(life <= 240) { if(pPlayer.isShiftKeyDown()) { Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner(); if(this.ownedBy(pPlayer)) { this.pickup = Pickup.ALLOWED; - if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false); + if(this.equals(leashDataEntity)) { + pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); + playerLeashable.dropLeash(true, false); + } } else { if(life >= 120) { Entity owner = getOwner(); @@ -108,30 +156,39 @@ public class LeashRopeArrow extends AbstractArrow { // if(this.equals(leashDataEntity)) { if(owner instanceof PlayerLeashable player) { player.setLeashedTo(pPlayer, true); + pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); } else if(owner instanceof Leashable leashable) { leashable.setLeashedTo(pPlayer, true); + pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); } ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack()); level().addFreshEntity(itemEntity); discard(); // } - } else return true; + } } else return false; } - } else return false; + } else { + ((ServerPlayer)pPlayer).sendSystemMessage(Component.translatable(PUSH_SHIFT_TO_PICKUP_QUICKLY), true); + return false; + } - } - else { + } else { Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner(); if(this.ownedBy(pPlayer)) { this.pickup = Pickup.ALLOWED; - if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false); + if(this.equals(leashDataEntity)) { + pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); + playerLeashable.dropLeash(true, false); + } } else { Entity owner = getOwner(); if(owner instanceof PlayerLeashable player) { player.setLeashedTo(pPlayer, true); + pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); } else if(owner instanceof Leashable leashable) { leashable.setLeashedTo(pPlayer, true); + pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); } ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack()); level().addFreshEntity(itemEntity); @@ -139,29 +196,91 @@ public class LeashRopeArrow extends AbstractArrow { } } - } + } else if (this.pickup != Pickup.CREATIVE_ONLY) this.pickup = Pickup.ALLOWED; + else return pPlayer.hasInfiniteMaterials() && this.pickup == Pickup.CREATIVE_ONLY; - return super.tryPickup(pPlayer); - } - protected void hitOnEntityHandler(Entity pEntity) { - //NOOP - } - protected ItemStack getOrginalItemStack() { - return Items.ARROW.getDefaultInstance(); - } - protected ItemStack getSelfItemStack() { - return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance(); } - @Override - protected void tickDespawn() { - this.life++; - if (this.life >= maxLifeTime) { - ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); - this.level().addFreshEntity(leash_rope_arrow); - this.discard(); + return super.tryPickup(pPlayer); + } + protected void hitOnEntityHandler(Entity pEntity) { + if(pEntity instanceof LivingEntity pLiving) { + super.doPostHurtEffects(pLiving); + Entity entity = this.getEffectSource(); + PotionContents potioncontents = this.getPotionContents(); + if (potioncontents.potion().isPresent()) { + for (MobEffectInstance mobeffectinstance : potioncontents.potion().get().value().getEffects()) { + pLiving.addEffect( + new MobEffectInstance( + mobeffectinstance.getEffect(), + Math.max(mobeffectinstance.mapDuration(p_268168_ -> p_268168_ / 8), 1), + mobeffectinstance.getAmplifier(), + mobeffectinstance.isAmbient(), + mobeffectinstance.isVisible() + ), + entity + ); + } + } + for (MobEffectInstance effectInstance : potioncontents.customEffects()) { + pLiving.addEffect(effectInstance, entity); } } + } + protected ItemStack getOrginalItemStack() { + return Items.ARROW.getDefaultInstance(); + } + protected ItemStack getSelfItemStack() { + return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance(); + } + + @Override + protected void tickDespawn() { + this.life++; + if (this.life >= maxLifeTime) { + ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack()); + this.level().addFreshEntity(leash_rope_arrow); + this.discard(); + } + } + @Override + public void tick() { + super.tick(); + if (this.level().isClientSide) { + if (this.isInGround()) { + if (this.inGroundTime % 5 == 0) { + this.makeParticle(1); + } + } else { + this.makeParticle(2); + } + } else if (this.isInGround() && this.inGroundTime != 0 && !this.getPotionContents().equals(PotionContents.EMPTY) && this.inGroundTime >= 600) { + this.level().broadcastEntityEvent(this, (byte)0); + this.setPickupItemStack(new ItemStack(getSelfItemStack().getItem())); + } + } + + private void makeParticle(int pParticleAmount) { + int i = this.getColor(); + if (i != -1 && pParticleAmount > 0) { + for (int j = 0; j < pParticleAmount; j++) { + this.level() + .addParticle( + ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, i), + this.getRandomX(0.5), + this.getRandomY(), + this.getRandomZ(0.5), + 0.0, + 0.0, + 0.0 + ); + } + } + } + + public int getColor() { + return this.entityData.get(ID_EFFECT_COLOR); + } @Override @@ -173,13 +292,14 @@ public class LeashRopeArrow extends AbstractArrow { if(leashDataEntity != null) { pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); + leashRopeArrow.dropLeashHandler(); } } Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos()); ILivingEntityExtension pLL = (ILivingEntityExtension) pL; pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); pL.setLeashedTo(leashKnotFence, true); + leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); this.level().addFreshEntity(arrow); discard(); @@ -188,6 +308,7 @@ public class LeashRopeArrow extends AbstractArrow { if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) { Entity leashDataEntity = this.getOwner(); if(leashDataEntity != null) { + leashDataEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1); L.dropLeash(true, false); if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.setOwner(null); @@ -195,6 +316,7 @@ public class LeashRopeArrow extends AbstractArrow { } Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos()); L.setLeashedTo(leashKnotFence, true); + leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); this.level().addFreshEntity(arrow); discard(); @@ -207,13 +329,13 @@ public class LeashRopeArrow extends AbstractArrow { @Override protected void onHitEntity(@NotNull EntityHitResult pResult) { - if(!level().isClientSide()){ + if (!level().isClientSide()) { Entity entity = pResult.getEntity(); hitOnEntityHandler(entity); - if(this.getOwner() instanceof LivingEntity livingEntity ) { + if (this.getOwner() instanceof LivingEntity livingEntity ) { MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT); - if(effect != null && effect.getDuration() != 0) { - this.setOwner(null); + if (effect != null && effect.getDuration() != 0) { + this.dropLeashHandler(); } } if(entity instanceof LivingEntity livingEntity) { @@ -224,44 +346,47 @@ public class LeashRopeArrow extends AbstractArrow { if(leashDataEntity != null) { pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); + leashRopeArrow.dropLeashHandler(); } } ILivingEntityExtension pLL = (ILivingEntityExtension) pL; pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); pL.setLeashedTo(this, true); - return; } else if (this.getOwner() instanceof PlayerLeashable pL) { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); if(leashDataEntity != null) { pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); + if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + leashRopeArrow.dropLeashHandler(); } } ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); ILivingEntityExtension pLL = (ILivingEntityExtension) pL; pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); pL.setLeashedTo(pResult.getEntity(), true); this.level().addFreshEntity(arrow); discard(); } else { - if(entity instanceof Leashable leashable) { + if (entity instanceof Leashable leashable) { if (getOwner() == null) { Entity leashDataEntity = leashable.getLeashHolder(); if (leashDataEntity != null) { leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); + if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + leashRopeArrow.dropLeashHandler(); } } + livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); leashable.setLeashedTo(this, true); this.setOwner(entity); return; } } - if(entity instanceof LivingEntity living) { - if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) { + if (entity instanceof LivingEntity living) { + if (this.getOwner() != null && this.getOwner()instanceof Leashable leashable) { + livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); leashable.setLeashedTo(living, true); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); this.level().addFreshEntity(arrow); @@ -276,26 +401,57 @@ public class LeashRopeArrow extends AbstractArrow { else if (entity instanceof LeashFenceKnotEntity leashKnotFence) { if (getOwner() instanceof PlayerLeashable pL) { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); - if(leashDataEntity != null) { + if (leashDataEntity != null) { pL.dropLeash(true, true); - if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { - leashRopeArrow.setOwner(null); + if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { + leashRopeArrow.dropLeashHandler(); } } ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); ILivingEntityExtension pLL = (ILivingEntityExtension) pL; pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); pL.setLeashedTo(leashKnotFence, true); this.level().addFreshEntity(arrow); discard(); - return; } } else { ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance()); this.level().addFreshEntity(lead); } } - if(!level().isClientSide()) super.onHitEntity(pResult); } + /** + * Handles an entity event received from a {@link net.minecraft.network.protocol.game.ClientboundEntityEventPacket}. + */ + @Override + public void handleEntityEvent(byte pId) { + if (pId == 0) { + int i = this.getColor(); + if (i != -1) { + float f = (float)(i >> 16 & 0xFF) / 255.0F; + float f1 = (float)(i >> 8 & 0xFF) / 255.0F; + float f2 = (float)(i & 0xFF) / 255.0F; + for (int j = 0; j < 20; j++) { + this.level() + .addParticle( + ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, f, f1, f2), + this.getRandomX(0.5), + this.getRandomY(), + this.getRandomZ(0.5), + 0.0, + 0.0, + 0.0 + ); + } + } + } else { + super.handleEntityEvent(pId); + } + } + public void dropLeashHandler() { + this.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1); + this.setOwner(null); + } } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java index 5a64912..ed7ac13 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java @@ -30,12 +30,7 @@ public class ModEntityRegister { .updateInterval(20) .build(ResourceKey.create(Registries.ENTITY_TYPE, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "spectral_leash_rope_arrow"))) ); -// public static final DeferredHolder, EntityType> CHAIN_TIE = ENTITY_TYPE.register( -// "chain_tie", -// () -> EntityType.Builder.of(ChainTieEntity::new, MobCategory.MISC) -// .sized(0.8F, 0.9F) -// .build("chain_tie") -// ); + public static String getEntityNameKey(String entityName) { return "entity." + LeashedPlayer.MOD_ID + "." + entityName; } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/gamerules/Server/DisablePlayerMoveCheck.java b/src/main/java/com/r3944realms/leashedplayer/content/gamerules/Server/DisablePlayerMoveCheck.java deleted file mode 100644 index ec9c546..0000000 --- a/src/main/java/com/r3944realms/leashedplayer/content/gamerules/Server/DisablePlayerMoveCheck.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.r3944realms.leashedplayer.content.gamerules.Server; - -import com.r3944realms.leashedplayer.LeashedPlayer; -import com.r3944realms.leashedplayer.content.gamerules.Gamerules; -import com.r3944realms.leashedplayer.utils.Util; -import net.minecraft.world.level.GameRules; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; - -import static com.r3944realms.leashedplayer.content.gamerules.Gamerules.GAMERULE_REGISTRY; - -@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD) -public class DisablePlayerMoveCheck { - public static final boolean DEFAULT_VALUE = false; - public static final String ID = Util.getGameruleName(DisablePlayerMoveCheck.class); - public static final String DESCRIPTION_KEY = Gamerules.getDescriptionKey(DisablePlayerMoveCheck.class); - public static final String NAME_KEY = Gamerules.getNameKey(DisablePlayerMoveCheck.class); - public static final GameRules.Category CATEGORY = GameRules.Category.PLAYER; - - @SubscribeEvent - public static void onCommonSetup(final FMLCommonSetupEvent event) { - GAMERULE_REGISTRY.registerGamerule(ID, CATEGORY, DEFAULT_VALUE); - } -} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java b/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java index 109c43c..10e628d 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java @@ -4,7 +4,9 @@ import com.r3944realms.leashedplayer.LeashedPlayer; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; +import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.item.alchemy.PotionContents; @@ -45,8 +47,28 @@ public class ModCreativeTab { .filter(p_337926_ -> Objects.requireNonNull(p_337926_.getKey()).location().getNamespace().equals(LeashedPlayer.MOD_ID)) .map(p_330083_ -> PotionContents.createItemStack(Items.LINGERING_POTION, p_330083_)) .forEach(pOutput::accept); + pOutput.accept(ModItemRegister.NEOFORGE.get()); + pParameters.holders() + .lookup(Registries.POTION) + .ifPresent( + pPotions -> generatePotionEffectTypes( + pOutput, + pPotions, + ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), + CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS, + pParameters.enabledFeatures() + ) + ); } })).build()); + private static void generatePotionEffectTypes( + CreativeModeTab.Output pOutput, HolderLookup pPotions, Item pItem, CreativeModeTab.TabVisibility pTabVisibility, FeatureFlagSet pRequiredFeatures + ) { + pPotions.listElements() + .filter(potionReference -> potionReference.value().isEnabled(pRequiredFeatures)) + .map(potionReference -> PotionContents.createItemStack(pItem, potionReference)) + .forEach(itemStack -> pOutput.accept(itemStack, pTabVisibility)); + } public static String getCreativeMod(@NotNull String tabs) { return LEASHED_PLAYER_TAB_STRING + "." + tabs; } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java index 46b6d4a..c529295 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java @@ -1,19 +1,18 @@ package com.r3944realms.leashedplayer.content.items; import com.r3944realms.leashedplayer.LeashedPlayer; -import com.r3944realms.leashedplayer.content.items.type.LeadBreakerItem; -import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem; -import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem; -import com.r3944realms.leashedplayer.content.items.type.TestItem; +import com.r3944realms.leashedplayer.content.items.type.*; +import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; +import net.minecraft.world.item.JukeboxSong; import net.minecraft.world.item.Rarity; import net.minecraft.world.item.ShearsItem; +import net.minecraft.world.item.alchemy.PotionContents; import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; import java.util.ArrayList; @@ -23,25 +22,39 @@ import java.util.function.Supplier; public class ModItemRegister { public static final DeferredRegister ITEMS = DeferredRegister.create(BuiltInRegistries.ITEM, LeashedPlayer.MOD_ID); - public static final List> ITEM_SUPPLIER = new ArrayList<>(); - public static final Supplier LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow", - () -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16)) + public static final List> ITEM_SUPPLIER = new ArrayList<>(); + public static final DeferredHolder LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow", + () -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16) + .setId(ModItemResourceKeys.LEASH_ROPE_ARROW.getResourceKey())) ); - public static final Supplier SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow", - () -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16))); - public static final Supplier AMETHYST_SHEARS = ModItemRegister.register("amethyst_shears", - () -> new LeadBreakerItem(new Item.Properties().durability(100).component(DataComponents.TOOL, ShearsItem.createToolProperties()) - .stacksTo(1).setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "amethyst_shears"))))); - public static final Supplier FABRIC = ModItemRegister.register("fabric", - () -> new TestItem(new Item.Properties().stacksTo(1) - .setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "fabric"))))); + public static final DeferredHolder SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow", + () -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16) + .setId(ModItemResourceKeys.SPECTRAL_LEASH_ROPE_ARROW.getResourceKey()))); - public static Supplier register(String name, Supplier supplier) { + public static final DeferredHolder TIPPED_LEASH_ROPE_ARROW = ModItemRegister.register("tipped_leash_rope_arrow", + () -> new TippedLeashRopeArrowItem(new Item.Properties().stacksTo(16).component(DataComponents.POTION_CONTENTS, PotionContents.EMPTY) + .setId(ModItemResourceKeys.TIPPED_LEASH_ROPE_ARROW.getResourceKey()))); + public static final DeferredHolder AMETHYST_SHEARS = ModItemRegister.register("amethyst_shears", + () -> new LeadBreakerItem(ModToolMaterials.AMETHYST, new Item.Properties().durability(100).component(DataComponents.TOOL, ShearsItem.createToolProperties()) + .stacksTo(1) + .setId(ModItemResourceKeys.AMETHYST_SHEARS.getResourceKey()))); + public static final DeferredHolder FABRIC = ModItemRegister.register("fabric", + () -> new TestItem(new Item.Properties().stacksTo(1) + .setId(ModItemResourceKeys.FABRIC.getResourceKey()))); + public static final DeferredHolder NEOFORGE = ModItemRegister.register("neoforge", + () -> new Item(DistProperties(ModJukeboxSongs.FOX_MUSIC) + .setId(ModItemResourceKeys.NEOFORGE.getResourceKey()))); + + public static Item.Properties DistProperties(ResourceKey song) { + return new Item.Properties().stacksTo(1).rarity(Rarity.RARE).jukeboxPlayable(song); + } + + public static DeferredHolder register(String name, Supplier supplier) { return register(name, supplier, true); } - public static Supplier register(String name, Supplier supplier, boolean shouldJoinSupplierLists) { - Supplier supplierItem = ITEMS.register(name, supplier); + public static DeferredHolder register(String name, Supplier supplier, boolean shouldJoinSupplierLists) { + DeferredHolder supplierItem = ITEMS.register(name, supplier); if(shouldJoinSupplierLists) ITEM_SUPPLIER.add(supplierItem); return supplierItem; } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemResourceKeys.java b/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemResourceKeys.java new file mode 100644 index 0000000..96a4289 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemResourceKeys.java @@ -0,0 +1,29 @@ +package com.r3944realms.leashedplayer.content.items; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.neoforged.neoforge.registries.DeferredHolder; + +public enum ModItemResourceKeys { + LEASH_ROPE_ARROW(ModItemRegister.LEASH_ROPE_ARROW), + SPECTRAL_LEASH_ROPE_ARROW(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW), + TIPPED_LEASH_ROPE_ARROW (ModItemRegister.TIPPED_LEASH_ROPE_ARROW), + AMETHYST_SHEARS(ModItemRegister.AMETHYST_SHEARS), + FABRIC(ModItemRegister.FABRIC), + NEOFORGE(ModItemRegister.NEOFORGE) + ; + private final ResourceKey resourceKey; + ModItemResourceKeys(String name) { + resourceKey = ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, name)); + } + ModItemResourceKeys(DeferredHolder item) { + resourceKey = ResourceKey.create(Registries.ITEM, item.getId()); + } + + public ResourceKey getResourceKey() { + return resourceKey; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/ModToolMaterials.java b/src/main/java/com/r3944realms/leashedplayer/content/items/ModToolMaterials.java new file mode 100644 index 0000000..82f6105 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/ModToolMaterials.java @@ -0,0 +1,13 @@ +package com.r3944realms.leashedplayer.content.items; + +import com.r3944realms.leashedplayer.datagen.LanguageAndOtherData.ModItemTags; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.item.ToolMaterial; + +public class ModToolMaterials { + public static final ToolMaterial AMETHYST = + new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, + 100, 8.0F, 2.0F, 15, + ModItemTags.AMETHYST_TOOL_MATERIALS + ); +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/repcipe/ModRecipeRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/items/repcipe/ModRecipeRegister.java new file mode 100644 index 0000000..9b4dd5b --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/repcipe/ModRecipeRegister.java @@ -0,0 +1,27 @@ +package com.r3944realms.leashedplayer.content.items.repcipe; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.crafting.CustomRecipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; + +public class ModRecipeRegister { + public static final DeferredRegister> RECIPE_SERIALIZER = + DeferredRegister.create(BuiltInRegistries.RECIPE_SERIALIZER, LeashedPlayer.MOD_ID); + + public static final DeferredHolder, RecipeSerializer> TIPPED_LEASH_ROPE_ARROW_A_RECIPE = + RECIPE_SERIALIZER.register("tipped_leash_rope_arrow_a_recipe", () -> + new CustomRecipe.Serializer<>(TippedLeashRopeArrowRecipe.TippedLeashRopeArrowARecipe::new) + ); + public static final DeferredHolder, RecipeSerializer> TIPPED_LEASH_ROPE_ARROW_B_RECIPE = + RECIPE_SERIALIZER.register("tipped_leash_rope_arrow_b_recipe", () -> + new CustomRecipe.Serializer<>(TippedLeashRopeArrowRecipe.TippedLeashRopeArrowBRecipe::new) + ); + + public static void register(IEventBus eventBus) { + RECIPE_SERIALIZER.register(eventBus); + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/repcipe/TippedLeashRopeArrowRecipe.java b/src/main/java/com/r3944realms/leashedplayer/content/items/repcipe/TippedLeashRopeArrowRecipe.java new file mode 100644 index 0000000..ee9329a --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/repcipe/TippedLeashRopeArrowRecipe.java @@ -0,0 +1,106 @@ +package com.r3944realms.leashedplayer.content.items.repcipe; + +import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.CraftingBookCategory; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.CustomRecipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; + +public abstract class TippedLeashRopeArrowRecipe { + public static class TippedLeashRopeArrowARecipe extends CustomRecipe { + public TippedLeashRopeArrowARecipe(CraftingBookCategory pCategory) { + super(pCategory); + } + + public boolean matches(CraftingInput pInput, @NotNull Level pLevel) { + if (pInput.width() == 3 && pInput.height() == 3) { + for (int i = 0; i < pInput.height(); i++) { + for (int j = 0; j < pInput.width(); j++) { + ItemStack itemstack = pInput.getItem(j, i); + if (itemstack.isEmpty()) { + return false; + } + + if (j == 1 && i == 1) { + if (!itemstack.is(Items.LINGERING_POTION)) { + return false; + } + } else if (!itemstack.is(ModItemRegister.LEASH_ROPE_ARROW.get())) { + return false; + } + } + } + + return true; + } else { + return false; + } + } + + public @NotNull ItemStack assemble(CraftingInput pInput, HolderLookup.@NotNull Provider pRegistries) { + ItemStack itemstack = pInput.getItem(1, 1); + if (!itemstack.is(Items.LINGERING_POTION)) { + return ItemStack.EMPTY; + } else { + ItemStack itemstack1 = new ItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), 8); + itemstack1.set(DataComponents.POTION_CONTENTS, itemstack.get(DataComponents.POTION_CONTENTS)); + return itemstack1; + } + } + + @Override + public @NotNull RecipeSerializer getSerializer() { + return ModRecipeRegister.TIPPED_LEASH_ROPE_ARROW_A_RECIPE.get(); + } + } + public static class TippedLeashRopeArrowBRecipe extends CustomRecipe { + + public TippedLeashRopeArrowBRecipe(CraftingBookCategory pCategory) { + super(pCategory); + } + + @Override + public boolean matches(CraftingInput pInput, @NotNull Level pLevel) { + int tipped_arrow_count = 0, lead_count = 0; + for (int i = 0; i < pInput.width(); i++) { + for (int j = 0; j < pInput.height(); j++) { + if (pInput.getItem(i, j).is(Items.TIPPED_ARROW)) + tipped_arrow_count++; + else if(pInput.getItem(i, j).is(Items.LEAD)) + lead_count++; + } + } + return tipped_arrow_count == 1 && lead_count == 1; + } + + @Override + public @NotNull ItemStack assemble(@NotNull CraftingInput pInput, HolderLookup.@NotNull Provider pRegistries) { + ItemStack tipped_arrow = null; + NODE:for (int i = 0; i < pInput.width(); i++) { + for (int j = 0; j < pInput.height(); j++) { + if (pInput.getItem(i, j).is(Items.TIPPED_ARROW)) { + tipped_arrow = pInput.getItem(i, j); + break NODE; + } + } + } + if(tipped_arrow != null) { + ItemStack itemstack1 = new ItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), 1); + itemstack1.set(DataComponents.POTION_CONTENTS, tipped_arrow.get(DataComponents.POTION_CONTENTS)); + return itemstack1; + } + return ItemStack.EMPTY; + } + @Override + public @NotNull RecipeSerializer getSerializer() { + return ModRecipeRegister.TIPPED_LEASH_ROPE_ARROW_B_RECIPE.get(); + } + + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeadBreakerItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeadBreakerItem.java index 5c89428..34845a1 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeadBreakerItem.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeadBreakerItem.java @@ -1,18 +1,29 @@ package com.r3944realms.leashedplayer.content.items.type; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; +import com.r3944realms.leashedplayer.datagen.LanguageAndOtherData.ModItemTags; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderSet; +import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; import net.minecraft.tags.BlockTags; +import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ShearsItem; +import net.minecraft.world.item.ToolMaterial; +import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.component.Tool; +import net.minecraft.world.item.enchantment.Enchantable; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import org.jetbrains.annotations.NotNull; @@ -20,19 +31,26 @@ import org.jetbrains.annotations.NotNull; import java.util.List; public class LeadBreakerItem extends ShearsItem { - - public LeadBreakerItem(Properties properties) { - super(properties); + private final ToolMaterial toolMaterial; + public static final String HOVER_KEY = "leashedplayer.lead_breaker.item.desc", + MESSAGE_USE_SUF = "leashedplayer.lead_breaker.item.use_suf", + MESSAGE_USE_FAI = "leashedplayer.lead_breaker.item.use_fai"; + public LeadBreakerItem(ToolMaterial toolMaterial, Properties properties) { + super(properties.durability(toolMaterial.durability()) + .component(DataComponents.ENCHANTABLE, new Enchantable(toolMaterial.enchantmentValue())) + .repairable(ModItemTags.AMETHYST_TOOL_MATERIALS) + .enchantable(toolMaterial.enchantmentValue())); + this.toolMaterial = toolMaterial; } public static Tool createToolProperties() { HolderGetter holdergetter = BuiltInRegistries.acquireBootstrapRegistrationLookup(BuiltInRegistries.BLOCK); return new Tool( List.of( - Tool.Rule.minesAndDrops(HolderSet.direct(Blocks.COBWEB.builtInRegistryHolder()), 18.0F), + Tool.Rule.minesAndDrops(HolderSet.direct(BuiltInRegistries.BLOCK.wrapAsHolder(Blocks.COBWEB)), 18.0F), Tool.Rule.overrideSpeed(holdergetter.getOrThrow(BlockTags.LEAVES), 25.0F), Tool.Rule.overrideSpeed(holdergetter.getOrThrow(BlockTags.WOOL), 8.0F), - Tool.Rule.overrideSpeed(HolderSet.direct(Blocks.VINE.builtInRegistryHolder(), Blocks.GLOW_LICHEN.builtInRegistryHolder()), 4.0F) + Tool.Rule.overrideSpeed(HolderSet.direct(BuiltInRegistries.BLOCK.wrapAsHolder(Blocks.VINE), BuiltInRegistries.BLOCK.wrapAsHolder(Blocks.GLOW_LICHEN)), 4.0F) ), 1.0F, 1 @@ -43,20 +61,30 @@ public class LeadBreakerItem extends ShearsItem { if(!entity.level().isClientSide) { if (entity instanceof PlayerLeashable playerLeashable) { if (playerLeashable.isLeashed()){ - playerLeashable.dropLeash(true, !(playerLeashable.getLeashHolder() instanceof LeashRopeArrow)); - if (playerLeashable.getLeashHolder() instanceof LeashRopeArrow leashRopeArrow) { + entity.playSound(SoundEvents.SHEEP_SHEAR, 1.0F, 1.0F); + Entity leashHolder = playerLeashable.getLeashHolder(); + playerLeashable.dropLeash(true, !(leashHolder instanceof LeashRopeArrow)); + if (leashHolder instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.setOwner(null); } if (!player.isCreative()) stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); + if (leashHolder != null) { + ((ServerPlayer)player).sendSystemMessage(Component.translatable(MESSAGE_USE_SUF, entity.getDisplayName(), leashHolder.getDisplayName()), true); + } return InteractionResult.SUCCESS; } else return InteractionResult.PASS; } else if (entity instanceof Leashable leashable) { if (leashable.isLeashed()){ - leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow)); + entity.playSound(SoundEvents.SHEEP_SHEAR, 1.0F, 1.0F); + Entity leashHolder = leashable.getLeashHolder(); + leashable.dropLeash(true, !(leashHolder instanceof LeashRopeArrow)); if (leashable.getLeashHolder() instanceof LeashRopeArrow leashRopeArrow) { leashRopeArrow.setOwner(null); } if (!player.isCreative()) stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); + if (leashHolder != null) { + ((ServerPlayer)player).sendSystemMessage(Component.translatable(MESSAGE_USE_SUF, entity.getDisplayName(), leashHolder.getDisplayName()), true); + } return InteractionResult.SUCCESS; } else return InteractionResult.PASS; } @@ -64,4 +92,38 @@ public class LeadBreakerItem extends ShearsItem { return InteractionResult.PASS; } + @Override + public @NotNull InteractionResult use(@NotNull Level pLevel, @NotNull Player pPlayer, @NotNull InteractionHand pUsedHand) { + if (!pLevel.isClientSide && pUsedHand == InteractionHand.MAIN_HAND) { + PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; + if (playerLeashable.isLeashed()) { + Entity leashHolder = playerLeashable.getLeashHolder(); + if(!(leashHolder instanceof LeashRopeArrow)) { + playerLeashable.dropLeash(true, true); + pPlayer.getItemInHand(pUsedHand).hurtAndBreak(10, pPlayer, LivingEntity.getSlotForHand(pUsedHand)); + if (leashHolder != null) { + ((ServerPlayer)pPlayer).sendSystemMessage(Component.translatable(MESSAGE_USE_SUF, pPlayer.getDisplayName(), leashHolder.getDisplayName()), true); + } + return InteractionResult.SUCCESS; + } + ((ServerPlayer)pPlayer).sendSystemMessage(Component.translatable(MESSAGE_USE_FAI, pPlayer.getDisplayName(), leashHolder.getDisplayName()), true); + } + } + if(pLevel.isClientSide) { + PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; + if (playerLeashable.getLeashDataFromEntityData() != null) { + pPlayer.playSound(SoundEvents.SHEEP_SHEAR, 1.0F, 1.0F); + } + } + return super.use(pLevel, pPlayer, pUsedHand); + } + + + @Override + public void appendHoverText(@NotNull ItemStack pStack, @NotNull TooltipContext pContext, @NotNull List pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { + pTooltipComponents.add(Component.translatable(HOVER_KEY)); + } + + + } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java index 6b67624..cf7576b 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java @@ -1,15 +1,11 @@ package com.r3944realms.leashedplayer.content.items.type; -import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import net.minecraft.ChatFormatting; import net.minecraft.core.Direction; import net.minecraft.core.Position; -import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.Projectile; @@ -24,9 +20,17 @@ import javax.annotation.Nullable; import java.util.List; public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ - public static final String descKey = "item.leash_rope_arrow.description"; + public static final String descKey = "item.leash_rope_arrow.description", + DESC_1 = "item.leash_rope_arrow.desc.1", + DESC_2 = "item.leash_rope_arrow.desc.2", + DESC_3 = "item.leash_rope_arrow.desc.3", + DESC_4 = "item.leash_rope_arrow.desc.4", + DESC_5 = "item.leash_rope_arrow.desc.5"; + public static final String + DESC_V_1 = "item.variant.leash_rope_arrow.desc.1", + DESC_V_2 = "item.variant.leash_rope_arrow.desc.2"; public LeashRopeArrowItem(Item.Properties pProperties) { - super(pProperties.setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "leash_rope_arrow")))) ; + super(pProperties) ; } public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) { @@ -35,7 +39,7 @@ public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ @Override public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) { - LeashRopeArrow arrow = new LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, this.getDefaultInstance(),null, null); + LeashRopeArrow arrow = new LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, pStack,null, null); arrow.pickup = AbstractArrow.Pickup.DISALLOWED; return arrow; } @@ -45,7 +49,12 @@ public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ return Component.translatable(descKey).withStyle(ChatFormatting.GRAY); } public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { - //TODO:也许会做 + pTooltipComponents.addAll(List.of( + Component.translatable(DESC_1), + Component.translatable(DESC_2), + Component.translatable(DESC_3), + Component.translatable(DESC_4), + Component.translatable(DESC_5) + )); } - } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java index bce1101..1647e6a 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java @@ -1,16 +1,12 @@ package com.r3944realms.leashedplayer.content.items.type; -import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.entities.SpectralLeashRopeArrow; import net.minecraft.ChatFormatting; import net.minecraft.core.Direction; import net.minecraft.core.Position; -import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.Projectile; @@ -25,9 +21,10 @@ import javax.annotation.Nullable; import java.util.List; public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ - public static final String descKey = "item.spectral_leash_rope_arrow.description"; + public static final String descKey = "item.spectral_leash_rope_arrow.description", + DESC = "item.spectral_leash_rope_arrow.desc"; public SpectralLeashRopeArrowItem(Properties pProperties) { - super(pProperties.setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "spectral_leash_rope_arrow")))); + super(pProperties); } public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) { return new SpectralLeashRopeArrow(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon); @@ -44,6 +41,10 @@ public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeA return Component.translatable(descKey).withStyle(ChatFormatting.GRAY); } public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { - //TODO:也许会做 + pTooltipComponents.addAll(List.of( + Component.translatable(LeashRopeArrowItem.DESC_V_1), + Component.translatable(LeashRopeArrowItem.DESC_V_2), + Component.translatable(DESC) + )); } } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/type/TippedLeashRopeArrowItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/TippedLeashRopeArrowItem.java new file mode 100644 index 0000000..d1cbd4c --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/TippedLeashRopeArrowItem.java @@ -0,0 +1,57 @@ +package com.r3944realms.leashedplayer.content.items.type; + +import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.world.item.alchemy.Potions; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Optional; + +public class TippedLeashRopeArrowItem extends LeashRopeArrowItem { + public static final String TIPPED_LEASH_ROPE_ARROW_NAME = "item.tipped_leash_rope_arrow.name"; + public static final String DESC = "item.tipped_leash_rope_arrow.desc"; + public TippedLeashRopeArrowItem(Properties pProperties) { + super(pProperties); + } + @Override + public @NotNull ItemStack getDefaultInstance() { + ItemStack itemstack = super.getDefaultInstance(); + itemstack.set(DataComponents.POTION_CONTENTS, new PotionContents(Potions.POISON)); + return itemstack; + } + + @Override + public void appendHoverText(@NotNull ItemStack pStack, @NotNull TooltipContext pContext, @NotNull List pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { + pTooltipComponents.addAll(List.of( + Component.translatable(LeashRopeArrowItem.DESC_V_1), + Component.translatable(LeashRopeArrowItem.DESC_V_2), + Component.translatable(DESC) + )); + PotionContents potioncontents = pStack.get(DataComponents.POTION_CONTENTS); + if (potioncontents != null) { + potioncontents.addPotionTooltip(pTooltipComponents::add, 0.125F, pContext.tickRate()); + } + + } + + + @Override + public @NotNull Component getName(@NotNull ItemStack pStack) { + Optional> pPotion = pStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); + String s = null,s1; + if (pPotion.isPresent()) { + s = pPotion.get().value().name(); + } + boolean flag = s == null; + s1 = pPotion.flatMap(Holder::unwrapKey).map(p_331494_ -> p_331494_.location().getPath()).orElse("empty"); + String potionTranslateKey = "item.minecraft.potion.effect." + (flag ? s1: s); + return Component.translatable(TIPPED_LEASH_ROPE_ARROW_NAME, Component.translatable(potionTranslateKey)); + } + +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/misc/LeadBreakItemBehavior.java b/src/main/java/com/r3944realms/leashedplayer/content/misc/LeadBreakItemBehavior.java index a950661..4b45d87 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/misc/LeadBreakItemBehavior.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/misc/LeadBreakItemBehavior.java @@ -9,7 +9,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.tags.BlockTags; -import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.EntitySelector; import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.LivingEntity; diff --git a/src/main/java/com/r3944realms/leashedplayer/content/sounds/ModSoundRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/sounds/ModSoundRegister.java new file mode 100644 index 0000000..d9e1359 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/sounds/ModSoundRegister.java @@ -0,0 +1,35 @@ +package com.r3944realms.leashedplayer.content.sounds; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; + +import java.util.function.Supplier; + +public class ModSoundRegister { + public static DeferredRegister SOUNDS = DeferredRegister.create(BuiltInRegistries.SOUND_EVENT, LeashedPlayer.MOD_ID); + public static ResourceLocation RL_FOX_MUSIC = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "music/what_does_the_fox_say"); + public static final DeferredHolder FOX_MUSIC = + ModSoundRegister.register("what_does_the_fox_say", () -> SoundEvent.createFixedRangeEvent( + RL_FOX_MUSIC, + 128 + )); + + public static DeferredHolder register(String name, Supplier supplier){ + return SOUNDS.register(name, supplier); + + } + public static void register(IEventBus modBus){ + SOUNDS.register(modBus); + } + public static String getJukeboxSongTranslateKey(String name) { + return "jukebox_song." + LeashedPlayer.MOD_ID + "." + name; + } + public static String getSubTitleTranslateKey(String name) { + return "sound." + LeashedPlayer.MOD_ID + ".subtitle." + name; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java index 4d331d4..ecc983a 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java @@ -16,6 +16,8 @@ public enum ModAdvancementKey { DOG_RUNNING_PLAYER("dog_running_player", LEASH_ARROW), NO_LEASH("no_leash", LEASH_START), LEASH_TERMINATOR("leash_terminator", LEASH_START), + TIPPED_LEASH_ARROW("tipped_leash_arrow", LEASH_ARROW), + NEO_FOX("neo_fox", LEASH_START), ; private final String Name; @Nullable diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModItemTags.java b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModItemTags.java new file mode 100644 index 0000000..1371e68 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModItemTags.java @@ -0,0 +1,21 @@ +package com.r3944realms.leashedplayer.datagen.LanguageAndOtherData; + +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; + +public final class ModItemTags { + public static final TagKey AMETHYST_TOOL_MATERIALS = bind("amethyst_tool_materials"); + + private ModItemTags() { + } + + private static TagKey bind(String name) { + return TagKey.create(Registries.ITEM, ResourceLocation.withDefaultNamespace(name)); + } + + public static TagKey create(final ResourceLocation name) { + return TagKey.create(Registries.ITEM, name); + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java index 2f44323..7637e49 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java @@ -1,18 +1,26 @@ package com.r3944realms.leashedplayer.datagen.LanguageAndOtherData; +import com.r3944realms.leashedplayer.content.ModKeyMapping; import com.r3944realms.leashedplayer.content.commands.LeashCommand; import com.r3944realms.leashedplayer.content.commands.MotionCommand; import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; import com.r3944realms.leashedplayer.content.effects.ModPotionRegister; +import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent; -import com.r3944realms.leashedplayer.content.gamerules.Server.DisablePlayerMoveCheck; import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTime; import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers; import com.r3944realms.leashedplayer.content.items.ModCreativeTab; import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import com.r3944realms.leashedplayer.content.items.type.LeadBreakerItem; import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.items.type.TippedLeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister; import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants; +import com.r3944realms.leashedplayer.network.server.Code; +import com.r3944realms.leashedplayer.network.server.DecreaseLeashRopeLength; +import com.r3944realms.leashedplayer.network.server.IncreaseLeashRopeLength; import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum; import com.r3944realms.leashedplayer.utils.Enum.ModPartEnum; import net.minecraft.world.item.Item; @@ -25,20 +33,40 @@ import java.util.function.Supplier; import static com.r3944realms.leashedplayer.content.items.ModCreativeTab.LEASHED_PLAYER_ITEM; public enum ModLangKeyValue { + KEY_CATEGORY(ModKeyMapping.CATEGORY, ModPartEnum.NAME, "Leashed Player", "可拴玩家", "可拴玩家", false), + KEY_ADD_LEASH_OTHER_LEASH_LENGTH(ModKeyMapping.ADD_LEASH_LENGTH_KEY, ModPartEnum.NAME, "Increase the Length of Leash Rope", "增加拴绳长度", "增加拴繩長度", false), + KEY_SUB_LEASH_OTHER_LEASH_LENGTH(ModKeyMapping.SUB_LEASH_LENGTH_KEY, ModPartEnum.NAME, "Decrease the Length of Leash Rope", "减小拴绳长度", "減小拴繩長度", false), //ITEM ITEM_LEASH_ROPE_ARROW(ModItemRegister.LEASH_ROPE_ARROW, ModPartEnum.ITEM, "Leash Rope Arrow", "拴绳箭", "拴繩箭", true), ITEM_SPECTRAL_LEASH_ROPE_ARROW(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW, ModPartEnum.ITEM, "Spectral Leash Rope Arrow", "拴绳光灵箭", "拴繩光靈箭", true), TEST_FABRIC_ITEM(ModItemRegister.FABRIC, ModPartEnum.ITEM, "Fabric", "Fabric", "Fabric", true), AMETHYST_SHEARS(ModItemRegister.AMETHYST_SHEARS, ModPartEnum.ITEM, "Amethyst Shears", "紫水晶剪刀", "紫水晶剪刀", true), - // LEAD_ROPE_POTTERY_SHERD(ModItemRegister.LEAD_ROPE_POTTERY_SHERD, ModPartEnum.ITEM, "Lead Rope Pottery Sherd", "拴绳纹样陶片", "拴繩紋樣陶片", true), + NEO_FORGE(ModItemRegister.NEOFORGE, ModPartEnum.ITEM, "NeoForge", "NeoForge", "NeoForge", false), + TIPPED_LEASH_ROPE_ARROW(TippedLeashRopeArrowItem.TIPPED_LEASH_ROPE_ARROW_NAME, ModPartEnum.ITEM, "Tipped Leash Rope Arrow Soaked By %1$s", "用%1$s浸泡过的拴绳箭", "蘸有%1$s的拴繩箭", false), //ITEM_DESC + DESC_ITEM_LEASH_R_ARROW_ONE(LeashRopeArrowItem.DESC_1, ModPartEnum.DESCRIPTION, "§7This arrow will carry the owner along with its flight:", "§7该箭将会携带拥有者随其飞行", "§7該箭將會攜帶擁有者隨其飛行:", false), + DESC_ITEM_LEASH_R_ARROW_TWO(LeashRopeArrowItem.DESC_2, ModPartEnum.DESCRIPTION, "§c1.§r If it hits a fence or an entity, it will leash the owner to it and drop as a normal arrow.", "§c1.§r 若击中栅栏或生物时,将持有者拴在其上并已普通箭形式掉落;", "§c1.§r 若擊中柵欄或生物時,將持有者拴在其上並以普通箭的形式掉落;", false), + DESC_ITEM_LEASH_R_ARROW_THREE(LeashRopeArrowItem.DESC_3, ModPartEnum.DESCRIPTION,"§c2.§r Crouching near the arrow allows for faster retrieval. If the arrow's owner is not the player, the owner will be leashed to the player who picks it up.", "§c2.§r 靠近该箭下蹲可以更快拾取该箭,如果该箭持有者不是自己,则持有者将被拾取者拴住;", "§c2.§r 靠近該箭下蹲可以更快拾取該箭,如果該箭的持有者不是自己,則持有者將被拾取者拴住;", false), + DESC_ITEM_LEASH_R_ARROW_FOUR(LeashRopeArrowItem.DESC_4, ModPartEnum.DESCRIPTION, "§c3.§r When fired from its launcher, the first entity hit will become the arrow's owner and will fly along with it.", "§c3.§r 当前其发射器里发射,第一个射中的生物将成为此箭的持有者并随箭飞行;", "§c3.§r 當箭從發射器發射時,第一個射中的生物將成為此箭的持有者並隨箭飛行;", false), + DESC_ITEM_LEASH_R_ARROW_FIVE(LeashRopeArrowItem.DESC_5, ModPartEnum.DESCRIPTION, "§c4.§r Under the §c§l\"no_leash\"§r effect, the behavior of the arrow when fired will follow the launcher’s behavior.", "§c4.§r 在§c§l禁拴§7(§c§lno_leash§7)§r效果下,射出的箭行为同发射器。","§c4.§r 在§c§l禁拴§7(§c§lno_leash§7)§r效果下,射出的箭行為將與發射器的行為相同。", false), DESC_ITEM_LEASH_ROPE_ARROW(LeashRopeArrowItem.descKey, ModPartEnum.DESCRIPTION, "Arrows with ropes attached?","带有拴绳的箭矢?", "帶有拴繩的箭矢?", false), + DESC_ITEM_V_LEASH_R_ARROW_ONE(LeashRopeArrowItem.DESC_V_1, ModPartEnum.DESCRIPTION, "§7A variant of Leash Rope Arrow", "§7拴绳箭的一个变种", "§7拴繩箭矢的一個變種", false), + DESC_ITEM_V_LEASH_R_ARROW_TWO(LeashRopeArrowItem.DESC_V_2, ModPartEnum.DESCRIPTION, "§c1.§r The function is the same as its original one。", "§c1.§r 功能同其本体;", "§c1.§r 功能與本體一致;", false), + DESC_ITEM_S_LEASH_R_ARROW_THREE(SpectralLeashRopeArrowItem.DESC, ModPartEnum.DESCRIPTION, "§c2.§r Strike the entity to give it a §e§lGlowing§r effect.", "§c2.§r 击中实体给与其§e§l发光§7(§e§lGlowing§7)§r效果", "擊中實體給予其§e§l發光§7(§e§lGlowing§7)§r效果", false), + DESC_ITEM_T_LEASH_R_ARROW_THREE(TippedLeashRopeArrowItem.DESC, ModPartEnum.DESCRIPTION, "§c2.§rStrike the entity to give it a Potion effect.", "§c2.§r 击中实体给与其药水效果", "擊中實體給予其药水效果", false), + DESC_ITEM_LEAD_BREAKER(LeadBreakerItem.HOVER_KEY, ModPartEnum.DESCRIPTION, "§7can break the link of leash", "§7可以破坏拴绳链接", "§7可以破壞拴繩鏈接", false), + //PAINTING GROUP_PHOTO_TITLE(ModPaintingVariants.getPaintingVariantTitleKey(ModPaintingVariants.GROUP_PHOTO),ModPartEnum.TITLE, "§dGroup Photo §7[§6memorable§7]§r", "§d集体照 §7[§6纪念§7]§r", "§d集體照 §7[§6紀念§7]§r", false), GROUP_PHOTO_AUTHOR(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO),ModPartEnum.AUTHOR, "§9Leisure §4Time §eDock§r","§9闲趣§4时§e坞§r","§9閑趣§4時§e塢§r",false), //ENTITY LEASH_ROPE_ARROW(ModEntityRegister.getEntityNameKey("leash_rope_arrow"), ModPartEnum.ENTITY, "Leash Rope Arrow", "拴绳箭", "拴繩箭", false), SPECTRAL_LEASH_ROPE_ARROW(ModEntityRegister.getEntityNameKey("spectral_leash_rope_arrow"), ModPartEnum.ENTITY, "Spectral Leash Rope Arrow", "拴绳光灵箭", "拴繩光靈箭", false), + kID(ModEntityRegister.getEntityNameKey("kid_player"), ModPartEnum.ENTITY, "Kid", "小孩", "小孩", "幼", false), + NESTLE_ROPE_ARROW(ModEntityRegister.getEntityNameKey("nestle_rope_arrow"), ModPartEnum.ENTITY, "Nestle Rope Arrow", "贴贴拴绳箭", "貼貼拴繩箭", false), + //DIST + ST_WHAT_DOES_THE_FOX_SAY(ModSoundRegister.getSubTitleTranslateKey("what_does_the_fox_say"), ModPartEnum.TITLE, "Great Chu will rise again! Chen She will be king!", "大楚兴~ 陈胜王~~", "大楚興~ 陳勝王~~", false), + JB_WHAT_DOES_THE_FOX_SAY(ModSoundRegister.getJukeboxSongTranslateKey("what_does_the_fox_say"), ModPartEnum.DESCRIPTION, "What does the fox say?", "狐狸是怎么叫的?", "狐狸是怎麽叫的?", false), //CREATIVE_TAB CREATIVE_TAB_NAME(ModCreativeTab.getCreativeMod(LEASHED_PLAYER_ITEM), ModPartEnum.CREATIVE_TAB, "Leashed Player","可拴玩家", "可拴玩家", false), //COMMAND_MESSAGE @@ -57,16 +85,26 @@ public enum ModLangKeyValue { MESSAGE_MOTION_ADDER_SUCCESSFUL(MotionCommand.MOTION_ADDER_SUCCESSFUL, ModPartEnum.COMMAND, "§bAdd Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r","§b添加成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r","§b添加成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r", false), MESSAGE_MOTION_SETTER_SUCCESSFUL(MotionCommand.MOTION_SETTER_SUCCESSFUL, ModPartEnum.COMMAND, "§bSet Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r","§b设置成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r","§b設置成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",false), MESSAGE_MOTION_MULTIPLY_SUCCESSFUL(MotionCommand.MOTION_MULTIPLY_SUCCESSFUL, ModPartEnum.COMMAND, "§bMultiply Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r","§b倍乘成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r","§b倍乘成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",false), + MESSAGE_LEASH_BREAKER_USE_SUF(LeadBreakerItem.MESSAGE_USE_SUF, ModPartEnum.MESSAGE, "§aSuccessfully break §f%1$s§a 's Leashed Link to §f%2$s ", "§a成功剪断§f%2$s§a对§f%1$s§a拴绳链接", "§a成功剪斷§f%2$s§a對§f%1$s§a拴繩鏈接", false), + MESSAGE_LEASH_BREAKER_USE_FAI(LeadBreakerItem.MESSAGE_USE_FAI, ModPartEnum.MESSAGE, "§cFailed to break §f%1$s§c 's Leashed Link to §f%2$s", "§c无法剪断§f%2$s§c对§f%1$s§c拴绳链接", "§c未能剪斷§f%2$s§c對§f%1$s§c拴繩鏈接", false), + MESSAGE_LEASH_NOT_SUPPORT_TO_NOT_PLAYER_ENTITY(ModKeyMapping.NOT_SUPPORT_TO_NOT_PLAYER_ENTITY, ModPartEnum.MESSAGE, "Only work on Players", "只在玩家身上有效", "僅對玩家有效", false), + MESSAGE_LEASH_ADD_LEASH_LENGTH(IncreaseLeashRopeLength.INCREASE_LEASH_ROPE_LENGTH, ModPartEnum.MESSAGE, "§aIncrease the §f%s §aLength of Leash Rope§7(§bLength§7:§e%d§7)", "§a增加§f%s的拴绳长度§a§7(§b长度§7:§e%d§7)", "§a增加§f%s§a的拴繩長度§7(§長度§7:§e%d§7)", false), + MESSAGE_LEASH_SUB_LEASH_LENGTH(DecreaseLeashRopeLength.DECREASE_LEASH_ROPE_LENGTH, ModPartEnum.MESSAGE, "§Decrease the §f%s §cLength of Leash Rope§7(§bLength§7:§e%d§7)", "§c减少§f%s的拴绳长度§c§7(§b长度§7:§e%d§7)", "§c減少§f%s§c的拴繩長度§7(§長度§7:§e%d§7)", false), + MESSAGE_LEASH_ADD_SELF_LEASH_LENGTH(IncreaseLeashRopeLength.INCREASE_SELF_LEASH_ROPE_LENGTH, ModPartEnum.MESSAGE, "§aIncrease the Length of Leash Rope§7(§bLength§7:§e%d§7)", "§a增加拴绳长度§a§7(§b长度§7:§e%d§7)", "§a增加拴繩長度§7(§長度§7:§e%d§7)", false), + MESSAGE_LEASH_SUB_SELF_LEASH_LENGTH(DecreaseLeashRopeLength.DECREASE_SELF_LEASH_ROPE_LENGTH, ModPartEnum.MESSAGE, "§cDecrease the Length of Leash Rope§7(§bLength§7:§e%d§7)", "§c减少拴绳长度§c§7(§b长度§7:§e%d§7)", "§c減少拴繩長度§7(§長度§7:§e%d§7)", false), + MESSAGE_LEASH_FAILED_SET_LENGTH(Code.LEASH_LENGTH_FAILED_SET, ModPartEnum.MESSAGE, "§cFailed", "§c失败", "§c失敗", false), //GAME_RULE_NAME - TELEPORT_WITH_LEASHED_PLAYERS(TeleportWithLeashedPlayers.NAME_KEY, ModPartEnum.NAME, "Teleport leashed player with player holder", "被拴玩家随玩家持有者传送", "被拴玩家随玩家持有者傳送" ,false), - CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT(CreateLeashFenceKnotEntityIfAbsent.NAME_KEY, ModPartEnum.NAME, "Create Leash Fence Knot Entity if absent", "如果缺失则创建拴绳结", "如果缺失則創建拴繩結", false), - KEEP_LEASH_NOT_DROP_TIME(KeepLeashNotDropTime.NAME_KEY, ModPartEnum.NAME, "Keep leash alive Time", "保持拴绳不掉落的时间", "保持其不掉落的時間", false), - DISABLE_MOVE_CHECK(DisablePlayerMoveCheck.NAME_KEY, ModPartEnum.NAME, "Disable Player Move Check", "禁止检查玩家移动", "禁止檢查玩家移動", false), + TELEPORT_WITH_LEASHED_PLAYERS_NAME(TeleportWithLeashedPlayers.NAME_KEY, ModPartEnum.NAME, "Teleport leashed player with player holder", "被拴玩家随玩家持有者传送", "被拴玩家随玩家持有者傳送" ,false), + CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT_NAME(CreateLeashFenceKnotEntityIfAbsent.NAME_KEY, ModPartEnum.NAME, "Create Leash Fence Knot Entity if absent", "如果缺失则创建拴绳结", "如果缺失則創建拴繩結", false), + KEEP_LEASH_NOT_DROP_TIME_NAME(KeepLeashNotDropTime.NAME_KEY, ModPartEnum.NAME, "Keep leash alive Time", "保持拴绳不掉落的时间", "保持其不掉落的時間", false), + + TRY_TO_PICKUP_LEASHED_ROPE_ARROW(LeashRopeArrow.PUSH_SHIFT_TO_PICKUP_QUICKLY, ModPartEnum.MESSAGE, "§aPush §f§lShift§a to pick up quickly", "§a按下§f§lShift键§a以加快拾取", "§a按下§f§lShift鍵§a以加速拾取", false), //GAME_RULE_DESCRIPTION TELEPORT_WITH_LEASHED_DESCRIPTION(TeleportWithLeashedPlayers.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Holder will teleport with their leashed players ", "传送时将被拴玩家与持有者一起传送", "將被拴玩家將隨持有者一起傳送" ,false), CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT_DESCRIPTION(CreateLeashFenceKnotEntityIfAbsent.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Create LeashKnot Entity if it's absent on fence", "如果在栅栏处缺失拴绳结,则创建它", "如果在柵欄処缺失拴繩結,則創建它", false), KEEP_LEASH_NOT_DROP_TIME_DESCRIPTION(KeepLeashNotDropTime.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION,"The time of Keep new leash which has far distance alive (Tick)", "当距离过远时,保持新建拴绳不掉落的时间 (刻)", "儅距離過遠時,保持其不掉落的時間(刻)", false), - DISABLE_MOVE_CHECK_DESCRIPTION(DisablePlayerMoveCheck.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Disable the player's movement Check And Correct it.", "禁止检查玩家移动并且纠正它","禁止檢查玩家移動並糾正他它", false), + + //ADV_NAME LEASH_START(ModAdvancementKey.LEASH_START.getNameKey(), ModPartEnum.NAME, "The Power of Traction", "牵引之力", "牽引之力", false), LEASH_LR_ARROW(ModAdvancementKey.LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "Arrow with a Tether?" , "拴绳之箭?", "拴繩之箭?", false), @@ -75,8 +113,10 @@ public enum ModLangKeyValue { LEASH_PLAYER(ModAdvancementKey.LEASHED_FRIEND.getNameKey(),ModPartEnum.NAME, "Be bound by Rope", "拴绳链接", "拴繩鏈接" , false), FOLLOW_ARROW(ModAdvancementKey.FOLLOW_LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "Launch!!!", "启航!!!" , "啓航!!!",false), FOLLOW_WOLF(ModAdvancementKey.DOG_RUNNING_PLAYER.getNameKey(), ModPartEnum.NAME, "It's Walking human time.", "遛“人”时间", "遛“人”時間",false), - NO_LEASH(ModAdvancementKey.NO_LEASH.getNameKey(), ModPartEnum.NAME, "Don't tie me up", "勿拴我", "請恁勿拴唔", false), TERMINATOR(ModAdvancementKey.LEASH_TERMINATOR.getNameKey(), ModPartEnum.NAME, "The Lead Terminator", "拴绳终结者","拴繩終結者", false), + NO_LEASH(ModAdvancementKey.NO_LEASH.getNameKey(), ModPartEnum.NAME, "Don't tie me up", "勿拴我", "請恁勿拴唔", false), + TIPPED_LEASH_ARROW(ModAdvancementKey.TIPPED_LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "God said there should be more arrows", "神说要有更多箭矢", "神說要有更多箭矢", false), + NEO_FOX(ModAdvancementKey.NEO_FOX.getNameKey(), ModPartEnum.NAME, "NEOFORGE!", "NEOFORGE!", "NEOFORGE!", false), //ADV_DESC LEASH_START_DESC(ModAdvancementKey.LEASH_START.getDescKey(), ModPartEnum.DESCRIPTION, "Journey to becoming a Leash Expert", "拴绳大师之路", "拴繩大師之路", false), LEASH_LR_ARROW_DESC(ModAdvancementKey.LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "Maybe you can using it to shoot some mob?", "也许可以用它来发射生物?", "也許可以用它發射生物?", false), @@ -85,8 +125,11 @@ public enum ModLangKeyValue { LEASH_PLAYER_DESC(ModAdvancementKey.LEASHED_FRIEND.getDescKey(),ModPartEnum.DESCRIPTION, "Be Bond by player with lead", "被玩家用拴绳链接", "被玩家用拴繩鏈接", false), FOLLOW_ARROW_DESC(ModAdvancementKey.FOLLOW_LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "Mc, what are you talking about in physics?", "抱歉,我的世界不存在物理学" , "抱歉,麦块不講物理學",false), FOLLOW_WOLF_DESC(ModAdvancementKey.DOG_RUNNING_PLAYER.getDescKey(), ModPartEnum.DESCRIPTION, "In the park where dogs are not allowed to be walked, the dog decided to walk the human instead", "公园不能遛狗,于是狗站起来遛人", "公園裏不許遛狗,於是狗站起來遛人",false), + NO_LEASH_DESC(ModAdvancementKey.NO_LEASH.getDescKey(), ModPartEnum.DESCRIPTION, "You cannot be leashed by ANY", "你不会被任何东西拴住", "恁不會被任何拴住", false), TERMINATOR_DESC(ModAdvancementKey.LEASH_TERMINATOR.getDescKey(), ModPartEnum.DESCRIPTION, "I am Lead Terminator!", "我來终结拴绳者!", "吾將終結拴繩!", false), - NO_LEASH_DESC(ModAdvancementKey.NO_LEASH.getDescKey(), ModPartEnum.NAME, "You cannot be leashed by ANY", "你不会被任何东西拴住", "恁不會被任何拴住", false), + TIPPED_LEASH_ARROW_DESC(ModAdvancementKey.TIPPED_LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "A dazzling array of Leash Rope arrows", "真是琳琅满目啊", "真是琳琅滿目啊", false), + NEO_FOX_DESC(ModAdvancementKey.NEO_FOX.getDescKey(), ModPartEnum.DESCRIPTION, "It seems can be equipped.", "似乎可以戴头上", "似乎可以戴著", false), + //MOB_EFFECT NO_LEASH_EFFECT(ModEffectRegister.getEffectKey(ModEffectRegister.NO_LEASH_EFFECT.get()), ModPartEnum.NAME, "No Leash", "禁拴", "禁拴", false), //POTION diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/ModDataGeneratorHandler.java b/src/main/java/com/r3944realms/leashedplayer/datagen/ModDataGeneratorHandler.java index 5854830..3065405 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/ModDataGeneratorHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/ModDataGeneratorHandler.java @@ -29,6 +29,7 @@ public class ModDataGeneratorHandler { ItemModelGenerator(event, existingFileHelper); RecipeGenerator(event, holderFolder); ModTagsProvider(event, event.getLookupProvider(), existingFileHelper); + ModSoundProvider(event, existingFileHelper); ModAdvancementProvider(event, holderFolder, existingFileHelper); } private static void addLanguage(GatherDataEvent event, LanguageEnum language){ @@ -62,7 +63,13 @@ public class ModDataGeneratorHandler { new ModItemTagProvider(pOutput, completableFuture, modBlockTagProvider.contentsGetter(), helper) ); } - + private static void ModSoundProvider(GatherDataEvent event, ExistingFileHelper helper) { + event.getGenerator().addProvider( + event.includeServer(), + (DataProvider.Factory) pOutput -> + new ModSoundDefinitionsProvider(pOutput,LeashedPlayer.MOD_ID, helper) + ); + } private static void ModDataPackBuiltInEntriesProvider(GatherDataEvent event, CompletableFuture future) { event.getGenerator().addProvider( event.includeServer(), diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java b/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java index ed60c16..8900a89 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java @@ -150,6 +150,29 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG .and(ModEffectRegister.NO_LEASH_EFFECT) ) ).parent(hasLeashRopeItem).save(saver, ModAdvancementKey.NO_LEASH.getNameWithNameSpace()); + AdvancementHolder tipped_leash_arrow = Advancement.Builder.advancement().display( + ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), + Component.translatable(ModAdvancementKey.TIPPED_LEASH_ARROW.getNameKey()), + Component.translatable(ModAdvancementKey.TIPPED_LEASH_ARROW.getDescKey()), + null, + AdvancementType.GOAL, + true, + true, + true + ).addCriterion("has_tipped_leash_arrow", InventoryChangeTrigger.TriggerInstance.hasItems(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get()) + ).parent(hasLeashRopeArrow).save(saver, ModAdvancementKey.TIPPED_LEASH_ARROW.getNameWithNameSpace()); + AdvancementHolder neo_fox = Advancement.Builder.advancement().display( + ModItemRegister.NEOFORGE.get(), + Component.translatable(ModAdvancementKey.NEO_FOX.getNameKey()), + Component.translatable(ModAdvancementKey.NEO_FOX.getDescKey()), + null, + AdvancementType.GOAL, + true, + false, + true + ).addCriterion("has_neo_fox", InventoryChangeTrigger.TriggerInstance.hasItems(ModItemRegister.NEOFORGE.get()) + ).parent(hasLeashRopeItem).save(saver, ModAdvancementKey.NEO_FOX.getNameWithNameSpace()); + } } diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModDataPackBuiltInEntriesProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModDataPackBuiltInEntriesProvider.java index a531797..0f1b4d9 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModDataPackBuiltInEntriesProvider.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModDataPackBuiltInEntriesProvider.java @@ -1,6 +1,7 @@ package com.r3944realms.leashedplayer.datagen.provider; import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs; import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants; import net.minecraft.core.HolderLookup; import net.minecraft.core.RegistrySetBuilder; @@ -13,7 +14,8 @@ import java.util.concurrent.CompletableFuture; public class ModDataPackBuiltInEntriesProvider extends DatapackBuiltinEntriesProvider { public static final RegistrySetBuilder BUILDER = new RegistrySetBuilder() - .add(Registries.PAINTING_VARIANT, ModPaintingVariants::bootstrap); + .add(Registries.PAINTING_VARIANT, ModPaintingVariants::bootstrap) + .add(Registries.JUKEBOX_SONG, ModJukeboxSongs::bootstrap); public ModDataPackBuiltInEntriesProvider(PackOutput output, CompletableFuture registries) { super(output, registries, BUILDER, Set.of(LeashedPlayer.MOD_ID)); CompletableFuture registryProvider = getRegistryProvider(); diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemModelProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemModelProvider.java index 249de34..355cae5 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemModelProvider.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemModelProvider.java @@ -46,6 +46,10 @@ public class ModItemModelProvider extends ItemModelProvider { getBuilder("bow_lra_pulling_2") .parent(new ModelFile.UncheckedModelFile("item/bow")) .texture("layer0", ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "item/bow_lra_pulling_2")); + getBuilder("tipped_leash_rope_arrow") + .parent(new ModelFile.UncheckedModelFile("item/generated")) + .texture("layer0", ResourceLocation.withDefaultNamespace("item/tipped_arrow_head")) + .texture("layer1", ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "item/tipped_leash_rope_arrow_base")); } @Override diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java index c7230f3..61cae78 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java @@ -2,11 +2,14 @@ package com.r3944realms.leashedplayer.datagen.provider; import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import com.r3944realms.leashedplayer.datagen.LanguageAndOtherData.ModItemTags; import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; import net.minecraft.data.tags.ItemTagsProvider; import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; +import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.common.data.ExistingFileHelper; import org.jetbrains.annotations.NotNull; @@ -22,6 +25,20 @@ public class ModItemTagProvider extends ItemTagsProvider { protected void addTags(HolderLookup.@NotNull Provider pProvider) { this.tag(ItemTags.ARROWS) .add(ModItemRegister.LEASH_ROPE_ARROW.get()) - .add(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); + .add(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()) + .add(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get()); + this.tag(ModItemTags.AMETHYST_TOOL_MATERIALS) + .add(Items.AMETHYST_SHARD); + this.tag(ItemTags.HEAD_ARMOR) + .add(ModItemRegister.NEOFORGE.get()) + .add(Items.LEAD); + this.tag(ItemTags.MINING_ENCHANTABLE) + .add(ModItemRegister.AMETHYST_SHEARS.get()); + this.tag(ItemTags.VANISHING_ENCHANTABLE) + .add(ModItemRegister.AMETHYST_SHEARS.get()); + this.tag(ItemTags.DURABILITY_ENCHANTABLE) + .add(ModItemRegister.AMETHYST_SHEARS.get()); + this.tag(Tags.Items.TOOLS_SHEAR) + .add(ModItemRegister.AMETHYST_SHEARS.get()); } } diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java index 0d7e8eb..b6cf9da 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java @@ -1,11 +1,13 @@ package com.r3944realms.leashedplayer.datagen.provider; import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import com.r3944realms.leashedplayer.content.items.repcipe.TippedLeashRopeArrowRecipe; import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.data.recipes.RecipeProvider; +import net.minecraft.data.recipes.SpecialRecipeBuilder; import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; @@ -45,6 +47,8 @@ public class ModRecipeProvider extends RecipeProvider { .define('%', Items.STICK) .unlockedBy("has_amethyst_shard",has(Items.AMETHYST_SHARD)) .save(this.output); + SpecialRecipeBuilder.special(TippedLeashRopeArrowRecipe.TippedLeashRopeArrowARecipe::new).save(this.output, "tipped_leash_rope_arrow_a"); + SpecialRecipeBuilder.special(TippedLeashRopeArrowRecipe.TippedLeashRopeArrowBRecipe::new).save(this.output, "tipped_leash_rope_arrow_b"); } public static class Runner extends RecipeProvider.Runner { diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModSoundDefinitionsProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModSoundDefinitionsProvider.java new file mode 100644 index 0000000..829a52a --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModSoundDefinitionsProvider.java @@ -0,0 +1,37 @@ +package com.r3944realms.leashedplayer.datagen.provider; + + +import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister; +import net.minecraft.data.PackOutput; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.common.data.SoundDefinition; +import net.neoforged.neoforge.common.data.SoundDefinitionsProvider; + +public class ModSoundDefinitionsProvider extends SoundDefinitionsProvider { + /** + * Creates a new instance of this data provider. + * + * @param output The {@linkplain PackOutput} instance provided by the data generator. + * @param modId The mod ID of the current mod. + * @param helper The existing file helper provided by the event you are initializing this provider in. + */ + public ModSoundDefinitionsProvider(PackOutput output, String modId, ExistingFileHelper helper) { + super(output, modId, helper); + } + + public SoundDefinition getSoundDefinition(String subTitle, SoundDefinition.Sound... sounds) { + return SoundDefinition.definition().subtitle(subTitle).with(sounds); + } + + @Override + public void registerSounds() { + add( + ModSoundRegister.FOX_MUSIC, + getSoundDefinition( + ModSoundRegister.getSubTitleTranslateKey("what_does_the_fox_say"), + sound(ModSoundRegister.RL_FOX_MUSIC, SoundDefinition.SoundType.SOUND) + ) + ); + + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/attributes/ModJukeboxSongs.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/attributes/ModJukeboxSongs.java new file mode 100644 index 0000000..c2f944a --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/attributes/ModJukeboxSongs.java @@ -0,0 +1,39 @@ +package com.r3944realms.leashedplayer.datagen.provider.attributes; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister; +import net.minecraft.Util; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.item.JukeboxSong; + +public class ModJukeboxSongs { + public static ResourceKey FOX_MUSIC = create("what_does_the_fox_say"); + + public static void bootstrap(BootstrapContext pContext) { + JukeboxSongBootstrap(pContext); + } + + public static void JukeboxSongBootstrap(BootstrapContext pContext) { + register(pContext, FOX_MUSIC, ModSoundRegister.FOX_MUSIC, 121, 15); + + } + + private static void register( + BootstrapContext pContext, ResourceKey pKey, Holder pSoundEvent, int pLengthInSeconds, int pComparatorOutput + ) { + pContext.register( + pKey, + new JukeboxSong(pSoundEvent, Component.translatable(Util.makeDescriptionId("jukebox_song", pKey.location())), (float)pLengthInSeconds, pComparatorOutput) + ); + } + private static ResourceKey create(String pName) { + return ResourceKey.create(Registries.JUKEBOX_SONG, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, pName)); + } + +} diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java b/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java index c04239c..e4970f1 100644 --- a/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java @@ -2,7 +2,6 @@ package com.r3944realms.leashedplayer.mixin.both; import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.commands.LeashCommand; -import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; @@ -12,7 +11,6 @@ import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Leashable; @@ -47,7 +45,7 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl private static final EntityDataAccessor Pl$LEASH_DATA = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); @Unique - @SuppressWarnings("WrongEntityDataParameterClass") + @SuppressWarnings("WrongEntityDataParameterClass") private static final EntityDataAccessor DATA_ENTITY_LEASH_LENGTH = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT); @SuppressWarnings("AddedMixinMembersNamePattern") @@ -203,12 +201,6 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl ILivingEntityExtension iEntityExtension = this;//获取设定值 float leashLengthSelf = iEntityExtension.getLeashLength(); leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE; - MobEffectInstance effect = this.getEffect(ModEffectRegister.NO_LEASH_EFFECT); - if(effect != null && effect.getDuration() != 0) { - if (entity instanceof LeashRopeArrow arrow) - arrow.setOwner(null); - this.dropLeash(true, !(entity instanceof LeashRopeArrow)); - } if (entity != null) { double breakDistanceTime = (entity instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1(); if(!isAlive() || !entity.isAlive() ||( distanceTo(entity) > Math.max(leashLength * breakDistanceTime, LeashCommand.MIN_VALUE * breakDistanceTime) && keepLeashTick == 0)){ diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderState.java b/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderState.java index 6ec3a39..11bec34 100644 --- a/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderState.java +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderState.java @@ -1,6 +1,7 @@ package com.r3944realms.leashedplayer.mixin.client; import com.r3944realms.leashedplayer.client.renders.PlayerLeashState; +import com.r3944realms.leashedplayer.client.renders.PlayerSlotItemLayerState; import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension; import net.minecraft.client.renderer.entity.state.PlayerRenderState; import org.jetbrains.annotations.Nullable; @@ -13,7 +14,8 @@ public class MixinPlayerRenderState implements IPlayerRenderStateExtension { @Unique @Nullable private PlayerLeashState playerLeashState; - + @Unique + private PlayerSlotItemLayerState playerSlotItemLayerState; @Override public @Nullable PlayerLeashState getPlayerLeashState() { return playerLeashState; @@ -24,4 +26,14 @@ public class MixinPlayerRenderState implements IPlayerRenderStateExtension { this.playerLeashState = playerRenderState; } + @Override + public PlayerSlotItemLayerState getPlayerSlotItemLayerState() { + return playerSlotItemLayerState; + } + + @Override + public void setPlayerSlotItemLayerState(PlayerSlotItemLayerState playerRenderState) { + this.playerSlotItemLayerState = playerRenderState; + } + } diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderer.java b/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderer.java index 6cf3dbe..2bf9f35 100644 --- a/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderer.java +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/client/MixinPlayerRenderer.java @@ -1,35 +1,20 @@ package com.r3944realms.leashedplayer.mixin.client; -import com.mojang.datafixers.util.Either; -import com.r3944realms.leashedplayer.LeashedPlayer; -import com.r3944realms.leashedplayer.client.renders.PlayerLeashState; -import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; -import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; +import com.r3944realms.leashedplayer.client.renders.LeashRendererUtil; +import com.r3944realms.leashedplayer.client.renders.PlayerSlotItemLayerState; import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension; import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension; -import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; -import net.minecraft.client.Minecraft; import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.state.PlayerRenderState; -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.Leashable; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; 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; -import java.util.List; -import java.util.UUID; - @Mixin(PlayerRenderer.class) public abstract class MixinPlayerRenderer extends LivingEntityRenderer implements IPlayerRendererExtension { public MixinPlayerRenderer(EntityRendererProvider.Context pContext, PlayerModel pModel, float pShadowRadius) { @@ -37,62 +22,9 @@ public abstract class MixinPlayerRenderer extends LivingEntityRenderer delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo; - PlayerLeashState playerLeashState = new PlayerLeashState(); - if (delayedLeashInfo != null) { - Minecraft mc = Minecraft.getInstance(); - ClientLevel level = mc.level; - if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) { - assert level != null; - playerLeashState.pos = delayedLeashInfo.right().get().getCenter(); - } else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) { - assert level != null; - Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get()); - if (playerByUUID != null) { - playerLeashState.pos = playerByUUID.position().add(0.0, playerByUUID.getEyeHeight() *0.7, 0); - } else { - double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1(); - double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * breakDistanceTime; - List entities = level.getEntities( - null, - new AABB( - abstractClientPlayer.getX() - MaxLeashLength * LeashedPlayer.M2(), - abstractClientPlayer.getY() - MaxLeashLength * LeashedPlayer.M2(), - abstractClientPlayer.getZ() - MaxLeashLength * LeashedPlayer.M2(), - abstractClientPlayer.getX() + MaxLeashLength * LeashedPlayer.M2(), - abstractClientPlayer.getY() + MaxLeashLength * LeashedPlayer.M2(), - abstractClientPlayer.getZ() + MaxLeashLength * LeashedPlayer.M2() - ) - ); - Entity holder = null; - for (Entity entity_ : entities) { - if (entity_.getUUID().equals(delayedLeashInfo.left().get())) { - holder = entity_; - break; - } - } - if (holder != null) { - if (holder instanceof LeashRopeArrow) { - playerLeashState.pos = holder.position().add(0.0, holder.getEyeHeight() *0.7, 0);//TODO: 待擴展Vec3 - } else playerLeashState.pos = holder.position().add(0.0, holder.getEyeHeight() *0.7, 0); - } else { - playerLeashState.pos = abstractClientPlayer.position(); - } - } - } - playerLeashState.o = new Vec3(abstractClientPlayer.xo, abstractClientPlayer.yo, abstractClientPlayer.zo); - playerLeashState.yRotO = abstractClientPlayer.yRotO; - playerLeashState.yRot = abstractClientPlayer.getYRot(); - playerLeashState.eyeHeight = abstractClientPlayer.getEyeHeight(); - iPlayerRenderStateExtension.setPlayerLeashState(playerLeashState); - } - } else { - iPlayerRenderStateExtension.setPlayerLeashState(null); - } - + LeashRendererUtil.createPlayerLeashState(abstractClientPlayer, (IPlayerRenderStateExtension) playerRenderState, partTicks); + ((IPlayerRenderStateExtension)playerRenderState).setPlayerSlotItemLayerState(new PlayerSlotItemLayerState(abstractClientPlayer)); } + } \ No newline at end of file diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/item/MixinArmorSlotMixin.java b/src/main/java/com/r3944realms/leashedplayer/mixin/item/MixinArmorSlotMixin.java new file mode 100644 index 0000000..ce9d211 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/item/MixinArmorSlotMixin.java @@ -0,0 +1,16 @@ +package com.r3944realms.leashedplayer.mixin.item; + +import net.minecraft.world.inventory.ArmorSlot; +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.CallbackInfoReturnable; + +@Mixin(ArmorSlot.class) +public class MixinArmorSlotMixin { + @Inject(method = "mayPlace", at = @At("RETURN"), cancellable = true) + public void allowItemEquipping(ItemStack stack, CallbackInfoReturnable cir) { + cir.setReturnValue(true); + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/registry/MixinJukeboxSongs.java b/src/main/java/com/r3944realms/leashedplayer/mixin/registry/MixinJukeboxSongs.java new file mode 100644 index 0000000..b49fc35 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/registry/MixinJukeboxSongs.java @@ -0,0 +1,18 @@ +package com.r3944realms.leashedplayer.mixin.registry; + +import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs; +import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.world.item.JukeboxSong; +import net.minecraft.world.item.JukeboxSongs; +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(JukeboxSongs.class) +public interface MixinJukeboxSongs { + @Inject(method = {"bootstrap"}, at = @At("TAIL")) + private static void bootstrap(BootstrapContext pContext, CallbackInfo ci) { + ModJukeboxSongs.JukeboxSongBootstrap(pContext); + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/server/MixinServerGamePacketListenerImpl.java b/src/main/java/com/r3944realms/leashedplayer/mixin/server/MixinServerGamePacketListenerImpl.java index a420a91..973ce56 100644 --- a/src/main/java/com/r3944realms/leashedplayer/mixin/server/MixinServerGamePacketListenerImpl.java +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/server/MixinServerGamePacketListenerImpl.java @@ -1,10 +1,8 @@ package com.r3944realms.leashedplayer.mixin.server; import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry; -import com.r3944realms.leashedplayer.content.gamerules.Server.DisablePlayerMoveCheck; import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; -import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.world.entity.Entity; @@ -58,10 +56,10 @@ public class MixinServerGamePacketListenerImpl { } } } - @SuppressWarnings("DiscouragedShift") - @Inject(method = {"handleMovePlayer"}, at = @At(value = "INVOKE",target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", ordinal = 0, shift = At.Shift.BEFORE), cancellable = true) - private void handleMovePlayer(ServerboundMovePlayerPacket pPacket, CallbackInfo ci) { - if(GameruleRegistry.getGameruleBoolValue(this.player.serverLevel(), DisablePlayerMoveCheck.ID)) - ci.cancel(); - } +// @SuppressWarnings("DiscouragedShift") +// @Inject(method = {"handleMovePlayer"}, at = @At(value = "INVOKE",target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", ordinal = 0, shift = At.Shift.BEFORE), cancellable = true) +// private void handleMovePlayer(ServerboundMovePlayerPacket pPacket, CallbackInfo ci) { +// if(GameruleRegistry.getGameruleBoolValue(this.player.serverLevel(), DisablePlayerMoveCheck.ID)) +// ci.cancel(); +// } } diff --git a/src/main/java/com/r3944realms/leashedplayer/modInterface/IPlayerRenderStateExtension.java b/src/main/java/com/r3944realms/leashedplayer/modInterface/IPlayerRenderStateExtension.java index a73c86d..9dd794b 100644 --- a/src/main/java/com/r3944realms/leashedplayer/modInterface/IPlayerRenderStateExtension.java +++ b/src/main/java/com/r3944realms/leashedplayer/modInterface/IPlayerRenderStateExtension.java @@ -1,8 +1,11 @@ package com.r3944realms.leashedplayer.modInterface; import com.r3944realms.leashedplayer.client.renders.PlayerLeashState; +import com.r3944realms.leashedplayer.client.renders.PlayerSlotItemLayerState; public interface IPlayerRenderStateExtension { PlayerLeashState getPlayerLeashState(); void setPlayerLeashState(PlayerLeashState playerRenderState); + PlayerSlotItemLayerState getPlayerSlotItemLayerState(); + void setPlayerSlotItemLayerState(PlayerSlotItemLayerState playerRenderState); } diff --git a/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java b/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java index efdcad4..bba3d67 100644 --- a/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java +++ b/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java @@ -1,6 +1,8 @@ package com.r3944realms.leashedplayer.modInterface; +import com.r3944realms.leashedplayer.content.commands.LeashCommand; import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers; +import com.r3944realms.leashedplayer.utils.Util; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; import net.minecraft.server.level.ServerLevel; @@ -10,6 +12,7 @@ import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.decoration.LeashFenceKnotEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -61,6 +64,72 @@ public interface PlayerLeashable extends Leashable { //这边覆写去掉了乘坐相关的逻辑,即乘坐状态下也可以正常被栓住,不影响其乘坐状态 } + static void legacyElasticRangeLeashBehaviour(Entity holderEntity, Entity restrainedEntity) { + float leashLength = LeashCommand.MIN_VALUE; + if (restrainedEntity instanceof ILivingEntityExtension iEntity) { + // 获取绳长 + float leashLengthFormValue = iEntity.getLeashLength(); + leashLength = leashLengthFormValue > LeashCommand.MIN_VALUE ? leashLengthFormValue : LeashCommand.MIN_VALUE; + } + + // 两者距离 + float distance = holderEntity.distanceTo(restrainedEntity); + Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity; + // 仅当距离大于绳长时施加拉力 + if (applyMovementEntity != null && distance > leashLength) { + MethodA(holderEntity, applyMovementEntity, distance, leashLength); + // 控制速度不要过快,避免偏激移动 + Util.MovementBrake(applyMovementEntity, entity -> { + Vec3 deltaMovement = entity.getDeltaMovement(); + entity.setDeltaMovement( + Math.min(Math.abs(deltaMovement.x), 1.0) * Math.signum(deltaMovement.x), + Math.min(Math.abs(deltaMovement.y), 1.0) * Math.signum(deltaMovement.y), + Math.min(Math.abs(deltaMovement.z), 1.0) * Math.signum(deltaMovement.z) + ); + entity.hurtMarked = true; + }); + } + } + private static void MethodA(Entity holderEntity, Entity applyMovementEntity, float distance, float leashLength) { + // 计算朝向持有者的拉力方向 + double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance; + double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance; + double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance; + + // 拉力大小,距离越远拉力越强,但施加一个最大限制 + double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力 + applyMovementEntity.setDeltaMovement( + applyMovementEntity.getDeltaMovement().add( + dX * pullStrength, + dY * pullStrength, + dZ * pullStrength + ) + ); + } + private static void MethodB(Entity holderEntity, Entity applyMovementEntity, float distance, float leashLength) { + // 计算朝向持有者的拉力方向 + double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance; + double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance; + + // 稳定点的目标高度 + double targetY = holderEntity.getY() + 1.0; // 根据需要调整目标高度 + double currentY = applyMovementEntity.getY(); + double heightDifference = targetY - currentY; + + // 控制垂直方向的拉力 + double dY = heightDifference > 0.5 ? 0.1 : (heightDifference < -0.5 ? -0.1 : 0); + + // 拉力大小,距离越远拉力越强,但施加一个最大限制 + double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力 + applyMovementEntity.setDeltaMovement( + applyMovementEntity.getDeltaMovement().add( + dX * pullStrength, + dY, + dZ * pullStrength + ) + ); + } + @Nullable static Entity getLeashDataEntity(@NotNull ServerPlayer serverPlayer , @NotNull ServerLevel serverLevel) { LeashData leashDataFromEntityData = ((PlayerLeashable) serverPlayer).getLeashDataFromEntityData(); diff --git a/src/main/java/com/r3944realms/leashedplayer/network/LeashedPlayerNetwork.java b/src/main/java/com/r3944realms/leashedplayer/network/LeashedPlayerNetwork.java index 344c529..00d00fc 100644 --- a/src/main/java/com/r3944realms/leashedplayer/network/LeashedPlayerNetwork.java +++ b/src/main/java/com/r3944realms/leashedplayer/network/LeashedPlayerNetwork.java @@ -2,6 +2,8 @@ package com.r3944realms.leashedplayer.network; import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.network.client.UpdatePlayerMovement; +import com.r3944realms.leashedplayer.network.server.DecreaseLeashRopeLength; +import com.r3944realms.leashedplayer.network.server.IncreaseLeashRopeLength; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; @@ -18,6 +20,16 @@ public class LeashedPlayerNetwork { UpdatePlayerMovement.STREAM_CODEC, UpdatePlayerMovement::handle ); + registrar.playToServer( + IncreaseLeashRopeLength.TYPE, + IncreaseLeashRopeLength.STREAM_CODEC, + IncreaseLeashRopeLength::handle + ); + registrar.playToServer( + DecreaseLeashRopeLength.TYPE, + DecreaseLeashRopeLength.STREAM_CODEC, + DecreaseLeashRopeLength::handle + ); } } diff --git a/src/main/java/com/r3944realms/leashedplayer/network/server/Code.java b/src/main/java/com/r3944realms/leashedplayer/network/server/Code.java new file mode 100644 index 0000000..00c8560 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/network/server/Code.java @@ -0,0 +1,8 @@ +package com.r3944realms.leashedplayer.network.server; + +public enum Code { + OTHER_ST, + OTHER_WE, + SELF; + public static final String LEASH_LENGTH_FAILED_SET = "leashedplayer.leash_rope.length.failed"; +} diff --git a/src/main/java/com/r3944realms/leashedplayer/network/server/DecreaseLeashRopeLength.java b/src/main/java/com/r3944realms/leashedplayer/network/server/DecreaseLeashRopeLength.java new file mode 100644 index 0000000..d101487 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/network/server/DecreaseLeashRopeLength.java @@ -0,0 +1,61 @@ +package com.r3944realms.leashedplayer.network.server; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; +import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public record DecreaseLeashRopeLength(Code code, String playerUUID) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID,"sub_leash_rope_length")); + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + NeoForgeStreamCodecs.enumCodec(Code.class), DecreaseLeashRopeLength::code, + ByteBufCodecs.STRING_UTF8, DecreaseLeashRopeLength::playerUUID, + DecreaseLeashRopeLength::new + ); + public static final String DECREASE_LEASH_ROPE_LENGTH = "leashedplayer.leash_rope.length.decrease", + DECREASE_SELF_LEASH_ROPE_LENGTH = DECREASE_LEASH_ROPE_LENGTH + ".self"; + + public void handle(IPayloadContext context) { + context.enqueueWork(() -> { + Player player = context.player(); + ServerLevel level = (ServerLevel) player.level(); + Player playerByUUID = level.getPlayerByUUID(UUID.fromString(playerUUID)); + if (playerByUUID != null) { + ILivingEntityExtension entityExtension = (ILivingEntityExtension) playerByUUID; + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) playerByUUID, level); + if ((leashDataEntity != null && code == Code.OTHER_ST && leashDataEntity == player ) || (leashDataEntity != null && code == Code.OTHER_ST)) { + float newValue = Math.max(Math.min(entityExtension.getLeashLength() - 1, LeashedPlayer.M4()), LeashedPlayer.M3()); + entityExtension.setLeashLength(newValue); + ((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(DECREASE_SELF_LEASH_ROPE_LENGTH, newValue), true); + ((ServerPlayer) player).sendSystemMessage(Component.translatable(DECREASE_LEASH_ROPE_LENGTH, playerByUUID.getDisplayName(), newValue), true); + } else if (code == Code.SELF) { + float newValue = Math.max(Math.min(entityExtension.getLeashLength() - 1, LeashedPlayer.M4()), LeashedPlayer.M3()); + entityExtension.setLeashLength(newValue); + ((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(DECREASE_SELF_LEASH_ROPE_LENGTH, newValue), true); + } else { + ((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true); + ((ServerPlayer) player).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true); + } + } + }); + } + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/network/server/IncreaseLeashRopeLength.java b/src/main/java/com/r3944realms/leashedplayer/network/server/IncreaseLeashRopeLength.java new file mode 100644 index 0000000..67191c5 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/network/server/IncreaseLeashRopeLength.java @@ -0,0 +1,63 @@ +package com.r3944realms.leashedplayer.network.server; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; +import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public record IncreaseLeashRopeLength(Code code, String playerUUID) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID,"add_leash_rope_length")); + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + NeoForgeStreamCodecs.enumCodec(Code.class), IncreaseLeashRopeLength::code, + ByteBufCodecs.STRING_UTF8, IncreaseLeashRopeLength::playerUUID, + IncreaseLeashRopeLength::new + ); + public static final String INCREASE_LEASH_ROPE_LENGTH = "leashedplayer.leash_rope.length.increase", + INCREASE_SELF_LEASH_ROPE_LENGTH = INCREASE_LEASH_ROPE_LENGTH + ".self"; + + + public void handle(IPayloadContext context) { + context.enqueueWork(() -> { + Player player = context.player(); + ServerLevel level = (ServerLevel) player.level(); + Player playerByUUID = level.getPlayerByUUID(UUID.fromString(playerUUID)); + if (playerByUUID != null) { + ILivingEntityExtension entityExtension = (ILivingEntityExtension) playerByUUID; + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) playerByUUID, level); + if ((leashDataEntity != null && code == Code.OTHER_ST && leashDataEntity == player ) || (leashDataEntity != null && code == Code.OTHER_ST)) { + float newValue = Math.max(Math.min(entityExtension.getLeashLength() + 1, LeashedPlayer.M4()), LeashedPlayer.M3()); + entityExtension.setLeashLength(newValue); + ((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(INCREASE_SELF_LEASH_ROPE_LENGTH, newValue), true); + ((ServerPlayer) player).sendSystemMessage(Component.translatable(INCREASE_LEASH_ROPE_LENGTH, playerByUUID.getDisplayName(), newValue), true); + } else if (code == Code.SELF) { + float newValue = Math.max(Math.min(entityExtension.getLeashLength() + 1, LeashedPlayer.M4()), LeashedPlayer.M3()); + entityExtension.setLeashLength(newValue); + ((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(INCREASE_SELF_LEASH_ROPE_LENGTH, newValue), true); + } else { + ((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true); + ((ServerPlayer) player).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true); + + } + } + }); + } + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/utils/Util.java b/src/main/java/com/r3944realms/leashedplayer/utils/Util.java index 39ef08a..7119d4d 100644 --- a/src/main/java/com/r3944realms/leashedplayer/utils/Util.java +++ b/src/main/java/com/r3944realms/leashedplayer/utils/Util.java @@ -2,9 +2,22 @@ package com.r3944realms.leashedplayer.utils; import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.gamerules.Gamerules; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.*; import net.neoforged.fml.loading.FMLPaths; +import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; import static com.r3944realms.leashedplayer.utils.Logger.logger; @@ -29,7 +42,7 @@ public class Util { if (!file.exists()) { boolean mkdirChildrenSuccess = file.mkdirs(); if (!mkdirChildrenSuccess) { - logger.error("failed to create " + child + " directory for +" + LeashedPlayer.MOD_ID); + logger.error("failed to create {} directory for +" + LeashedPlayer.MOD_ID, child); throw new RuntimeException("failed to create " + child + " directory for" +LeashedPlayer.MOD_ID); } } @@ -37,4 +50,87 @@ public class Util { } } } + public static void throwItemTowardsLook(Entity thrower, Item itemToThrow, float velocity, float inaccuracy) { + ItemEntity thrownItem = new ItemEntity( + thrower.level(), + thrower.getX(), + thrower.getEyeY() - 0.1, + thrower.getZ(), + new ItemStack(itemToThrow) + ); + thrownItem.setPickUpDelay(40); + Vec3 lookDirection = thrower.getLookAngle(); + + thrownItem.setDeltaMovement( + lookDirection.x * velocity + (thrower.level().random.nextGaussian() * 0.0075 * inaccuracy), + lookDirection.y * velocity + (thrower.level().random.nextGaussian() * 0.0075 * inaccuracy), + lookDirection.z * velocity + (thrower.level().random.nextGaussian() * 0.0075 * inaccuracy) + ); + + thrower.level().addFreshEntity(thrownItem); + } + + public static List getRefLookAtEntityHitResult(Entity looker, Level level, float distance, Function condition) { + Vec3 startPosition = looker.getEyePosition(); + Vec3 endPosition = looker.getLookAngle().normalize().scale(distance).add(startPosition); + BlockHitResult clip = level.clip(new ClipContext(startPosition, endPosition, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, looker)); + endPosition = clip.getLocation(); + AABB range = looker.getBoundingBox().expandTowards(endPosition.subtract(startPosition)); + List hits = new ArrayList<>(); + List entities = level.getEntities(looker, range, condition::apply); + for (Entity entity : entities) { + Vec3 vec3 = entity.getBoundingBox().clip(startPosition, endPosition).orElse(null); + if(vec3 != null) { + EntityHitResult entityHitResult = new EntityHitResult(entity, vec3); + hits.add(entityHitResult); + } + } + return hits; + } + + @Nullable + public static Entity getTheNearestEntityFromHitResultList(Entity looker, List hitResults) { + if(!hitResults.isEmpty()) { + hitResults.sort(Comparator.comparingDouble(e -> e.getLocation().distanceTo(looker.getEyePosition()))); + HitResult hitResult = hitResults.getFirst(); + if (hitResult instanceof EntityHitResult entityHitResult) + return entityHitResult.getEntity(); + else return null; + } + else return null; + } + /** + * 刹车( + * @param pEntity 刹车的实体 + * @param pMaxX X方向的最大动量 + * @param pMaxY Y方向的最大动量 + * @param pMaxZ Z方向的最大动量 + */ + public static void MovementBrake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) { + Vec3 deltaMovement = pEntity.getDeltaMovement(); + double dX = Math.abs(deltaMovement.x) > pMaxX ? 0 : deltaMovement.x; + double dY = Math.abs(deltaMovement.y) > pMaxY ? 0 : deltaMovement.y; + double dZ = Math.abs(deltaMovement.z) > pMaxZ ? 0 : deltaMovement.z; + pEntity.setDeltaMovement(dX, dY,dZ); + pEntity.hurtMarked = true; + } + /** + * 刹车( + * @param pEntity 刹车的实体 + * @param pOpt 自定义规则 + */ + public static void MovementBrake(Entity pEntity, @javax.annotation.Nullable Consumer pOpt) { + Consumer consumer = pOpt; + if(pOpt == null) { + consumer = entity -> { + Vec3 deltaMovement = entity.getDeltaMovement(); + double dX = Math.abs(deltaMovement.x) > 1 ? 0 : deltaMovement.x; + double dY = Math.abs(deltaMovement.y) > 1 ? 0 : deltaMovement.y; + double dZ = Math.abs(deltaMovement.z) > 1 ? 0 : deltaMovement.z; + entity.setDeltaMovement(dX, dY,dZ); + entity.hurtMarked = true; + }; + } + consumer.accept(pEntity); + } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 6026431..a7a548b 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -16,6 +16,8 @@ public net.minecraft.world.entity.Leashable$LeashData delayedLeashHolderId # del protected net.minecraft.world.entity.projectile.AbstractArrow life # life #protect -> public public net.minecraft.world.effect.MobEffect (Lnet/minecraft/world/effect/MobEffectCategory;I)V # MobEffect +#packge-private -> public +public net.minecraft.world.inventory.ArmorSlot #ArmorSlot #private -> protected protected net.minecraft.world.entity.projectile.Projectile cachedOwner # cachedOwner protected net.minecraft.world.entity.projectile.Projectile ownerUUID # ownerUUID diff --git a/src/main/resources/assets/leashedplayer/models/item/neoforge.json b/src/main/resources/assets/leashedplayer/models/item/neoforge.json new file mode 100644 index 0000000..528ab26 --- /dev/null +++ b/src/main/resources/assets/leashedplayer/models/item/neoforge.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "leashedplayer:item/neoforge" + }, + "display": { + "head": { + "translation": [0, 0, -7.5], + "scale": [1.25, 1.25, 1.25] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/leashedplayer/sounds/music/what_does_the_fox_say.ogg b/src/main/resources/assets/leashedplayer/sounds/music/what_does_the_fox_say.ogg new file mode 100644 index 0000000..3029305 Binary files /dev/null and b/src/main/resources/assets/leashedplayer/sounds/music/what_does_the_fox_say.ogg differ diff --git a/src/main/resources/assets/leashedplayer/textures/item/neoforge.png b/src/main/resources/assets/leashedplayer/textures/item/neoforge.png new file mode 100644 index 0000000..9a58fc6 Binary files /dev/null and b/src/main/resources/assets/leashedplayer/textures/item/neoforge.png differ diff --git a/src/main/resources/assets/leashedplayer/textures/item/tipped_leash_rope_arrow_base.png b/src/main/resources/assets/leashedplayer/textures/item/tipped_leash_rope_arrow_base.png new file mode 100644 index 0000000..374c118 Binary files /dev/null and b/src/main/resources/assets/leashedplayer/textures/item/tipped_leash_rope_arrow_base.png differ diff --git a/src/main/resources/leashedplayer.mixins.json b/src/main/resources/leashedplayer.mixins.json index 5d48b17..f4dca52 100644 --- a/src/main/resources/leashedplayer.mixins.json +++ b/src/main/resources/leashedplayer.mixins.json @@ -4,7 +4,9 @@ "both.MixinEntity", "both.MixinLivingEntity", "both.MixinPlayer", + "item.MixinArmorSlotMixin", "item.MixinLeadItem", + "registry.MixinJukeboxSongs", "registry.MixinPaintingVariants", "server.MixinServerGamePacketListenerImpl" ],