Compare commits

..

No commits in common. "c46f753aee200a01d3222fa0a5a1d462fac2dd97" and "a0e2b95167d87a3eea1038ea9862d02958f5cefd" have entirely different histories.

124 changed files with 819 additions and 3125 deletions

View File

@ -1,4 +1,4 @@
# 版本 1.21.3 0.0.3.9.9 # 版本 0.0.3.9.1 提前介绍c[最终版本对于0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
## 简介 ## 简介
现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧( 现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧(
@ -17,9 +17,6 @@
## 新物品 和 实体 ## 新物品 和 实体
### 拴绳箭 [有普通和荧光两种箭矢] ### 拴绳箭 [有普通和荧光两种箭矢]
获得飞一样的感觉(操作不当可能会摔死 获得飞一样的感觉(操作不当可能会摔死
+ 拴绳箭可以拴其它可拴LivingEntity了
### 紫水晶剪刀
剪断拴绳链接,在发射器里可使用
#### 射中实体时会将射击者拴绳绑定在改实体上该实体父类必须是有LivingEntity类型同时拴绳箭会以普通的箭矢掉落 #### 射中实体时会将射击者拴绳绑定在改实体上该实体父类必须是有LivingEntity类型同时拴绳箭会以普通的箭矢掉落
#### 射中栅栏时,会自动将玩家拴在上面 ,同时拴绳箭会以普通的箭矢掉落 #### 射中栅栏时,会自动将玩家拴在上面 ,同时拴绳箭会以普通的箭矢掉落
#### 在地面上的箭可以通过按Shift靠近来捡起如果捡起实体为发射箭矢玩家则直接获取拴绳箭矢如果捡起者为非发射者则成为发送者的拴绳持有者并获得普通箭矢 #### 在地面上的箭可以通过按Shift靠近来捡起如果捡起实体为发射箭矢玩家则直接获取拴绳箭矢如果捡起者为非发射者则成为发送者的拴绳持有者并获得普通箭矢
@ -54,4 +51,4 @@
* `LP.KeepLeashNotDropTime` - 此规则决定,当拴绳关系创建时一段时间里,即是距离已经达到了断裂距离,也保持其不断裂 [默认值: 240ticks ,可设置范围[80, 1200]ticks] * `LP.KeepLeashNotDropTime` - 此规则决定,当拴绳关系创建时一段时间里,即是距离已经达到了断裂距离,也保持其不断裂 [默认值: 240ticks ,可设置范围[80, 1200]ticks]
* `LP.DisableMoveCheck` - 此规则启用将会禁止服务器对玩家进行速度过快修正 [默认值: True]

View File

@ -3,7 +3,7 @@ plugins {
id 'eclipse' id 'eclipse'
id 'idea' id 'idea'
id 'maven-publish' id 'maven-publish'
id 'net.neoforged.gradle.userdev' version '7.0.180' id 'net.neoforged.gradle.userdev' version '7.0.145'
} }
tasks.named('wrapper', Wrapper).configure { tasks.named('wrapper', Wrapper).configure {
@ -25,10 +25,11 @@ repositories {
base { base {
archivesName = mod_id archivesName = mod_id
} }
// Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21. // Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21.
java.toolchain.languageVersion = JavaLanguageVersion.of(21) java.toolchain.languageVersion = JavaLanguageVersion.of(21)
minecraft.accessTransformers.file rootProject.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 //minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager
// Default run configurations. // Default run configurations.
@ -53,12 +54,12 @@ runs {
client { client {
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces. // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
} }
server { server {
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
programArgument '--nogui'
} }
// This run config launches GameTestServer and runs all registered gametests, then exits. // This run config launches GameTestServer and runs all registered gametests, then exits.
@ -71,9 +72,9 @@ runs {
data { data {
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// workingDirectory project.file('run-data') // 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. // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
arguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
} }
} }
@ -154,7 +155,7 @@ publishing {
} }
repositories { repositories {
maven { maven {
url = "file://${project.projectDir}/repo" url "file://${project.projectDir}/repo"
} }
} }
} }
@ -162,7 +163,9 @@ publishing {
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation 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 no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
idea { idea {
module { module {

View File

@ -2,34 +2,25 @@
org.gradle.jvmargs=-Xmx8G org.gradle.jvmargs=-Xmx8G
org.gradle.daemon=false org.gradle.daemon=false
org.gradle.debug=false org.gradle.debug=false
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=false
#read more on this at https://github.com/neoforged/ModDevGradle?tab=readme-ov-file#better-minecraft-parameter-names--javadoc-parchment
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
parchment_minecraft_version=1.21
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 #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 # you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
neogradle.subsystems.parchment.minecraftVersion=1.21.3 neogradle.subsystems.parchment.minecraftVersion=1.21
neogradle.subsystems.parchment.mappingsVersion=2024.12.07 neogradle.subsystems.parchment.mappingsVersion=2024.07.28
# Environment Properties # Environment Properties
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge # 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 # The Minecraft version must agree with the Neo version to get a valid artifact
minecraft_version=1.21.3 minecraft_version=1.21
# The Minecraft version range can use any release version of Minecraft as bounds. # 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 # Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
# as they do not follow standard versioning conventions. # as they do not follow standard versioning conventions.
minecraft_version_range=[1.21.3] minecraft_version_range=[1.21,1.22)
enable_accesstransformers=true
# The Neo version must agree with the Minecraft version to get a valid artifact # The Neo version must agree with the Minecraft version to get a valid artifact
neo_version=21.3.58 neo_version=21.0.157
# The Neo version range can use any version of Neo as bounds # The Neo version range can use any version of Neo as bounds
neo_version_range=[21.3.58,) neo_version_range=[21.0.0-beta,)
# The loader version range can only use the major version of FML as bounds # The loader version range can only use the major version of FML as bounds
loader_version_range=[1,) loader_version_range=[4,)
## Mod Properties ## Mod Properties
@ -41,7 +32,7 @@ mod_name=Leashed Player
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT mod_license=MIT
# The mod version. See https://semver.org/ # The mod version. See https://semver.org/
mod_version=1.21.3_0.0.3.9.9 mod_version=0.0.3.9.2
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # 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. # This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html # See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View File

@ -1,2 +0,0 @@
#This file is generated by updateDaemonJvm
toolchainVersion=21

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.12-bin.zip distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.9-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@ -7,5 +7,5 @@ pluginManagement {
} }
plugins { plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0' id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
} }

View File

@ -1,5 +1,4 @@
// 1.21.3 2025-01-27T17:55:02.7810616 Item Models: leashedplayer // 1.21 2024-10-23T13:15:06.1102778 Item Models: leashedplayer
766c487fbf0c59e9045eeaf81daf583eb679b0e1 assets/leashedplayer/models/item/amethyst_shears.json
5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json 5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json
845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json 845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json
5bd1f9f28b91005c587f1c38fb77cd19b59495e3 assets/leashedplayer/models/item/bow_lra_pulling_2.json 5bd1f9f28b91005c587f1c38fb77cd19b59495e3 assets/leashedplayer/models/item/bow_lra_pulling_2.json
@ -7,4 +6,3 @@
bb0d76077719c83c8a8bd4346a24ea1766175125 assets/leashedplayer/models/item/fabric.json bb0d76077719c83c8a8bd4346a24ea1766175125 assets/leashedplayer/models/item/fabric.json
114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json 114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json
c4748995a5fe190d20e3bd16f4b2244164ec0f83 assets/leashedplayer/models/item/spectral_leash_rope_arrow.json c4748995a5fe190d20e3bd16f4b2244164ec0f83 assets/leashedplayer/models/item/spectral_leash_rope_arrow.json
c4ef06f3162fe85f152c5b4a25ecdb4c2c56f945 assets/leashedplayer/models/item/tipped_leash_rope_arrow.json

View File

@ -1,3 +1,2 @@
// 1.21.3 2025-01-27T17:42:59.0511618 Registries // 1.21 2024-10-23T13:15:06.1082841 Registries
f2536789df7f06362718a59ba4a96890e2f9b8aa data/leashedplayer/jukebox_song/what_does_the_fox_say.json 6f79a674215db9f9d2820b1c7f052c60ce729fee data/leashedplayer/painting_variant/group_photo.json
84106976f4f71012fc5bd1784303a0d135623c77 data/leashedplayer/painting_variant/group_photo.json

View File

@ -1,8 +1,2 @@
// 1.21.3 2025-01-27T21:03:10.3134854 Tags for minecraft:item mod id leashedplayer // 1.21 2024-10-23T13:15:06.1012494 Tags for minecraft:item mod id leashedplayer
84707301f1fe2490a899deb51302d413cfff5a89 data/c/tags/item/tools/shear.json 36c1cccc1dfa448620c4e9cbc4a7d73986ff9e47 data/minecraft/tags/item/arrows.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

View File

@ -1,2 +1,2 @@
// 1.21.3 2025-01-27T21:03:10.3134854 Languages: en_us for mod: leashedplayer // 1.21 2024-10-23T14:43:16.8619078 Languages: en_us for mod: leashedplayer
2c7f061dfc276db13135adce15c68cfc145ccf37 assets/leashedplayer/lang/en_us.json 4dc2ca922a540c7133a4a6867dfcd8bfec5a1db4 assets/leashedplayer/lang/en_us.json

View File

@ -1 +1 @@
// 1.21.3 2024-10-27T23:14:21.0429914 Tags for minecraft:block mod id leashedplayer // 1.21 2024-10-23T13:15:06.1052755 Tags for minecraft:block mod id leashedplayer

View File

@ -1,2 +0,0 @@
// 1.21.3 2025-01-27T17:42:59.0511618 Sound Definitions
81f1cc9f404c2670bf7cc679107177ffb0b48c77 assets/leashedplayer/sounds.json

View File

@ -1,2 +1,2 @@
// 1.21.3 2024-10-27T23:14:21.0429914 Tags for minecraft:painting_variant mod id leashedplayer // 1.21 2024-10-23T13:15:06.1052755 Tags for minecraft:painting_variant mod id leashedplayer
e081a053d7c2f2d3238cf38436185ef23d234505 data/minecraft/tags/painting_variant/placeable.json e081a053d7c2f2d3238cf38436185ef23d234505 data/minecraft/tags/painting_variant/placeable.json

View File

@ -1,2 +1,2 @@
// 1.21.3 2025-01-26T22:13:41.4090272 Languages: lzh for mod: leashedplayer // 1.21 2024-10-23T13:15:06.1042677 Languages: lzh for mod: leashedplayer
7536eb6d1c69695c06ebb9da5b57a391174b02cb assets/leashedplayer/lang/lzh.json bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f assets/leashedplayer/lang/lzh.json

View File

@ -0,0 +1,7 @@
// 1.21 2024-10-23T13:15:06.1092763 Recipes
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
974d74538b3e172946f2e169036b453b6eb6bc0a data/leashedplayer/recipe/leash_rope_arrow.json
c0e05f359296d3e28573fa1b205ac44736376622 data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_glowstone_dust.json
131fcbef603bfde7204d8e1ad15e4544696926bf data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_leash_rope_arrow.json
bb5909aa91d878c8f0ef9999881cfe89532509dd data/minecraft/recipe/spectral_leash_rope_arrow_with_glowstone_dust.json
a1381da885fbedec01243c78afbb0a50ca803ee4 data/minecraft/recipe/spectral_leash_rope_arrow_with_leash_rope_arrow.json

View File

@ -1,2 +1,2 @@
// 1.21.3 2025-01-27T21:03:10.3134854 Languages: zh_cn for mod: leashedplayer // 1.21 2024-10-23T14:43:16.860909 Languages: zh_cn for mod: leashedplayer
f7bcf89907a8ca5f575e4b519d53cd0628bb1e6b assets/leashedplayer/lang/zh_cn.json 35bc6c3001138c5306d1ee9d55ef3dfbfd417e08 assets/leashedplayer/lang/zh_cn.json

View File

@ -1,11 +0,0 @@
// 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
af1f65626735f1001426e0984217139e15649725 data/leashedplayer/recipe/amethyst_shears.json
db45be6e2bbddc49e60a6c1b12e2ef44afad30d8 data/leashedplayer/recipe/leash_rope_arrow.json
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

View File

@ -1,4 +1,4 @@
// 1.21.3 2025-01-26T22:13:41.4090272 Advancements // 1.21 2024-10-23T14:19:10.2054361 Advancements
4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json 4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json
f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json
bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json
@ -6,7 +6,4 @@ bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_a
25f6b476b194a27c0fe0e75d74ac3a7ff4054789 data/leashedplayer/advancement/leashed_self.json 25f6b476b194a27c0fe0e75d74ac3a7ff4054789 data/leashedplayer/advancement/leashed_self.json
a69a455855fb6dd8a8ac131a55099de5de45d7c4 data/leashedplayer/advancement/leash_arrow.json a69a455855fb6dd8a8ac131a55099de5de45d7c4 data/leashedplayer/advancement/leash_arrow.json
133f844ffafd37b9ba57cafa96350f035cac57f9 data/leashedplayer/advancement/leash_start.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 4b0bcf6b372f52e954edcef37a6b04435ec2b4e8 data/leashedplayer/advancement/no_leash.json
72f40eb5816d1e8c296bdf4df6b599c15ba7e7e9 data/leashedplayer/advancement/tipped_leash_arrow.json

View File

@ -1,2 +1,2 @@
// 1.21.3 2025-01-27T21:03:10.3134854 Languages: zh_tw for mod: leashedplayer // 1.21 2024-10-23T14:43:16.8589078 Languages: zh_tw for mod: leashedplayer
c23825af72a73bc54b72ad3817acb5a03d299375 assets/leashedplayer/lang/zh_tw.json c6df14a1f53a3e892ebc6b396b552ff27f1a7580 assets/leashedplayer/lang/zh_tw.json

View File

@ -9,55 +9,32 @@
"advancement.leashedplayer.leash_arrow.desc": "Maybe you can using it to shoot some mob?", "advancement.leashedplayer.leash_arrow.desc": "Maybe you can using it to shoot some mob?",
"advancement.leashedplayer.leash_start": "The Power of Traction", "advancement.leashedplayer.leash_start": "The Power of Traction",
"advancement.leashedplayer.leash_start.desc": "Journey to becoming a Leash Expert", "advancement.leashedplayer.leash_start.desc": "Journey to becoming a Leash Expert",
"advancement.leashedplayer.leash_terminator": "The Lead Terminator",
"advancement.leashedplayer.leash_terminator.desc": "I am Lead Terminator!",
"advancement.leashedplayer.leashed_friend": "Be bound by Rope", "advancement.leashedplayer.leashed_friend": "Be bound by Rope",
"advancement.leashedplayer.leashed_friend.desc": "Be Bond by player with lead", "advancement.leashedplayer.leashed_friend.desc": "Be Bond by player with lead",
"advancement.leashedplayer.leashed_self": "Stable Connection", "advancement.leashedplayer.leashed_self": "Stable Connection",
"advancement.leashedplayer.leashed_self.desc": "“Restrain oneself with a rope", "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": "Don't tie me up",
"advancement.leashedplayer.no_leash.desc": "You cannot be leashed by ANY", "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", "creativetab.leashedplayer.leashedplayer_tab": "Leashed Player",
"effect.leashedplayer.no_leash": "No Leash", "effect.leashedplayer.no_leash": "No Leash",
"entity.leashedplayer.kid_player": "Kid",
"entity.leashedplayer.leash_rope_arrow": "Leash Rope Arrow", "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", "entity.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent", "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.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": "Keep leash alive Time",
"gamerule.LP.KeepLeashNotDropTime.description": "The time of Keep new leash which has far distance alive (Tick)", "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": "Teleport leashed player with player holder",
"gamerule.LP.TeleportWithLeashedPlayers.description": "Holder will teleport with their leashed players ", "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 launchers behavior.",
"item.leash_rope_arrow.description": "Arrows with ropes attached?", "item.leash_rope_arrow.description": "Arrows with ropes attached?",
"item.leashedplayer.amethyst_shears": "Amethyst Shears",
"item.leashedplayer.fabric": "Fabric", "item.leashedplayer.fabric": "Fabric",
"item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow", "item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
"item.leashedplayer.neoforge": "NeoForge",
"item.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow", "item.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow",
"item.minecraft.lingering_potion.effect.no_leash": "Splash No Leash Potion", "item.minecraft.lingering_potion.effect.no_leash": "Splash No Leash Potion",
"item.minecraft.potion.effect.no_leash": "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.splash_potion.effect.no_leash": "Splash No Leash Potion",
"item.minecraft.tipped_arrow.effect.no_leash": "Arrow of No Leash", "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": "%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.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", "leashedplayer.command.leash.message.leash.data.null": "%1$s has no LeashDataEntity",
@ -73,16 +50,6 @@
"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.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.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.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.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!"
} }

View File

@ -1,3 +1 @@
{ {}
"entity.leashedplayer.kid_player": "幼"
}

View File

@ -9,55 +9,32 @@
"advancement.leashedplayer.leash_arrow.desc": "也许可以用它来发射生物?", "advancement.leashedplayer.leash_arrow.desc": "也许可以用它来发射生物?",
"advancement.leashedplayer.leash_start": "牵引之力", "advancement.leashedplayer.leash_start": "牵引之力",
"advancement.leashedplayer.leash_start.desc": "拴绳大师之路", "advancement.leashedplayer.leash_start.desc": "拴绳大师之路",
"advancement.leashedplayer.leash_terminator": "拴绳终结者",
"advancement.leashedplayer.leash_terminator.desc": "我來终结拴绳者!",
"advancement.leashedplayer.leashed_friend": "拴绳链接", "advancement.leashedplayer.leashed_friend": "拴绳链接",
"advancement.leashedplayer.leashed_friend.desc": "被玩家用拴绳链接", "advancement.leashedplayer.leashed_friend.desc": "被玩家用拴绳链接",
"advancement.leashedplayer.leashed_self": "稳固联结", "advancement.leashedplayer.leashed_self": "稳固联结",
"advancement.leashedplayer.leashed_self.desc": "用拴绳拴住自己", "advancement.leashedplayer.leashed_self.desc": "用拴绳拴住自己",
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
"advancement.leashedplayer.neo_fox.desc": "似乎可以戴头上",
"advancement.leashedplayer.no_leash": "勿拴我", "advancement.leashedplayer.no_leash": "勿拴我",
"advancement.leashedplayer.no_leash.desc": "你不会被任何东西拴住", "advancement.leashedplayer.no_leash.desc": "你不会被任何东西拴住",
"advancement.leashedplayer.tipped_leash_arrow": "神说要有更多箭矢",
"advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅满目啊",
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家", "creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
"effect.leashedplayer.no_leash": "禁拴", "effect.leashedplayer.no_leash": "禁拴",
"entity.leashedplayer.kid_player": "小孩",
"entity.leashedplayer.leash_rope_arrow": "拴绳箭", "entity.leashedplayer.leash_rope_arrow": "拴绳箭",
"entity.leashedplayer.nestle_rope_arrow": "贴贴拴绳箭",
"entity.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭", "entity.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它",
"gamerule.LP.DisablePlayerMoveCheck": "禁止检查玩家移动",
"gamerule.LP.DisablePlayerMoveCheck.description": "禁止检查玩家移动并且纠正它",
"gamerule.LP.KeepLeashNotDropTime": "保持拴绳不掉落的时间", "gamerule.LP.KeepLeashNotDropTime": "保持拴绳不掉落的时间",
"gamerule.LP.KeepLeashNotDropTime.description": "当距离过远时,保持新建拴绳不掉落的时间 (刻)", "gamerule.LP.KeepLeashNotDropTime.description": "当距离过远时,保持新建拴绳不掉落的时间 (刻)",
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者传送", "gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者传送",
"gamerule.LP.TeleportWithLeashedPlayers.description": "传送时将被拴玩家与持有者一起传送", "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.leash_rope_arrow.description": "带有拴绳的箭矢?",
"item.leashedplayer.amethyst_shears": "紫水晶剪刀",
"item.leashedplayer.fabric": "Fabric", "item.leashedplayer.fabric": "Fabric",
"item.leashedplayer.leash_rope_arrow": "拴绳箭", "item.leashedplayer.leash_rope_arrow": "拴绳箭",
"item.leashedplayer.neoforge": "NeoForge",
"item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭", "item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
"item.minecraft.lingering_potion.effect.no_leash": "滞留型禁拴药水", "item.minecraft.lingering_potion.effect.no_leash": "滞留型禁拴药水",
"item.minecraft.potion.effect.no_leash": "禁拴药水", "item.minecraft.potion.effect.no_leash": "禁拴药水",
"item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水", "item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水",
"item.minecraft.tipped_arrow.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": "%1$s的拴绳数据拴绳持有者实体%2$s现在已清除",
"leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴绳数据可清除", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴绳数据可清除",
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴绳数据实体", "leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴绳数据实体",
@ -73,16 +50,6 @@
"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.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.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.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.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": "大楚兴~ 陈胜王~~"
} }

View File

@ -9,55 +9,32 @@
"advancement.leashedplayer.leash_arrow.desc": "也許可以用它發射生物?", "advancement.leashedplayer.leash_arrow.desc": "也許可以用它發射生物?",
"advancement.leashedplayer.leash_start": "牽引之力", "advancement.leashedplayer.leash_start": "牽引之力",
"advancement.leashedplayer.leash_start.desc": "拴繩大師之路", "advancement.leashedplayer.leash_start.desc": "拴繩大師之路",
"advancement.leashedplayer.leash_terminator": "拴繩終結者",
"advancement.leashedplayer.leash_terminator.desc": "吾將終結拴繩!",
"advancement.leashedplayer.leashed_friend": "拴繩鏈接", "advancement.leashedplayer.leashed_friend": "拴繩鏈接",
"advancement.leashedplayer.leashed_friend.desc": "被玩家用拴繩鏈接", "advancement.leashedplayer.leashed_friend.desc": "被玩家用拴繩鏈接",
"advancement.leashedplayer.leashed_self": "穩固聯結", "advancement.leashedplayer.leashed_self": "穩固聯結",
"advancement.leashedplayer.leashed_self.desc": "用栓繩拴住自己", "advancement.leashedplayer.leashed_self.desc": "用栓繩拴住自己",
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
"advancement.leashedplayer.neo_fox.desc": "似乎可以戴著",
"advancement.leashedplayer.no_leash": "請恁勿拴唔", "advancement.leashedplayer.no_leash": "請恁勿拴唔",
"advancement.leashedplayer.no_leash.desc": "恁不會被任何拴住", "advancement.leashedplayer.no_leash.desc": "恁不會被任何拴住",
"advancement.leashedplayer.tipped_leash_arrow": "神說要有更多箭矢",
"advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅滿目啊",
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家", "creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
"effect.leashedplayer.no_leash": "禁拴", "effect.leashedplayer.no_leash": "禁拴",
"entity.leashedplayer.kid_player": "小孩",
"entity.leashedplayer.leash_rope_arrow": "拴繩箭", "entity.leashedplayer.leash_rope_arrow": "拴繩箭",
"entity.leashedplayer.nestle_rope_arrow": "貼貼拴繩箭",
"entity.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭", "entity.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它",
"gamerule.LP.DisablePlayerMoveCheck": "禁止檢查玩家移動",
"gamerule.LP.DisablePlayerMoveCheck.description": "禁止檢查玩家移動並糾正他它",
"gamerule.LP.KeepLeashNotDropTime": "保持其不掉落的時間", "gamerule.LP.KeepLeashNotDropTime": "保持其不掉落的時間",
"gamerule.LP.KeepLeashNotDropTime.description": "儅距離過遠時,保持其不掉落的時間(刻)", "gamerule.LP.KeepLeashNotDropTime.description": "儅距離過遠時,保持其不掉落的時間(刻)",
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者傳送", "gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者傳送",
"gamerule.LP.TeleportWithLeashedPlayers.description": "將被拴玩家將隨持有者一起傳送", "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.leash_rope_arrow.description": "帶有拴繩的箭矢?",
"item.leashedplayer.amethyst_shears": "紫水晶剪刀",
"item.leashedplayer.fabric": "Fabric", "item.leashedplayer.fabric": "Fabric",
"item.leashedplayer.leash_rope_arrow": "拴繩箭", "item.leashedplayer.leash_rope_arrow": "拴繩箭",
"item.leashedplayer.neoforge": "NeoForge",
"item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭", "item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
"item.minecraft.lingering_potion.effect.no_leash": "滯留型禁拴藥水", "item.minecraft.lingering_potion.effect.no_leash": "滯留型禁拴藥水",
"item.minecraft.potion.effect.no_leash": "禁拴藥水", "item.minecraft.potion.effect.no_leash": "禁拴藥水",
"item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水", "item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水",
"item.minecraft.tipped_arrow.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": "%1$s的拴繩數據拴繩持有者實體%2$s現在已清除",
"leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴繩數據實體可被清除", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴繩數據實體可被清除",
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴繩數據實體", "leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴繩數據實體",
@ -73,16 +50,6 @@
"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.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.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.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.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": "大楚興~ 陳勝王~~"
} }

View File

@ -1,6 +0,0 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "leashedplayer:item/amethyst_shears"
}
}

View File

@ -1,7 +0,0 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "minecraft:item/tipped_arrow_head",
"layer1": "leashedplayer:item/tipped_leash_rope_arrow_base"
}
}

View File

@ -1,8 +0,0 @@
{
"music/what_does_the_fox_say": {
"sounds": [
"leashedplayer:music/what_does_the_fox_say"
],
"subtitle": "sound.leashedplayer.subtitle.what_does_the_fox_say"
}
}

View File

@ -1,5 +0,0 @@
{
"values": [
"leashedplayer:amethyst_shears"
]
}

View File

@ -1,34 +0,0 @@
{
"parent": "leashedplayer:leash_start",
"criteria": {
"has_amethyst_shears": {
"conditions": {
"items": [
{
"items": "leashedplayer:amethyst_shears"
}
]
},
"trigger": "minecraft:inventory_changed"
}
},
"display": {
"description": {
"translate": "advancement.leashedplayer.leash_terminator.desc"
},
"hidden": true,
"icon": {
"count": 1,
"id": "leashedplayer:amethyst_shears"
},
"title": {
"translate": "advancement.leashedplayer.leash_terminator"
}
},
"requirements": [
[
"has_amethyst_shears"
]
],
"sends_telemetry_event": true
}

View File

@ -1,36 +0,0 @@
{
"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
}

View File

@ -1,32 +0,0 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_amethyst_shard": {
"conditions": {
"items": [
{
"items": "minecraft:amethyst_shard"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "leashedplayer:amethyst_shears"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_amethyst_shard"
]
],
"rewards": {
"recipes": [
"leashedplayer:amethyst_shears"
]
}
}

View File

@ -1,35 +0,0 @@
{
"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
}

View File

@ -1,8 +0,0 @@
{
"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"
}

View File

@ -1,11 +1,5 @@
{ {
"asset_id": "leashedplayer:group_photo", "asset_id": "leashedplayer:group_photo",
"author": {
"translate": "painting.leashedplayer.group_photo.author"
},
"height": 3, "height": 3,
"title": {
"translate": "painting.leashedplayer.group_photo.title"
},
"width": 4 "width": 4
} }

View File

@ -1,16 +0,0 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"key": {
"#": "minecraft:amethyst_shard",
"%": "minecraft:stick"
},
"pattern": [
"#%",
"%#"
],
"result": {
"count": 1,
"id": "leashedplayer:amethyst_shears"
}
}

View File

@ -2,8 +2,12 @@
"type": "minecraft:crafting_shapeless", "type": "minecraft:crafting_shapeless",
"category": "misc", "category": "misc",
"ingredients": [ "ingredients": [
"minecraft:lead", {
"minecraft:arrow" "item": "minecraft:lead"
},
{
"item": "minecraft:arrow"
}
], ],
"result": { "result": {
"count": 1, "count": 1,

View File

@ -23,7 +23,7 @@
}, },
"has_the_recipe": { "has_the_recipe": {
"conditions": { "conditions": {
"recipe": "minecraft:leash_rope_arrow_shape" "recipe": "minecraft:spectral_leash_rope_arrow_with_glowstone_dust"
}, },
"trigger": "minecraft:recipe_unlocked" "trigger": "minecraft:recipe_unlocked"
} }
@ -37,7 +37,7 @@
], ],
"rewards": { "rewards": {
"recipes": [ "recipes": [
"minecraft:leash_rope_arrow_shape" "minecraft:spectral_leash_rope_arrow_with_glowstone_dust"
] ]
} }
} }

View File

@ -23,7 +23,7 @@
}, },
"has_the_recipe": { "has_the_recipe": {
"conditions": { "conditions": {
"recipe": "leashedplayer:spectral_leash_rope_arrow" "recipe": "minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow"
}, },
"trigger": "minecraft:recipe_unlocked" "trigger": "minecraft:recipe_unlocked"
} }
@ -37,7 +37,7 @@
], ],
"rewards": { "rewards": {
"recipes": [ "recipes": [
"leashedplayer:spectral_leash_rope_arrow" "minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow"
] ]
} }
} }

View File

@ -2,8 +2,12 @@
"type": "minecraft:crafting_shaped", "type": "minecraft:crafting_shaped",
"category": "misc", "category": "misc",
"key": { "key": {
"#": "leashedplayer:leash_rope_arrow", "#": {
"$": "minecraft:glowstone_dust" "item": "leashedplayer:leash_rope_arrow"
},
"$": {
"item": "minecraft:glowstone_dust"
}
}, },
"pattern": [ "pattern": [
" $ ", " $ ",

View File

@ -2,8 +2,12 @@
"type": "minecraft:crafting_shapeless", "type": "minecraft:crafting_shapeless",
"category": "misc", "category": "misc",
"ingredients": [ "ingredients": [
"minecraft:lead", {
"minecraft:spectral_arrow" "item": "minecraft:lead"
},
{
"item": "minecraft:spectral_arrow"
}
], ],
"result": { "result": {
"count": 1, "count": 1,

View File

@ -1,4 +0,0 @@
{
"type": "leashedplayer:tipped_leash_rope_arrow_a_recipe",
"category": "misc"
}

View File

@ -1,4 +0,0 @@
{
"type": "leashedplayer:tipped_leash_rope_arrow_b_recipe",
"category": "misc"
}

View File

@ -1,5 +0,0 @@
{
"values": [
"minecraft:amethyst_shard"
]
}

View File

@ -1,7 +1,6 @@
{ {
"values": [ "values": [
"leashedplayer:leash_rope_arrow", "leashedplayer:leash_rope_arrow",
"leashedplayer:spectral_leash_rope_arrow", "leashedplayer:spectral_leash_rope_arrow"
"leashedplayer:tipped_leash_rope_arrow"
] ]
} }

View File

@ -1,5 +0,0 @@
{
"values": [
"leashedplayer:amethyst_shears"
]
}

View File

@ -1,5 +0,0 @@
{
"values": [
"leashedplayer:amethyst_shears"
]
}

View File

@ -1,5 +0,0 @@
{
"values": [
"leashedplayer:amethyst_shears"
]
}

View File

@ -1,6 +0,0 @@
{
"values": [
"leashedplayer:neoforge",
"minecraft:lead"
]
}

View File

@ -1,117 +1,23 @@
package com.r3944realms.leashedplayer; 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.LeashRopeArrowRenderer;
import com.r3944realms.leashedplayer.client.renders.entities.SpectralLeashRopeArrowRenderer; 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.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow; 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.renderer.item.ItemProperties;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
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.Items;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.component.ChargedProjectiles; import net.minecraft.world.item.component.ChargedProjectiles;
import net.minecraft.world.phys.HitResult;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.*; import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import java.util.List;
public class ClientEventHandler {
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME, modid = LeashedPlayer.MOD_ID)
public static class Game {
@SubscribeEvent
public static void onPlayerRendererEventPre(RenderPlayerEvent.Post event) {
PlayerRenderState renderState = event.getRenderState();
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<HitResult> 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<HitResult> 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) @EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID)
public static class Mod { public class ClientEventHandler {
@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 @SubscribeEvent
public static void onRegisterItemProperties(FMLClientSetupEvent event) { public static void onRegisterItemProperties(FMLClientSetupEvent event) {
event.enqueueWork(() -> { event.enqueueWork(() -> {
@ -125,22 +31,12 @@ public class ClientEventHandler {
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F (pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F
)); ));
}); });
} }
@SubscribeEvent @SubscribeEvent
public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) { public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new); event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::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()
);
}
}
} }

View File

@ -4,29 +4,23 @@ import com.mojang.brigadier.CommandDispatcher;
import com.r3944realms.leashedplayer.content.commands.LeashCommand; import com.r3944realms.leashedplayer.content.commands.LeashCommand;
import com.r3944realms.leashedplayer.content.commands.MotionCommand; import com.r3944realms.leashedplayer.content.commands.MotionCommand;
import com.r3944realms.leashedplayer.content.commands.TickCommand; 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.effects.ModPotionRegister;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.content.items.ModItemRegister; 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.commands.CommandSourceStack;
import net.minecraft.core.component.DataComponents; import net.minecraft.world.effect.MobEffectInstance;
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.Entity;
import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.animal.Fox; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.alchemy.Potions; import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DispenserBlock; import net.minecraft.world.level.block.DispenserBlock;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.event.AnvilUpdateEvent;
import net.neoforged.neoforge.event.RegisterCommandsEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent; import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent;
import net.neoforged.neoforge.event.tick.EntityTickEvent; import net.neoforged.neoforge.event.tick.EntityTickEvent;
@ -50,43 +44,26 @@ public class CommonEventHandler {
@SubscribeEvent @SubscribeEvent
public static void OnLivingTickEvent(EntityTickEvent.Post event) { public static void OnLivingTickEvent(EntityTickEvent.Post event) {
Entity entity = event.getEntity(); Entity entity = event.getEntity();
Level level = entity.level(); if (entity.level().isClientSide()) {
if (level.isClientSide()) {
return; return;
} }
if (entity instanceof Fox fox) { if (entity instanceof LivingEntity living) {
if (fox.getMainHandItem().is(ItemTags.ANVIL)) { MobEffectInstance effect = living.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); if(effect != null && effect.getDuration() > 0){
Util.throwItemTowardsLook(fox, ModItemRegister.NEOFORGE.get(), 0.3f, 0.1f); if (entity instanceof PlayerLeashable player) {
fox.playSound(SoundEvents.FOX_EAT); if (player.getLeashHolder() != null) {
} else if (fox.getMainHandItem().is(ModItemRegister.NEOFORGE.get())) { if (player.getLeashHolder() instanceof LeashRopeArrow arrow)
// 繞圈參數 arrow.setOwner(null);
float rotationSpeed = 10.0f; // tick 旋轉的角度 player.dropLeash(true, !(player.getLeashHolder() instanceof LeashRopeArrow));
// 計算新的旋轉角度 }
fox.yBodyRot += rotationSpeed; // 身體旋轉 } else if (entity instanceof Leashable leashable) {
fox.yHeadRot += rotationSpeed; // 頭部旋轉 if (leashable.getLeashHolder() != null) {
fox.yRotO += rotationSpeed; // 當前旋轉角度 if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow)
fox.yHeadRotO += rotationSpeed; // 頭部的當前旋轉角度 arrow.setOwner(null);
leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow));
// 確保旋轉角度不超出 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);
} }
} }
} }
@ -94,12 +71,10 @@ public class CommonEventHandler {
public static class Mod extends CommonEventHandler { public static class Mod extends CommonEventHandler {
@SubscribeEvent @SubscribeEvent
public static void onCommonSetup(FMLCommonSetupEvent event) { public static void onCommonSetup(FMLCommonSetupEvent event) {
event.enqueueWork(() -> {
DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get()); DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get());
DispenserBlock.registerProjectileBehavior(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get());
DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get());
DispenserBlock.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior());
});
} }
} }

View File

@ -7,9 +7,7 @@ import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.items.ModCreativeTab; import com.r3944realms.leashedplayer.content.items.ModCreativeTab;
import com.r3944realms.leashedplayer.content.items.ModItemRegister; 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.paintings.ModPaintingsRegister;
import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister;
import com.r3944realms.leashedplayer.utils.Util; import com.r3944realms.leashedplayer.utils.Util;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModLoadingContext; import net.neoforged.fml.ModLoadingContext;
@ -22,12 +20,8 @@ public class LeashedPlayer {
public static final String MOD_ID = "leashedplayer"; public static final String MOD_ID = "leashedplayer";
private static Double M1;//拴繩掉落距離倍基數 private static Double M1;//拴繩掉落距離倍基數
private static Double M2;//繩箭拴繩掉落距離倍基數 private static Double M2;//繩箭拴繩掉落距離倍基數
private static Integer M3; //拴绳最小长度
private static Integer M4; //拴绳最大长度
public LeashedPlayer(IEventBus event) { public LeashedPlayer(IEventBus event) {
ModItemRegister.register(event); ModItemRegister.register(event);
ModRecipeRegister.register(event);
ModSoundRegister.register(event);
ModPaintingsRegister.register(event); ModPaintingsRegister.register(event);
ModEffectRegister.register(event); ModEffectRegister.register(event);
ModPotionRegister.register(event); ModPotionRegister.register(event);
@ -54,17 +48,6 @@ public class LeashedPlayer {
} }
return M2; 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;
}
} }

View File

@ -1,527 +0,0 @@
package com.r3944realms.leashedplayer.client.renders;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.datafixers.util.Either;
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.PlayerLeashable;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
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.state.EntityRenderState;
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
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();
}
/**
* <h1>1. 角度与弧度转换</h1>
* {@snippet lang=java :
* double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float)(Math.PI / 180.0)) + (Math.PI / 2);
* }
* <ul>
* <li><code>pEntity.getPreciseBodyRotation(pPartialTick)</code> 返回实体的旋转角度通常是以度为单位/li>
* <li> <code>(Math.PI / 180.0)</code> 是将度数转换为弧度的乘数因为大多数三角函数 <code>cos</code> <code>sin</code>都需要弧度值</li>
* <li><code>+ (Math.PI / 2)</code> 用于将结果平移90度四分之一圆可能是为了校正方向或设置起始方向 </li>
* </ul>
*
* <p>
* <h1> 2. 三角函数计算位移</h1>
* {@snippet lang=java :
* double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
* double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
* }
* <ul>
* <li><code>d1</code> <code>d2</code> 是利用三角函数 <code>cos</code> <code>sin</code> 计算出来的位移量用于确定实体相对于其旋转的实际位置</li>
* <li><code>Math.cos(d0) * vec31.z</code> <code>Math.sin(d0) * vec31.x</code> 分别计算沿 X Z 轴的位移分量这种计算通常用于旋转一个点或向量</li>
* <li>两个公式结合起来用于旋转平面内的一个点 <code>(vec31.x, vec31.z)</code>从而得到旋转后的新坐标</li>
* </ul>
* <p>
* <h1> 3. 线性插值 (Lerp) </h1>
* {@snippet lang=java :
* double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
* double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
* double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
* }
* <ul>
* <li><code>Mth.lerp</code> 是线性插值函数通常用于在两个值之间平滑过渡</li>
* <li><code>pEntity.xo</code>, <code>pEntity.yo</code>, <code>pEntity.zo</code> 是实体在上一个刻度tick中的位置 <code>pEntity.getX()</code>, <code>pEntity.getY()</code>, <code>pEntity.getZ()</code> 是当前刻度的位置</li>
* <li><code>pPartialTick</code> 介于 <code>0</code> <code>1</code> 之间用来平滑过渡使得动画更加流畅</li>
* </ul>
* <p>
* <h1> 4. 向量差值 </h1>
* {@snippet lang=java :
* float f = (float)(vec3.x - d3);
* float f1 = (float)(vec3.y - d4);
* float f2 = (float)(vec3.z - d5);
* }
* <ul>
* <li>计算两个点<code>vec3</code> <code>(d3, d4, d5)</code>之间的差值得到的 <code>f</code><code>f1</code><code>f2</code> 是向量差用于后续的渲染计算</li>
* </ul>
* <p>
* <h1> 5. 逆平方根与比例因子 </h1>
* {@snippet lang=java :
* float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
* }
* <ul>
* <li><code>Mth.invSqrt</code> 计算的是逆平方根通常用于归一化向量或调整比例</li>
* <li><code>f * f + f2 * f2</code> 是计算向量 <code>(f, f2)</code> 的平方和用于得到其长度的平方</li>
* <li>乘以 <code>0.025F / 2.0F</code> 用于缩放结果使得线条在渲染时具有合适的比例</li>
* </ul>
* <p>
* <h1> 6. 循环绘制 </h1>
* {@snippet lang=java :
* for (int i1 = 0; i1 <= 24; i1++) {
* addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
* }
* }
* <ul>
* <li>循环从 <code>0</code> <code>24</code>用于创建24个顶点对形成一个链状结构或绳索的外观</li>
* <li>每个循环迭代都会更新顶点的位置颜色光照等属性使得链状结构被绘制出来</li>
* </ul>
* <p>
* <h1> 总结 </h1>
* 这些数学运算主要用于计算实体在三维空间中的位置和方向以确保在渲染链状结构如拴住的绳索链条能够跟随实体的移动和旋转并正确显示在图形编程中这些计算非常常见尤其是在处理旋转插值和光照效果时
*/
public static void renderLeash(
com.mojang.blaze3d.vertex.PoseStack poseStack,
net.minecraft.client.renderer.MultiBufferSource bufferSource,
PlayerRenderState playerRenderState
) {
float f = 0.025F;
// 获得绳索持有者的位置
PlayerLeashState leashState = ((IPlayerRenderStateExtension)playerRenderState).getPlayerLeashState();
if (leashState == null)
return;
Vec3 Holder = leashState.pos;//TODO问题修复
Vec3 o = leashState.o;
// 计算实体的朝向角度弧度
float partialTick = playerRenderState.partialTick;
double entityRotationAngleRadians = (double)(leashState.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
// 计算实体的绳索偏移此处add偏移让渲染拴绳显示在玩家头部下大约在脖子处
// Logger.logger.info("eyeHeight:{}",playerRenderState.eyeHeight);
Vec3 cameraEntityLeashOffset = new Vec3(0.0, leashState.eyeHeight , playerRenderState.boundingBoxWidth * 0.4F).add(0, -0.2, -0.2);
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
// 计算实体当前的实际位置
double entityPosX = Mth.lerp(partialTick, o.x, playerRenderState.x) + leashOffsetX;
double entityPosY = Mth.lerp(partialTick, o.y, playerRenderState.y) + cameraEntityLeashOffset.y;
double entityPosZ = Mth.lerp(partialTick, o.z, playerRenderState.z) + leashOffsetZ;
// 计算绳索的相对位置差
float deltaX = (float)(Holder.x - entityPosX);
float deltaY = (float)(Holder.y - entityPosY);
float deltaZ = (float)(Holder.z - entityPosZ);
// 计算比例因子用于调节绳索的粗细
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
// 计算比例因子用于调节绳索的粗细
float leashXZScaleX = deltaZ * leashLengthRatio;
float leashXZScaleZ = deltaX * leashLengthRatio;
poseStack.pushPose();
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y,leashOffsetZ);
VertexConsumer vertexconsumer = bufferSource.getBuffer(RenderType.leash());
Matrix4f matrix4f = poseStack.last().pose();
for (int i = 0; i <= 24; i++) {
addVertexPair(
vertexconsumer,
matrix4f,
deltaX,
deltaY,
deltaZ,
leashState.startBlockLight,
leashState.endBlockLight,
leashState.startSkyLight,
leashState.endSkyLight,
0.025F,
0.025F,
leashXZScaleX,
leashXZScaleZ,
i,
false
);
}
for (int j = 24; j >= 0; j--) {
addVertexPair(
vertexconsumer,
matrix4f,
deltaX,
deltaY,
deltaZ,
leashState.startBlockLight,
leashState.endBlockLight,
leashState.startSkyLight,
leashState.endSkyLight,
0.025F,
0.0F,
leashXZScaleX,
leashXZScaleZ,
j,
true
);
}
poseStack.popPose();
}
protected static void addVertexPair(
VertexConsumer buffer,
Matrix4f pose,
float startX,
float startY,
float startZ,
int entityBlockLight,
int holderBlockLight,
int entitySkyLight,
int holderSkyLight,
float yOffset,
float dy,
float dx,
float dz,
int index,
boolean reverse
) {
float f = (float)index / 24.0F;
int i = (int)Mth.lerp(f, (float)entityBlockLight, (float)holderBlockLight);
int j = (int)Mth.lerp(f, (float)entitySkyLight, (float)holderSkyLight);
int k = LightTexture.pack(i, j);
float f1 = index % 2 == (reverse ? 1 : 0) ? 0.7F : 1.0F;
float f2 = 0.5F * f1;
float f3 = 0.4F * f1;
float f4 = 0.3F * f1;
float f5 = startX * f;
float f6 = startY > 0.0F ? startY * f * f : startY - startY * (1.0F - f) * (1.0F - f);
float f7 = startZ * f;
buffer.addVertex(pose, f5 - dx, f6 + dy, f7 + dz).setColor(f2, f3, f4, 1.0F).setLight(k);
buffer.addVertex(pose, f5 + dx, f6 + yOffset - dy, f7 - dz).setColor(f2, f3, f4, 1.0F).setLight(k);
}
public static <E extends net.minecraft.world.entity.Entity> void renderLeashForCamera(
Camera camera,
float partialTick,
com.mojang.blaze3d.vertex.PoseStack poseStack,
net.minecraft.client.renderer.MultiBufferSource bufferSource,
E leashHolder,
Vec3 holderOffset
) {
poseStack.pushPose();
// Logger.logger.info("eyeHeight{}", camera.getEntity().getEyeHeight());
// 获得绳索持有者的位置
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick).add(holderOffset);
// 获取当前观察的实体
Entity cameraEntity = camera.getEntity();
// 计算实体的朝向角度弧度
double entityRotationAngleRadians = (double)(cameraEntity.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
// 计算实体的绳索偏移此处add偏移让渲染拴绳显示在玩家头部下大约在脖子处
Vec3 cameraEntityLeashOffset = cameraEntity.getLeashOffset(partialTick).add(0, -0.2, -0.5);
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
// 计算实体当前的实际位置
double entityPosX = Mth.lerp(partialTick, cameraEntity.xo, cameraEntity.getX()) + leashOffsetX;
double entityPosY = Mth.lerp(partialTick, cameraEntity.yo, cameraEntity.getY()) + cameraEntityLeashOffset.y;
double entityPosZ = Mth.lerp(partialTick, cameraEntity.zo, cameraEntity.getZ()) + leashOffsetZ;
// 在当前变换矩阵上应用偏移
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y , leashOffsetZ);
// 计算绳索的相对位置差
float deltaX = (float)(leashHolderPosition.x - entityPosX);
float deltaY = (float)(leashHolderPosition.y - entityPosY);
float deltaZ = (float)(leashHolderPosition.z - entityPosZ);
// 获取顶点消费者用于绘制绳索
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.leash());
Matrix4f matrix = poseStack.last().pose();
// 计算比例因子用于调节绳索的粗细
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
float leashXZScaleX = deltaZ * leashLengthRatio;
float leashXZScaleZ = deltaX * leashLengthRatio;
// 获取光照信息
BlockPos cameraEntityBlockPos = BlockPos.containing(cameraEntity.getEyePosition(partialTick));
BlockPos leashHolderBlockPos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
int cameraEntityBlockLightLevel = 0;
int leashHolderBlockLightLevel = 0; //getBlockLightLevel(leashHolder, leashHolderBlockPos);
int cameraEntitySkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, cameraEntityBlockPos);
int leashHolderSkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, leashHolderBlockPos);
// 绘制绳索的上半部分
for (int segment = 0; segment <= 24; segment++) {
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.025F, leashXZScaleX, leashXZScaleZ, segment, false);
}
// 绘制绳索的下半部分
for (int segment = 24; segment >= 0; segment--) {
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.0F, leashXZScaleX, leashXZScaleZ, segment, true);
}
poseStack.popPose();
}
public static void levelRenderLeash(ClientLevel level, Camera pCamera, PoseStack poseStack, MultiBufferSource.BufferSource multibuffersource$buffersource) {
for(Entity entity : level.entitiesForRendering()) {
//对于玩家实体拴绳渲染从第一人称视角
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
Minecraft mc = Minecraft.getInstance();
if (mc.options.getCameraType().isFirstPerson()) {
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
if(leashDataFromEntityData == null) continue;
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
if(delayedLeashInfo != null) {
float partialTickTime = pCamera.getPartialTickTime();
Vec3 position = pCamera.getPosition();
double dX = Mth.lerp(partialTickTime, abstractClientPlayer.xOld, abstractClientPlayer.getX()) - position.x;
double dY = Mth.lerp(partialTickTime, abstractClientPlayer.yOld, abstractClientPlayer.getY()) - position.y;
double dZ = Mth.lerp(partialTickTime, abstractClientPlayer.zOld, abstractClientPlayer.getZ()) - position.z;
Vec3 vec3 = getRenderOffset(entity, partialTickTime);
double dX_ = dX + vec3.x();
double dY_ = dY + vec3.y();
double dZ_ = dZ + vec3.z();
poseStack.pushPose();
poseStack.translate(dX_, dY_, dZ_);
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()), Vec3.ZERO);
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
if (playerByUUID != null) {
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID, Vec3.ZERO);
} else {
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
List<Entity> entities = level.getEntities(
null,
new AABB(
abstractClientPlayer.getX() - MaxLeashLength,
abstractClientPlayer.getY() - MaxLeashLength,
abstractClientPlayer.getZ() - MaxLeashLength,
abstractClientPlayer.getX() + MaxLeashLength,
abstractClientPlayer.getY() + MaxLeashLength,
abstractClientPlayer.getZ() + MaxLeashLength
)
);
Entity holder = null;
for (Entity entity_ : entities) {
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
holder = entity_;
break;
}
}
if (holder != null) {
if(holder instanceof LeashRopeArrow) {
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3吗
}
else renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, Vec3.ZERO);
}
}
break;
}
}
}
}
}
}
public static Vec3 getRenderOffset(Entity entity, float partialTickTime) {
Vec3 ret = Vec3.ZERO;
if(entity.isPassenger()
&& entity.getVehicle() instanceof AbstractMinecart abstractminecart
&& abstractminecart.getBehavior() instanceof NewMinecartBehavior newminecartbehavior
&& newminecartbehavior.cartHasPosRotLerp()
) {
double d2 = Mth.lerp(partialTickTime, abstractminecart.xOld, abstractminecart.getX());
double d0 = Mth.lerp(partialTickTime, abstractminecart.yOld, abstractminecart.getY());
double d1 = Mth.lerp(partialTickTime, abstractminecart.zOld, abstractminecart.getZ());
ret = newminecartbehavior.getCartLerpPosition(partialTickTime).subtract(new Vec3(d2, d0, d1));
}
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<UUID, BlockPos> 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 <T extends Entity> 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<UUID, BlockPos> 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<Entity> 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);
}
}

View File

@ -1,41 +0,0 @@
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;
public float eyeHeight;
public int startBlockLight;
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);
}
public PlayerLeashState() {
this.offset = Vec3.ZERO;
this.o = Vec3.ZERO;
this.pos = Vec3.ZERO;
this.yRot = 0.0f;
this.yRotO = 0.0f;
this.eyeHeight = 0.0f;
this.startBlockLight = 0;
this.endBlockLight = 0;
this.startSkyLight = 15;
this.endSkyLight = 15;
this.vanilaLeashState = null;
}
}

View File

@ -1,13 +0,0 @@
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;
}
}

View File

@ -1,120 +0,0 @@
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<S extends PlayerRenderState, M extends EntityModel<S>> extends RenderLayer<S, M> {
private final ItemInHandRenderer heldItemRenderer;
public ChestItemLayerRenderer(RenderLayerParent<S, M> 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();
}
}
}
}

View File

@ -4,27 +4,20 @@ import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import net.minecraft.client.renderer.entity.ArrowRenderer; import net.minecraft.client.renderer.entity.ArrowRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.state.ArrowRenderState;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow, ArrowRenderState> { public class LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow> {
public static final ResourceLocation LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/leash_rope_arrow.png"); public static final ResourceLocation LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/leash_rope_arrow.png");
public LeashRopeArrowRenderer(EntityRendererProvider.Context pContext) { public LeashRopeArrowRenderer(EntityRendererProvider.Context pContext) {
super(pContext); super(pContext);
} }
@Override @Override
public @NotNull ArrowRenderState createRenderState() { public @NotNull ResourceLocation getTextureLocation(@NotNull LeashRopeArrow pEntity) {
return new ArrowRenderState();
}
@Override
protected @NotNull ResourceLocation getTextureLocation(@NotNull ArrowRenderState arrowRenderState) {
return LEASH_ROPE_ARROW; return LEASH_ROPE_ARROW;
} }
} }

View File

@ -4,28 +4,20 @@ import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.entities.SpectralLeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.SpectralLeashRopeArrow;
import net.minecraft.client.renderer.entity.ArrowRenderer; import net.minecraft.client.renderer.entity.ArrowRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.state.ArrowRenderState;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class SpectralLeashRopeArrowRenderer extends ArrowRenderer<SpectralLeashRopeArrow, ArrowRenderState> { public class SpectralLeashRopeArrowRenderer extends ArrowRenderer<SpectralLeashRopeArrow> {
public static final ResourceLocation SPECTRAL_LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/spectral_leash_rope_arrow.png"); public static final ResourceLocation SPECTRAL_LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/spectral_leash_rope_arrow.png");
public SpectralLeashRopeArrowRenderer(EntityRendererProvider.Context pContext) { public SpectralLeashRopeArrowRenderer(EntityRendererProvider.Context pContext) {
super(pContext); super(pContext);
} }
@Override @Override
public @NotNull ArrowRenderState createRenderState() { public @NotNull ResourceLocation getTextureLocation(@NotNull SpectralLeashRopeArrow pEntity) {
return new ArrowRenderState();
}
@Override
protected @NotNull ResourceLocation getTextureLocation(@NotNull ArrowRenderState arrowRenderState) {
return SPECTRAL_LEASH_ROPE_ARROW; return SPECTRAL_LEASH_ROPE_ARROW;
} }
} }

View File

@ -27,7 +27,7 @@ public class LeashPlayerCommonConfig {
BUILDER.push("Misc"); BUILDER.push("Misc");
BUILDER.comment("Leash Player Length"); BUILDER.comment("Leash Player Length");
BUILDER.push("LeashLength"); BUILDER.push("LeashLength");
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); TheLeashBreakLengthTimesBase = BUILDER.comment("When it exceeds how many times, the leash will drop"," [ Default:2.0f, Invalid Range:[2.0f, 5.0f] ]").defineInRange("BreakLengthTimeBase", 2.0f, 2.0f ,5.0f);
MinimumLeashLengthCanBeSet = BUILDER.comment("The minimum integer's length of Leash", " [ Default:5, Invalid Range:[2,10] ]").defineInRange("MinLeashLength", 5, 2, 10); 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); MaximumLeashLengthCanBeSet = BUILDER.comment("The maximum integer's length of Leash", " [ Default:1024, Invalid Range:[32, 1024] ]").defineInRange("MaxLeashLength", 1024, 32, 1024);
BUILDER.pop().pop(); BUILDER.pop().pop();

View File

@ -1,37 +0,0 @@
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
);
}

View File

@ -41,7 +41,6 @@ public class MotionCommand {
); );
if(entity instanceof ServerPlayer player) { if(entity instanceof ServerPlayer player) {
PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.ADD, motionVec.x, motionVec.y, motionVec.z)); 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 { } else {
entity.addDeltaMovement(motionVec); entity.addDeltaMovement(motionVec);
} }
@ -60,7 +59,6 @@ public class MotionCommand {
); );
if(entity instanceof ServerPlayer player) { if(entity instanceof ServerPlayer player) {
PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.SET, motionVec.x, motionVec.y, motionVec.z)); 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 { } else {
entity.setDeltaMovement(motionVec); entity.setDeltaMovement(motionVec);
} }
@ -79,7 +77,6 @@ public class MotionCommand {
); );
if(entity instanceof ServerPlayer player) { if(entity instanceof ServerPlayer player) {
PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.MULTIPLY, motionFactorVec.x, motionFactorVec.y, motionFactorVec.z)); PacketDistributor.sendToPlayer(player, new UpdatePlayerMovement(UpdatePlayerMovement.Operation.MULTIPLY, motionFactorVec.x, motionFactorVec.y, motionFactorVec.z));
player.setDeltaMovement(entity.getDeltaMovement().multiply(motionFactorVec));
} else { } else {
entity.setDeltaMovement(entity.getDeltaMovement().multiply(motionFactorVec)); entity.setDeltaMovement(entity.getDeltaMovement().multiply(motionFactorVec));
} }

View File

@ -1,7 +1,6 @@
package com.r3944realms.leashedplayer.content.effects; package com.r3944realms.leashedplayer.content.effects;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.effects.type.NoLeashEffect;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffectCategory;
@ -15,7 +14,7 @@ public class ModEffectRegister {
public static DeferredRegister<MobEffect> MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID); public static DeferredRegister<MobEffect> MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID);
public static DeferredHolder<MobEffect, ? extends MobEffect> NO_LEASH_EFFECT = register( public static DeferredHolder<MobEffect, ? extends MobEffect> NO_LEASH_EFFECT = register(
"no_leash", "no_leash",
() -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764) () -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764)
); );
public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> effect) { public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> effect) {
return MOB_EFFECT.register(name, effect); return MOB_EFFECT.register(name, effect);

View File

@ -1,37 +0,0 @@
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;
}
}

View File

@ -7,16 +7,8 @@ import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTi
import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; 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.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -29,7 +21,6 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.EntityHitResult;
@ -37,56 +28,17 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class LeashRopeArrow extends AbstractArrow { public class LeashRopeArrow extends AbstractArrow {
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<Integer> 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(); private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get();
protected LeashRopeArrow(EntityType<? extends AbstractArrow> entityType,Level pLevel) { protected LeashRopeArrow(EntityType<? extends AbstractArrow> entityType,Level pLevel) {
super(entityType, pLevel); super(entityType, pLevel);
}
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<? extends AbstractArrow> entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { public LeashRopeArrow(EntityType<? extends AbstractArrow> 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); super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon);
this.updateColor();
if(serverPlayer != null && !level().isClientSide) { if(serverPlayer != null && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level()); Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);//将先前的箭矢置空 leashRopeArrow.setOwner(null);
} }
((PlayerLeashable)serverPlayer).setLeashedTo(this, true); ((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
} }
@ -94,7 +46,6 @@ public class LeashRopeArrow extends AbstractArrow {
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
this.updateColor();
if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level()); Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) { if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
@ -106,11 +57,12 @@ public class LeashRopeArrow extends AbstractArrow {
@Override @Override
protected @NotNull ItemStack getDefaultPickupItem() { protected @NotNull ItemStack getDefaultPickupItem() {
return new ItemStack(ModItemRegister.LEASH_ROPE_ARROW.get()); return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
} }
@Override @Override
public void setOwner(@Nullable Entity pEntity) { public void setOwner(@Nullable Entity pEntity) {
// super.setOwner(pEntity);
boolean isNull = pEntity == null; boolean isNull = pEntity == null;
this.ownerUUID = isNull ? null : pEntity.getUUID(); this.ownerUUID = isNull ? null : pEntity.getUUID();
this.cachedOwner = isNull ? null : pEntity; this.cachedOwner = isNull ? null : pEntity;
@ -137,18 +89,18 @@ public class LeashRopeArrow extends AbstractArrow {
if(life <= 40 ) { if(life <= 40 ) {
return false; return false;
} else { }
else {
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
if(this.getOwner() != null) {//未有Owner始终可检 if(this.getOwner() == null) {//未有Owner始终可检
return true;
}
if(life <= 240) { if(life <= 240) {
if(pPlayer.isShiftKeyDown()) { if(pPlayer.isShiftKeyDown()) {
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner(); Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
if(this.ownedBy(pPlayer)) { if(this.ownedBy(pPlayer)) {
this.pickup = Pickup.ALLOWED; this.pickup = Pickup.ALLOWED;
if(this.equals(leashDataEntity)) { if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false);
pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
playerLeashable.dropLeash(true, false);
}
} else { } else {
if(life >= 120) { if(life >= 120) {
Entity owner = getOwner(); Entity owner = getOwner();
@ -156,39 +108,30 @@ public class LeashRopeArrow extends AbstractArrow {
// if(this.equals(leashDataEntity)) { // if(this.equals(leashDataEntity)) {
if(owner instanceof PlayerLeashable player) { if(owner instanceof PlayerLeashable player) {
player.setLeashedTo(pPlayer, true); player.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
} else if(owner instanceof Leashable leashable) { } else if(owner instanceof Leashable leashable) {
leashable.setLeashedTo(pPlayer, true); leashable.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
} }
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack()); ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
level().addFreshEntity(itemEntity); level().addFreshEntity(itemEntity);
discard(); discard();
// } // }
} } else return true;
} else return false; } else return false;
} }
} else { } else return false;
((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(); Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
if(this.ownedBy(pPlayer)) { if(this.ownedBy(pPlayer)) {
this.pickup = Pickup.ALLOWED; this.pickup = Pickup.ALLOWED;
if(this.equals(leashDataEntity)) { if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false);
pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
playerLeashable.dropLeash(true, false);
}
} else { } else {
Entity owner = getOwner(); Entity owner = getOwner();
if(owner instanceof PlayerLeashable player) { if(owner instanceof PlayerLeashable player) {
player.setLeashedTo(pPlayer, true); player.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
} else if(owner instanceof Leashable leashable) { } else if(owner instanceof Leashable leashable) {
leashable.setLeashedTo(pPlayer, true); leashable.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
} }
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack()); ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
level().addFreshEntity(itemEntity); level().addFreshEntity(itemEntity);
@ -196,36 +139,12 @@ 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); return super.tryPickup(pPlayer);
} }
protected void hitOnEntityHandler(Entity pEntity) { protected void hitOnEntityHandler(Entity pEntity) {
if(pEntity instanceof LivingEntity pLiving) { //NOOP
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() { protected ItemStack getOrginalItemStack() {
return Items.ARROW.getDefaultInstance(); return Items.ARROW.getDefaultInstance();
@ -238,49 +157,11 @@ public class LeashRopeArrow extends AbstractArrow {
protected void tickDespawn() { protected void tickDespawn() {
this.life++; this.life++;
if (this.life >= maxLifeTime) { if (this.life >= maxLifeTime) {
ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack()); 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.level().addFreshEntity(leash_rope_arrow);
this.discard(); 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 @Override
@ -291,15 +172,11 @@ public class LeashRopeArrow extends AbstractArrow {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) { if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
} }
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos()); Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL; ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(leashKnotFence, true); 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()); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow); this.level().addFreshEntity(arrow);
discard(); discard();
@ -308,15 +185,10 @@ public class LeashRopeArrow extends AbstractArrow {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) { if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = this.getOwner(); Entity leashDataEntity = this.getOwner();
if(leashDataEntity != null) { if(leashDataEntity != null) {
leashDataEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
L.dropLeash(true, false); L.dropLeash(true, false);
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
} }
Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos()); Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos());
L.setLeashedTo(leashKnotFence, true); 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()); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow); this.level().addFreshEntity(arrow);
discard(); discard();
@ -334,8 +206,8 @@ public class LeashRopeArrow extends AbstractArrow {
hitOnEntityHandler(entity); hitOnEntityHandler(entity);
if(this.getOwner() instanceof LivingEntity livingEntity ) { if(this.getOwner() instanceof LivingEntity livingEntity ) {
MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT); MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
if (effect != null && effect.getDuration() != 0) { if(effect != null && effect.getDuration() > 0) {
this.dropLeashHandler(); this.setOwner(null);
} }
} }
if(entity instanceof LivingEntity livingEntity) { if(entity instanceof LivingEntity livingEntity) {
@ -343,28 +215,17 @@ public class LeashRopeArrow extends AbstractArrow {
if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成 if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成
setOwner(livingEntity); setOwner(livingEntity);
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) { if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
}
ILivingEntityExtension pLL = (ILivingEntityExtension) pL; ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
pL.setLeashedTo(this, true); pL.setLeashedTo(this, true);
return;
} else if (this.getOwner() instanceof PlayerLeashable pL) { } else if (this.getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) { if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
}
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL; ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
pL.setLeashedTo(pResult.getEntity(), true); pL.setLeashedTo(pResult.getEntity(), true);
this.level().addFreshEntity(arrow); this.level().addFreshEntity(arrow);
discard(); discard();
@ -372,13 +233,8 @@ public class LeashRopeArrow extends AbstractArrow {
if(entity instanceof Leashable leashable) { if(entity instanceof Leashable leashable) {
if (getOwner() == null) { if (getOwner() == null) {
Entity leashDataEntity = leashable.getLeashHolder(); Entity leashDataEntity = leashable.getLeashHolder();
if (leashDataEntity != null) { if (leashDataEntity != null)
leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
}
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
leashable.setLeashedTo(this, true); leashable.setLeashedTo(this, true);
this.setOwner(entity); this.setOwner(entity);
return; return;
@ -386,7 +242,6 @@ public class LeashRopeArrow extends AbstractArrow {
} }
if(entity instanceof LivingEntity living) { if(entity instanceof LivingEntity living) {
if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) { if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
leashable.setLeashedTo(living, true); leashable.setLeashedTo(living, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow); this.level().addFreshEntity(arrow);
@ -401,57 +256,21 @@ public class LeashRopeArrow extends AbstractArrow {
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) { else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
if (getOwner() instanceof PlayerLeashable pL) { if (getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if (leashDataEntity != null) { if(leashDataEntity != null) pL.dropLeash(true, true);
pL.dropLeash(true, true);
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
}
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack()); ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL; ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
pL.setLeashedTo(leashKnotFence, true); pL.setLeashedTo(leashKnotFence, true);
this.level().addFreshEntity(arrow); this.level().addFreshEntity(arrow);
discard(); discard();
return;
} }
} else { } else {
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance()); ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
this.level().addFreshEntity(lead); this.level().addFreshEntity(lead);
} }
} }
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);
}
} }

View File

@ -2,8 +2,6 @@ package com.r3944realms.leashedplayer.content.entities;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.MobCategory;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
@ -19,7 +17,7 @@ public class ModEntityRegister {
.eyeHeight(0.13F) .eyeHeight(0.13F)
.clientTrackingRange(4) .clientTrackingRange(4)
.updateInterval(20) .updateInterval(20)
.build(ResourceKey.create(Registries.ENTITY_TYPE, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "leash_rope_arrow"))) .build("leash_rope_arrow")
); );
public static final DeferredHolder<EntityType<?>, EntityType<SpectralLeashRopeArrow>> SPECTRAL_LEASH_ROPE_ARROW = ENTITY_TYPE.register( public static final DeferredHolder<EntityType<?>, EntityType<SpectralLeashRopeArrow>> SPECTRAL_LEASH_ROPE_ARROW = ENTITY_TYPE.register(
"spectral_leash_rope_arrow", "spectral_leash_rope_arrow",
@ -28,9 +26,14 @@ public class ModEntityRegister {
.eyeHeight(0.13F) .eyeHeight(0.13F)
.clientTrackingRange(4) .clientTrackingRange(4)
.updateInterval(20) .updateInterval(20)
.build(ResourceKey.create(Registries.ENTITY_TYPE, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "spectral_leash_rope_arrow"))) .build("spectral_leash_rope_arrow")
); );
// public static final DeferredHolder<EntityType<?>, EntityType<ChainTieEntity>> CHAIN_TIE = ENTITY_TYPE.register(
// "chain_tie",
// () -> EntityType.Builder.<ChainTieEntity>of(ChainTieEntity::new, MobCategory.MISC)
// .sized(0.8F, 0.9F)
// .build("chain_tie")
// );
public static String getEntityNameKey(String entityName) { public static String getEntityNameKey(String entityName) {
return "entity." + LeashedPlayer.MOD_ID + "." + entityName; return "entity." + LeashedPlayer.MOD_ID + "." + entityName;
} }

View File

@ -33,7 +33,7 @@ public class SpectralLeashRopeArrow extends LeashRopeArrow {
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
if (this.level().isClientSide && !this.isInGround()) { if (this.level().isClientSide && !this.inGround) {
this.level().addParticle(ParticleTypes.INSTANT_EFFECT, this.getX(), this.getY(), this.getZ(), 0.0, 0.0, 0.0); this.level().addParticle(ParticleTypes.INSTANT_EFFECT, this.getX(), this.getY(), this.getZ(), 0.0, 0.0, 0.0);
} }
} }

View File

@ -1,8 +1,6 @@
package com.r3944realms.leashedplayer.content.gamerules; package com.r3944realms.leashedplayer.content.gamerules;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@ -27,7 +25,7 @@ public enum GameruleRegistry {
if (gameruleDataTypes.get(gameruleName) != RuleDataType.BOOLEAN) { if (gameruleDataTypes.get(gameruleName) != RuleDataType.BOOLEAN) {
return false; return false;
} }
return ((ServerLevel)level).getGameRules().getBoolean((GameRules.Key<GameRules.BooleanValue>) gamerules.get(gameruleName)); return level.getGameRules().getBoolean((GameRules.Key<GameRules.BooleanValue>) gamerules.get(gameruleName));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static Integer getGameruleIntValue(Level level, String gameruleName) { public static Integer getGameruleIntValue(Level level, String gameruleName) {
@ -37,7 +35,7 @@ public enum GameruleRegistry {
if (gameruleDataTypes.get(gameruleName) != RuleDataType.INTEGER) { if (gameruleDataTypes.get(gameruleName) != RuleDataType.INTEGER) {
return 0; return 0;
} }
return ((ServerLevel)level).getGameRules().getInt((GameRules.Key<GameRules.IntegerValue>)gamerules.get(gameruleName)); return level.getGameRules().getInt((GameRules.Key<GameRules.IntegerValue>)gamerules.get(gameruleName));
} }
public void registerGamerule(String gameruleName, GameRules.Category category, boolean pDefault) { public void registerGamerule(String gameruleName, GameRules.Category category, boolean pDefault) {
@ -55,7 +53,7 @@ public enum GameruleRegistry {
gameruleDataTypes.put(gameruleName, RuleDataType.INTEGER); gameruleDataTypes.put(gameruleName, RuleDataType.INTEGER);
} }
public void registerGamerule(String gameruleName, GameRules.Category category, int pDefault, int pMin, int pMax, BiConsumer<MinecraftServer, GameRules.IntegerValue> pChangeListener) { public void registerGamerule(String gameruleName, GameRules.Category category, int pDefault, int pMin, int pMax, BiConsumer<MinecraftServer, GameRules.IntegerValue> pChangeListener) {
gamerules.put(gameruleName, GameRules.register(gameruleName, category, GameRules.IntegerValue.create(pDefault, pMin, pMax, FeatureFlagSet.of(), pChangeListener))); gamerules.put(gameruleName, GameRules.register(gameruleName, category, GameRules.IntegerValue.create(pDefault, pMin, pMax, pChangeListener)));
gameruleDataTypes.put(gameruleName, RuleDataType.INTEGER); gameruleDataTypes.put(gameruleName, RuleDataType.INTEGER);
} }
public void registerGamerule(String gameruleName, GameRules.Category category,float value) { public void registerGamerule(String gameruleName, GameRules.Category category,float value) {

View File

@ -4,7 +4,6 @@ import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameRules;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -39,8 +38,7 @@ public class Gamerules {
(FloatArgumentType::floatArg, (FloatArgumentType::floatArg,
pType -> new FloatValue(pType, pDefaultValue), pType -> new FloatValue(pType, pDefaultValue),
pChangeListener, pChangeListener,
GameRules.GameRuleTypeVisitor::visit, GameRules.GameRuleTypeVisitor::visit
FeatureFlagSet.of()
); );
} }
public static GameRules.Type<FloatValue> create( public static GameRules.Type<FloatValue> create(
@ -50,8 +48,7 @@ public class Gamerules {
() -> FloatArgumentType.floatArg(pMin, pMax), () -> FloatArgumentType.floatArg(pMin, pMax),
pType -> new FloatValue(pType, pDefaultValue), pType -> new FloatValue(pType, pDefaultValue),
pChangeListener, pChangeListener,
GameRules.GameRuleTypeVisitor::visit, GameRules.GameRuleTypeVisitor::visit
FeatureFlagSet.of()
); );
} }
public FloatValue(GameRules.Type<FloatValue> pType, float value) { public FloatValue(GameRules.Type<FloatValue> pType, float value) {

View File

@ -0,0 +1,25 @@
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 = true;
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);
}
}

View File

@ -4,9 +4,7 @@ import com.r3944realms.leashedplayer.LeashedPlayer;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionContents; import net.minecraft.world.item.alchemy.PotionContents;
@ -32,43 +30,14 @@ public class ModCreativeTab {
pOutput.accept(Items.CROSSBOW); pOutput.accept(Items.CROSSBOW);
pOutput.accept(ModItemRegister.LEASH_ROPE_ARROW.get()); pOutput.accept(ModItemRegister.LEASH_ROPE_ARROW.get());
pOutput.accept(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); pOutput.accept(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get());
pOutput.accept(ModItemRegister.AMETHYST_SHEARS.get());
HolderLookup.RegistryLookup<Potion> potionRegistryLookup = CommonHooks.resolveLookup(Registries.POTION); HolderLookup.RegistryLookup<Potion> potionRegistryLookup = CommonHooks.resolveLookup(Registries.POTION);
if(potionRegistryLookup != null) { if(potionRegistryLookup != null) {
potionRegistryLookup.listElements() potionRegistryLookup.listElements()
.filter(p_337926_ -> Objects.requireNonNull(p_337926_.getKey()).location().getNamespace().equals(LeashedPlayer.MOD_ID)) .filter(p_337926_ -> Objects.requireNonNull(p_337926_.getKey()).location().getNamespace().equals(LeashedPlayer.MOD_ID))
.map(p_330083_ -> PotionContents.createItemStack(Items.POTION, p_330083_)) .map(p_330083_ -> PotionContents.createItemStack(Items.POTION, p_330083_))
.forEach(pOutput::accept); .forEach(pOutput::accept);
potionRegistryLookup.listElements()
.filter(p_337926_ -> Objects.requireNonNull(p_337926_.getKey()).location().getNamespace().equals(LeashedPlayer.MOD_ID))
.map(p_330083_ -> PotionContents.createItemStack(Items.SPLASH_POTION, p_330083_))
.forEach(pOutput::accept);
potionRegistryLookup.listElements()
.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()); })).build());
private static void generatePotionEffectTypes(
CreativeModeTab.Output pOutput, HolderLookup<Potion> 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) { public static String getCreativeMod(@NotNull String tabs) {
return LEASHED_PLAYER_TAB_STRING + "." + tabs; return LEASHED_PLAYER_TAB_STRING + "." + tabs;
} }

View File

@ -1,18 +1,12 @@
package com.r3944realms.leashedplayer.content.items; package com.r3944realms.leashedplayer.content.items;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.items.type.*; import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem;
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs; import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem;
import net.minecraft.core.component.DataComponents; import com.r3944realms.leashedplayer.content.items.type.TestItem;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.Item; 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.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.ArrayList; import java.util.ArrayList;
@ -22,39 +16,23 @@ import java.util.function.Supplier;
public class ModItemRegister { public class ModItemRegister {
public static final DeferredRegister<Item> ITEMS = public static final DeferredRegister<Item> ITEMS =
DeferredRegister.create(BuiltInRegistries.ITEM, LeashedPlayer.MOD_ID); DeferredRegister.create(BuiltInRegistries.ITEM, LeashedPlayer.MOD_ID);
public static final List<DeferredHolder<Item, Item>> ITEM_SUPPLIER = new ArrayList<>(); public static final List<Supplier<Item>> ITEM_SUPPLIER = new ArrayList<>();
public static final DeferredHolder<Item, Item> LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow", public static final Supplier<Item> LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow",
() -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16) () -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16))
.setId(ModItemResourceKeys.LEASH_ROPE_ARROW.getResourceKey()))
); );
public static final DeferredHolder<Item, Item> SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow", public static final Supplier<Item> SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow",
() -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16) () -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16)));
.setId(ModItemResourceKeys.SPECTRAL_LEASH_ROPE_ARROW.getResourceKey())));
public static final DeferredHolder<Item, Item> TIPPED_LEASH_ROPE_ARROW = ModItemRegister.register("tipped_leash_rope_arrow", public static final Supplier<Item> FABRIC = ModItemRegister.register("fabric",
() -> new TippedLeashRopeArrowItem(new Item.Properties().stacksTo(16).component(DataComponents.POTION_CONTENTS, PotionContents.EMPTY) () -> new TestItem(new Item.Properties().stacksTo(1))
.setId(ModItemResourceKeys.TIPPED_LEASH_ROPE_ARROW.getResourceKey()))); );
public static final DeferredHolder<Item, Item> 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<Item, Item> FABRIC = ModItemRegister.register("fabric",
() -> new TestItem(new Item.Properties().stacksTo(1)
.setId(ModItemResourceKeys.FABRIC.getResourceKey())));
public static final DeferredHolder<Item, Item> NEOFORGE = ModItemRegister.register("neoforge",
() -> new Item(DistProperties(ModJukeboxSongs.FOX_MUSIC)
.setId(ModItemResourceKeys.NEOFORGE.getResourceKey())));
public static Item.Properties DistProperties(ResourceKey<JukeboxSong> song) { public static Supplier<Item> register(String name, Supplier<Item> supplier) {
return new Item.Properties().stacksTo(1).rarity(Rarity.RARE).jukeboxPlayable(song);
}
public static DeferredHolder<Item, Item> register(String name, Supplier<Item> supplier) {
return register(name, supplier, true); return register(name, supplier, true);
} }
public static DeferredHolder<Item, Item> register(String name, Supplier<Item> supplier, boolean shouldJoinSupplierLists) { public static Supplier<Item> register(String name, Supplier<Item> supplier, boolean shouldJoinSupplierLists) {
DeferredHolder<Item, Item> supplierItem = ITEMS.register(name, supplier); Supplier<Item> supplierItem = ITEMS.register(name, supplier);
if(shouldJoinSupplierLists) ITEM_SUPPLIER.add(supplierItem); if(shouldJoinSupplierLists) ITEM_SUPPLIER.add(supplierItem);
return supplierItem; return supplierItem;
} }

View File

@ -1,29 +0,0 @@
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<Item> resourceKey;
ModItemResourceKeys(String name) {
resourceKey = ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, name));
}
ModItemResourceKeys(DeferredHolder<Item, Item> item) {
resourceKey = ResourceKey.create(Registries.ITEM, item.getId());
}
public ResourceKey<Item> getResourceKey() {
return resourceKey;
}
}

View File

@ -1,13 +0,0 @@
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
);
}

View File

@ -1,27 +0,0 @@
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<RecipeSerializer<?>> RECIPE_SERIALIZER =
DeferredRegister.create(BuiltInRegistries.RECIPE_SERIALIZER, LeashedPlayer.MOD_ID);
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<TippedLeashRopeArrowRecipe.TippedLeashRopeArrowARecipe>> 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<?>, RecipeSerializer<TippedLeashRopeArrowRecipe.TippedLeashRopeArrowBRecipe>> 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);
}
}

View File

@ -1,106 +0,0 @@
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<? extends CustomRecipe> 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<? extends CustomRecipe> getSerializer() {
return ModRecipeRegister.TIPPED_LEASH_ROPE_ARROW_B_RECIPE.get();
}
}
}

View File

@ -1,129 +0,0 @@
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;
import java.util.List;
public class LeadBreakerItem extends ShearsItem {
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<Block> holdergetter = BuiltInRegistries.acquireBootstrapRegistrationLookup(BuiltInRegistries.BLOCK);
return new Tool(
List.of(
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(BuiltInRegistries.BLOCK.wrapAsHolder(Blocks.VINE), BuiltInRegistries.BLOCK.wrapAsHolder(Blocks.GLOW_LICHEN)), 4.0F)
),
1.0F,
1
);
}
@Override
public @NotNull InteractionResult interactLivingEntity(@NotNull ItemStack stack, @NotNull Player player, @NotNull LivingEntity entity, net.minecraft.world.@NotNull InteractionHand hand) {
if(!entity.level().isClientSide) {
if (entity instanceof PlayerLeashable playerLeashable) {
if (playerLeashable.isLeashed()){
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()){
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;
}
}
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<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
pTooltipComponents.add(Component.translatable(HOVER_KEY));
}
}

View File

@ -20,15 +20,7 @@ import javax.annotation.Nullable;
import java.util.List; import java.util.List;
public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ 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) { public LeashRopeArrowItem(Item.Properties pProperties) {
super(pProperties); super(pProperties);
} }
@ -39,22 +31,17 @@ public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
@Override @Override
public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) { 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, pStack,null, null); LeashRopeArrow arrow = new LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, this.getDefaultInstance(),null, null);
arrow.pickup = AbstractArrow.Pickup.DISALLOWED; arrow.pickup = AbstractArrow.Pickup.DISALLOWED;
return arrow; return arrow;
} }
@Override
public @NotNull Component getDescription() { public @NotNull Component getDescription() {
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY); return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
} }
public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
pTooltipComponents.addAll(List.of( //TODO:也许会做
Component.translatable(DESC_1),
Component.translatable(DESC_2),
Component.translatable(DESC_3),
Component.translatable(DESC_4),
Component.translatable(DESC_5)
));
} }
} }

View File

@ -21,8 +21,7 @@ import javax.annotation.Nullable;
import java.util.List; import java.util.List;
public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ 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) { public SpectralLeashRopeArrowItem(Properties pProperties) {
super(pProperties); super(pProperties);
} }
@ -37,14 +36,11 @@ public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeA
return arrow; return arrow;
} }
@Override
public @NotNull Component getDescription() { public @NotNull Component getDescription() {
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY); return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
} }
public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
pTooltipComponents.addAll(List.of( //TODO:也许会做
Component.translatable(LeashRopeArrowItem.DESC_V_1),
Component.translatable(LeashRopeArrowItem.DESC_V_2),
Component.translatable(DESC)
));
} }
} }

View File

@ -7,9 +7,10 @@ import com.r3944realms.leashedplayer.client.renders.gui.IFadingProcessBarRendere
import com.r3944realms.leashedplayer.client.renders.gui.IProcessBarRenderer; import com.r3944realms.leashedplayer.client.renders.gui.IProcessBarRenderer;
import com.r3944realms.leashedplayer.client.renders.gui.TestProcessBarRenderer; import com.r3944realms.leashedplayer.client.renders.gui.TestProcessBarRenderer;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class TestItem extends Item {
} }
@Override @Override
public @NotNull InteractionResult use(@NotNull Level pLevel, @NotNull Player pPlayer, @NotNull InteractionHand pUsedHand) { public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, @NotNull Player pPlayer, @NotNull InteractionHand pUsedHand) {
if(!pLevel.isClientSide()){ if(!pLevel.isClientSide()){
//some lo //some lo
} }

View File

@ -1,57 +0,0 @@
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<Component> 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<Holder<Potion>> 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));
}
}

View File

@ -1,77 +0,0 @@
package com.r3944realms.leashedplayer.content.misc;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.dispenser.BlockSource;
import net.minecraft.core.dispenser.OptionalDispenseItemBehavior;
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.entity.EntitySelector;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.BeehiveBlock;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.NotNull;
public class LeadBreakItemBehavior extends OptionalDispenseItemBehavior {
@Override
protected @NotNull ItemStack execute(@NotNull BlockSource blockSource, @NotNull ItemStack item) {
ServerLevel serverLevel = blockSource.level();
if(!serverLevel.isClientSide()) {
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item));
if (this.isSuccess()) {
item.hurtAndBreak(1, serverLevel, null, p_348118_ -> {
});
}
}
return item;
}
private static boolean tryShearBeehive(ServerLevel level, BlockPos pos) {
BlockState blockstate = level.getBlockState(pos);
if (blockstate.is(BlockTags.BEEHIVES, p_202454_ -> p_202454_.hasProperty(BeehiveBlock.HONEY_LEVEL) && p_202454_.getBlock() instanceof BeehiveBlock)) {
int i = blockstate.getValue(BeehiveBlock.HONEY_LEVEL);
if (i >= 5) {
level.playSound(null, pos, SoundEvents.BEEHIVE_SHEAR, SoundSource.BLOCKS, 1.0F, 1.0F);
BeehiveBlock.dropHoneycomb(level, pos);
((BeehiveBlock)blockstate.getBlock())
.releaseBeesAndResetHoneyLevel(level, blockstate, pos, null, BeehiveBlockEntity.BeeReleaseStatus.BEE_RELEASED);
level.gameEvent(null, GameEvent.SHEAR, pos);
return true;
}
}
return false;
}
private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos, ItemStack item) {
for (LivingEntity livingentity : level.getEntitiesOfClass(LivingEntity.class, new AABB(pos), EntitySelector.NO_SPECTATORS)) {
if (livingentity instanceof PlayerLeashable playerLeashable) {
if (playerLeashable.isLeashed()){
playerLeashable.dropLeash(true, !(playerLeashable.getLeashHolder() instanceof LeashRopeArrow));
if (playerLeashable.getLeashHolder() instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
return true;
} else return false;
} else if (livingentity instanceof Leashable leashable) {
if (leashable.isLeashed()) {
leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow));
if (leashable.getLeashHolder() instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
return true;
} else return false;
}
}
return false;
}
}

View File

@ -1,22 +1,19 @@
package com.r3944realms.leashedplayer.content.paintings; package com.r3944realms.leashedplayer.content.paintings;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.decoration.PaintingVariant; import net.minecraft.world.entity.decoration.PaintingVariant;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ModPaintingsRegister { public class ModPaintingsRegister {
public static final DeferredRegister<PaintingVariant> PAINTING_VARIANT = public static final DeferredRegister<PaintingVariant> PAINTING_VARIANT =
DeferredRegister.create(Registries.PAINTING_VARIANT, LeashedPlayer.MOD_ID); DeferredRegister.create(Registries.PAINTING_VARIANT, LeashedPlayer.MOD_ID);
public static final Supplier<PaintingVariant> GROUP_PHOTO = PAINTING_VARIANT.register("group_photo", () -> new PaintingVariant(1920, 1080, getAssetId("group_photo"), Optional.of(Component.translatable(ModPaintingVariants.getPaintingVariantTitleKey(ModPaintingVariants.GROUP_PHOTO))), Optional.of(Component.translatable(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO))))); public static final Supplier<PaintingVariant> GROUP_PHOTO = PAINTING_VARIANT.register("group_photo", () -> new PaintingVariant(1920, 1080, getAssetId("group_photo")));
private static @NotNull ResourceLocation getAssetId( String paint_name) { private static @NotNull ResourceLocation getAssetId( String paint_name) {
return ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/painting/"+paint_name+".png"); return ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/painting/"+paint_name+".png");

View File

@ -1,35 +0,0 @@
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<SoundEvent> 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<SoundEvent, SoundEvent> FOX_MUSIC =
ModSoundRegister.register("what_does_the_fox_say", () -> SoundEvent.createFixedRangeEvent(
RL_FOX_MUSIC,
128
));
public static DeferredHolder<SoundEvent, SoundEvent> register(String name, Supplier<SoundEvent> 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;
}
}

View File

@ -15,9 +15,6 @@ public enum ModAdvancementKey {
FOLLOW_LEASH_ARROW("follow_arrow", LEASH_ARROW), FOLLOW_LEASH_ARROW("follow_arrow", LEASH_ARROW),
DOG_RUNNING_PLAYER("dog_running_player", LEASH_ARROW), DOG_RUNNING_PLAYER("dog_running_player", LEASH_ARROW),
NO_LEASH("no_leash", LEASH_START), 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; private final String Name;
@Nullable @Nullable

View File

@ -1,21 +0,0 @@
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<Item> AMETHYST_TOOL_MATERIALS = bind("amethyst_tool_materials");
private ModItemTags() {
}
private static TagKey<Item> bind(String name) {
return TagKey.create(Registries.ITEM, ResourceLocation.withDefaultNamespace(name));
}
public static TagKey<Item> create(final ResourceLocation name) {
return TagKey.create(Registries.ITEM, name);
}
}

View File

@ -1,26 +1,18 @@
package com.r3944realms.leashedplayer.datagen.LanguageAndOtherData; 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.LeashCommand;
import com.r3944realms.leashedplayer.content.commands.MotionCommand; import com.r3944realms.leashedplayer.content.commands.MotionCommand;
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister; import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
import com.r3944realms.leashedplayer.content.effects.ModPotionRegister; 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.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent; 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.KeepLeashNotDropTime;
import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers; import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers;
import com.r3944realms.leashedplayer.content.items.ModCreativeTab; import com.r3944realms.leashedplayer.content.items.ModCreativeTab;
import com.r3944realms.leashedplayer.content.items.ModItemRegister; 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.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.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.LanguageEnum;
import com.r3944realms.leashedplayer.utils.Enum.ModPartEnum; import com.r3944realms.leashedplayer.utils.Enum.ModPartEnum;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
@ -33,40 +25,18 @@ import java.util.function.Supplier;
import static com.r3944realms.leashedplayer.content.items.ModCreativeTab.LEASHED_PLAYER_ITEM; import static com.r3944realms.leashedplayer.content.items.ModCreativeTab.LEASHED_PLAYER_ITEM;
public enum ModLangKeyValue { 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
ITEM_LEASH_ROPE_ARROW(ModItemRegister.LEASH_ROPE_ARROW, ModPartEnum.ITEM, "Leash Rope Arrow", "拴绳箭", "拴繩箭", true), 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), 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), TEST_FABRIC_ITEM(ModItemRegister.FABRIC, ModPartEnum.ITEM, "Fabric", "Fabric", "Fabric", true),
AMETHYST_SHEARS(ModItemRegister.AMETHYST_SHEARS, ModPartEnum.ITEM, "Amethyst Shears", "紫水晶剪刀", "紫水晶剪刀", 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 //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 launchers 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_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 //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_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), GROUP_PHOTO_AUTHOR(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO),ModPartEnum.AUTHOR, "§9Leisure §4Time §eDock§r","§9闲趣§4时§e坞§r","§9閑趣§4時§e塢§r",false),
//ENTITY //ENTITY
LEASH_ROPE_ARROW(ModEntityRegister.getEntityNameKey("leash_rope_arrow"), ModPartEnum.ENTITY, "Leash Rope Arrow", "拴绳箭", "拴繩箭", false), 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), 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
CREATIVE_TAB_NAME(ModCreativeTab.getCreativeMod(LEASHED_PLAYER_ITEM), ModPartEnum.CREATIVE_TAB, "Leashed Player","可拴玩家", "可拴玩家", false), CREATIVE_TAB_NAME(ModCreativeTab.getCreativeMod(LEASHED_PLAYER_ITEM), ModPartEnum.CREATIVE_TAB, "Leashed Player","可拴玩家", "可拴玩家", false),
//COMMAND_MESSAGE //COMMAND_MESSAGE
@ -85,26 +55,16 @@ 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_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_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_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 //GAME_RULE_NAME
TELEPORT_WITH_LEASHED_PLAYERS_NAME(TeleportWithLeashedPlayers.NAME_KEY, ModPartEnum.NAME, "Teleport leashed player with player holder", "被拴玩家随玩家持有者传送", "被拴玩家随玩家持有者傳送" ,false), TELEPORT_WITH_LEASHED_PLAYERS(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), 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_NAME(KeepLeashNotDropTime.NAME_KEY, ModPartEnum.NAME, "Keep leash alive Time", "保持拴绳不掉落的时间", "保持其不掉落的時間", 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),
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 //GAME_RULE_DESCRIPTION
TELEPORT_WITH_LEASHED_DESCRIPTION(TeleportWithLeashedPlayers.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Holder will teleport with their leashed players ", "传送时将被拴玩家与持有者一起传送", "將被拴玩家將隨持有者一起傳送" ,false), 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), 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), 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 //ADV_NAME
LEASH_START(ModAdvancementKey.LEASH_START.getNameKey(), ModPartEnum.NAME, "The Power of Traction", "牵引之力", "牽引之力", false), 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), LEASH_LR_ARROW(ModAdvancementKey.LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "Arrow with a Tether?" , "拴绳之箭?", "拴繩之箭?", false),
@ -113,10 +73,7 @@ public enum ModLangKeyValue {
LEASH_PLAYER(ModAdvancementKey.LEASHED_FRIEND.getNameKey(),ModPartEnum.NAME, "Be bound by Rope", "拴绳链接", "拴繩鏈接" , false), 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_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), FOLLOW_WOLF(ModAdvancementKey.DOG_RUNNING_PLAYER.getNameKey(), ModPartEnum.NAME, "It's Walking human time.", "遛“人”时间", "遛“人”時間",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), 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 //ADV_DESC
LEASH_START_DESC(ModAdvancementKey.LEASH_START.getDescKey(), ModPartEnum.DESCRIPTION, "Journey to becoming a Leash Expert", "拴绳大师之路", "拴繩大師之路", false), 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), LEASH_LR_ARROW_DESC(ModAdvancementKey.LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "Maybe you can using it to shoot some mob?", "也许可以用它来发射生物?", "也許可以用它發射生物?", false),
@ -125,11 +82,7 @@ public enum ModLangKeyValue {
LEASH_PLAYER_DESC(ModAdvancementKey.LEASHED_FRIEND.getDescKey(),ModPartEnum.DESCRIPTION, "Be Bond by player with lead", "被玩家用拴绳链接", "被玩家用拴繩鏈接", false), 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_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), 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), NO_LEASH_DESC(ModAdvancementKey.NO_LEASH.getDescKey(), ModPartEnum.NAME, "You cannot be leashed by ANY", "你不会被任何东西拴住", "恁不會被任何拴住", false),
TERMINATOR_DESC(ModAdvancementKey.LEASH_TERMINATOR.getDescKey(), ModPartEnum.DESCRIPTION, "I am Lead Terminator!", "我來终结拴绳者!", "吾將終結拴繩!", 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 //MOB_EFFECT
NO_LEASH_EFFECT(ModEffectRegister.getEffectKey(ModEffectRegister.NO_LEASH_EFFECT.get()), ModPartEnum.NAME, "No Leash", "禁拴", "禁拴", false), NO_LEASH_EFFECT(ModEffectRegister.getEffectKey(ModEffectRegister.NO_LEASH_EFFECT.get()), ModPartEnum.NAME, "No Leash", "禁拴", "禁拴", false),
//POTION //POTION

View File

@ -5,7 +5,6 @@ import com.r3944realms.leashedplayer.datagen.provider.*;
import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum; import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.data.DataProvider; import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.common.data.ExistingFileHelper; import net.neoforged.neoforge.common.data.ExistingFileHelper;
@ -18,6 +17,7 @@ public class ModDataGeneratorHandler {
@SubscribeEvent @SubscribeEvent
public static void genData(GatherDataEvent event) { public static void genData(GatherDataEvent event) {
CompletableFuture<HolderLookup.Provider> holderFolder = event.getLookupProvider(); CompletableFuture<HolderLookup.Provider> holderFolder = event.getLookupProvider();
ExistingFileHelper existingFileHelper = event.getExistingFileHelper(); ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
/*Language Provider ENGLISH CHINESE(SIM/TRA)*/ /*Language Provider ENGLISH CHINESE(SIM/TRA)*/
addLanguage(event, LanguageEnum.English); addLanguage(event, LanguageEnum.English);
@ -29,7 +29,6 @@ public class ModDataGeneratorHandler {
ItemModelGenerator(event, existingFileHelper); ItemModelGenerator(event, existingFileHelper);
RecipeGenerator(event, holderFolder); RecipeGenerator(event, holderFolder);
ModTagsProvider(event, event.getLookupProvider(), existingFileHelper); ModTagsProvider(event, event.getLookupProvider(), existingFileHelper);
ModSoundProvider(event, existingFileHelper);
ModAdvancementProvider(event, holderFolder, existingFileHelper); ModAdvancementProvider(event, holderFolder, existingFileHelper);
} }
private static void addLanguage(GatherDataEvent event, LanguageEnum language){ private static void addLanguage(GatherDataEvent event, LanguageEnum language){
@ -45,10 +44,9 @@ public class ModDataGeneratorHandler {
); );
} }
private static void RecipeGenerator(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> future) { private static void RecipeGenerator(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> future) {
PackOutput packOutput = event.getGenerator().getPackOutput();
event.getGenerator().addProvider( event.getGenerator().addProvider(
event.includeServer(), event.includeServer(),
new ModRecipeProvider.Runner(packOutput, future) (DataProvider.Factory<ModRecipeProvider>) pOutput -> new ModRecipeProvider(pOutput, future)
); );
} }
private static void ModTagsProvider(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> completableFuture, ExistingFileHelper helper) { private static void ModTagsProvider(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> completableFuture, ExistingFileHelper helper) {
@ -63,13 +61,7 @@ public class ModDataGeneratorHandler {
new ModItemTagProvider(pOutput, completableFuture, modBlockTagProvider.contentsGetter(), helper) new ModItemTagProvider(pOutput, completableFuture, modBlockTagProvider.contentsGetter(), helper)
); );
} }
private static void ModSoundProvider(GatherDataEvent event, ExistingFileHelper helper) {
event.getGenerator().addProvider(
event.includeServer(),
(DataProvider.Factory<ModSoundDefinitionsProvider>) pOutput ->
new ModSoundDefinitionsProvider(pOutput,LeashedPlayer.MOD_ID, helper)
);
}
private static void ModDataPackBuiltInEntriesProvider(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> future) { private static void ModDataPackBuiltInEntriesProvider(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> future) {
event.getGenerator().addProvider( event.getGenerator().addProvider(
event.includeServer(), event.includeServer(),

View File

@ -10,9 +10,7 @@ import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.AdvancementType; import net.minecraft.advancements.AdvancementType;
import net.minecraft.advancements.critereon.*; import net.minecraft.advancements.critereon.*;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
@ -28,7 +26,6 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
private final ResourceLocation ADV_BG = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/gui/advancements/backgrounds/leashed_player.png"); private final ResourceLocation ADV_BG = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/gui/advancements/backgrounds/leashed_player.png");
@Override @Override
public void generate(HolderLookup.@NotNull Provider registries, @NotNull Consumer<AdvancementHolder> saver, @NotNull ExistingFileHelper existingFileHelper) { public void generate(HolderLookup.@NotNull Provider registries, @NotNull Consumer<AdvancementHolder> saver, @NotNull ExistingFileHelper existingFileHelper) {
HolderGetter<EntityType<?>> holdergetter = registries.lookupOrThrow(Registries.ENTITY_TYPE);
AdvancementHolder hasLeashRopeItem = Advancement.Builder.advancement().display( AdvancementHolder hasLeashRopeItem = Advancement.Builder.advancement().display(
Items.LEAD, Items.LEAD,
Component.translatable(ModAdvancementKey.LEASH_START.getNameKey()), Component.translatable(ModAdvancementKey.LEASH_START.getNameKey()),
@ -77,7 +74,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
true, true,
true true
).addCriterion("leash_self", LeashPlayerTrigger.TriggerInstance.LeashPlayer( ).addCriterion("leash_self", LeashPlayerTrigger.TriggerInstance.LeashPlayer(
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, EntityType.LEASH_KNOT)) EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(EntityType.LEASH_KNOT))
)) ))
.parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASHED_SELF.getNameWithNameSpace()); .parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASHED_SELF.getNameWithNameSpace());
AdvancementHolder followLeashRopeArrow = Advancement.Builder.advancement().display( AdvancementHolder followLeashRopeArrow = Advancement.Builder.advancement().display(
@ -90,7 +87,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
false, false,
true true
).addCriterion("leash_arrow", LeashPlayerTrigger.TriggerInstance.LeashPlayer( ).addCriterion("leash_arrow", LeashPlayerTrigger.TriggerInstance.LeashPlayer(
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, ModEntityRegister.LEASH_ROPE_ARROW.get())) EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(ModEntityRegister.LEASH_ROPE_ARROW.get()))
)) ))
.parent(hasLeashRopeArrow) .parent(hasLeashRopeArrow)
.save(saver, ModAdvancementKey.FOLLOW_LEASH_ARROW.getNameWithNameSpace()); .save(saver, ModAdvancementKey.FOLLOW_LEASH_ARROW.getNameWithNameSpace());
@ -104,7 +101,7 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
true, true,
true true
).addCriterion("leash_by_wo_do", LeashPlayerTrigger.TriggerInstance.LeashPlayer( ).addCriterion("leash_by_wo_do", LeashPlayerTrigger.TriggerInstance.LeashPlayer(
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, EntityType.WOLF)) EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(EntityType.WOLF))
)) ))
.parent(hasLeashRopeArrow).save(saver, ModAdvancementKey.DOG_RUNNING_PLAYER.getNameWithNameSpace()); .parent(hasLeashRopeArrow).save(saver, ModAdvancementKey.DOG_RUNNING_PLAYER.getNameWithNameSpace());
@ -119,22 +116,10 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
true true
).addCriterion("leash_other_player", ).addCriterion("leash_other_player",
LeashPlayerTrigger.TriggerInstance.LeashPlayer( LeashPlayerTrigger.TriggerInstance.LeashPlayer(
EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(holdergetter, EntityType.PLAYER)) EntityPredicate.Builder.entity().entityType(EntityTypePredicate.of(EntityType.PLAYER))
) )
) )
.parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASHED_FRIEND.getNameWithNameSpace()); .parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASHED_FRIEND.getNameWithNameSpace());
AdvancementHolder lead_rope_terminator = Advancement.Builder.advancement().display(
ModItemRegister.AMETHYST_SHEARS.get(),
Component.translatable(ModAdvancementKey.LEASH_TERMINATOR.getNameKey()),
Component.translatable(ModAdvancementKey.LEASH_TERMINATOR.getDescKey()),
null,
AdvancementType.TASK,
true,
true,
true
).addCriterion("has_amethyst_shears", InventoryChangeTrigger.TriggerInstance.hasItems(ModItemRegister.AMETHYST_SHEARS.get())
).parent(hasLeashRopeItem).save(saver, ModAdvancementKey.LEASH_TERMINATOR.getNameWithNameSpace());
AdvancementHolder no_leash = Advancement.Builder.advancement().display( AdvancementHolder no_leash = Advancement.Builder.advancement().display(
Items.BARRIER, Items.BARRIER,
Component.translatable(ModAdvancementKey.NO_LEASH.getNameKey()), Component.translatable(ModAdvancementKey.NO_LEASH.getNameKey()),
@ -150,29 +135,6 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG
.and(ModEffectRegister.NO_LEASH_EFFECT) .and(ModEffectRegister.NO_LEASH_EFFECT)
) )
).parent(hasLeashRopeItem).save(saver, ModAdvancementKey.NO_LEASH.getNameWithNameSpace()); ).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());
} }
} }

View File

@ -1,7 +1,6 @@
package com.r3944realms.leashedplayer.datagen.provider; package com.r3944realms.leashedplayer.datagen.provider;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs;
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants; import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.RegistrySetBuilder;
@ -14,8 +13,7 @@ import java.util.concurrent.CompletableFuture;
public class ModDataPackBuiltInEntriesProvider extends DatapackBuiltinEntriesProvider { public class ModDataPackBuiltInEntriesProvider extends DatapackBuiltinEntriesProvider {
public static final RegistrySetBuilder BUILDER = new RegistrySetBuilder() 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<HolderLookup.Provider> registries) { public ModDataPackBuiltInEntriesProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
super(output, registries, BUILDER, Set.of(LeashedPlayer.MOD_ID)); super(output, registries, BUILDER, Set.of(LeashedPlayer.MOD_ID));
CompletableFuture<HolderLookup.Provider> registryProvider = getRegistryProvider(); CompletableFuture<HolderLookup.Provider> registryProvider = getRegistryProvider();

View File

@ -46,10 +46,6 @@ public class ModItemModelProvider extends ItemModelProvider {
getBuilder("bow_lra_pulling_2") getBuilder("bow_lra_pulling_2")
.parent(new ModelFile.UncheckedModelFile("item/bow")) .parent(new ModelFile.UncheckedModelFile("item/bow"))
.texture("layer0", ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "item/bow_lra_pulling_2")); .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 @Override

View File

@ -2,14 +2,11 @@ package com.r3944realms.leashedplayer.datagen.provider;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.datagen.LanguageAndOtherData.ModItemTags;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput; import net.minecraft.data.PackOutput;
import net.minecraft.data.tags.ItemTagsProvider; import net.minecraft.data.tags.ItemTagsProvider;
import net.minecraft.tags.ItemTags; import net.minecraft.tags.ItemTags;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.data.ExistingFileHelper; import net.neoforged.neoforge.common.data.ExistingFileHelper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -25,20 +22,6 @@ public class ModItemTagProvider extends ItemTagsProvider {
protected void addTags(HolderLookup.@NotNull Provider pProvider) { protected void addTags(HolderLookup.@NotNull Provider pProvider) {
this.tag(ItemTags.ARROWS) this.tag(ItemTags.ARROWS)
.add(ModItemRegister.LEASH_ROPE_ARROW.get()) .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());
} }
} }

View File

@ -1,37 +1,34 @@
package com.r3944realms.leashedplayer.datagen.provider; package com.r3944realms.leashedplayer.datagen.provider;
import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.content.items.repcipe.TippedLeashRopeArrowRecipe;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput; import net.minecraft.data.PackOutput;
import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.*;
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 net.minecraft.world.item.Items;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class ModRecipeProvider extends RecipeProvider { public class ModRecipeProvider extends RecipeProvider {
public ModRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { public ModRecipeProvider(PackOutput pOutput, CompletableFuture<HolderLookup.Provider> future) {
super(registries, output); super(pOutput, future);
} }
@Override @Override
protected void buildRecipes() { protected void buildRecipes(@NotNull RecipeOutput pRecipeOutput) {
this.shapeless(RecipeCategory.MISC, ModItemRegister.LEASH_ROPE_ARROW.get(), 1)
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItemRegister.LEASH_ROPE_ARROW.get(),1)
.requires(Items.LEAD) .requires(Items.LEAD)
.requires(Items.ARROW) .requires(Items.ARROW)
.unlockedBy("has_lead",has(Items.LEAD)) .unlockedBy("has_lead",has(Items.LEAD))
.save(this.output); .save(pRecipeOutput);
this.shapeless(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1) ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1)
.requires(Items.LEAD) .requires(Items.LEAD)
.requires(Items.SPECTRAL_ARROW) .requires(Items.SPECTRAL_ARROW)
.unlockedBy("has_lead",has(Items.LEAD)) .unlockedBy("has_lead",has(Items.LEAD))
.unlockedBy("has_spectral_arrow",has(Items.SPECTRAL_ARROW)) .unlockedBy("has_spectral_arrow",has(Items.SPECTRAL_ARROW))
.save(this.output); .save(pRecipeOutput, "spectral_leash_rope_arrow_with_leash_rope_arrow");
this.shaped(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1) ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1)
.pattern(" $ ") .pattern(" $ ")
.pattern("$#$") .pattern("$#$")
.pattern(" $ ") .pattern(" $ ")
@ -39,33 +36,7 @@ public class ModRecipeProvider extends RecipeProvider {
.define('$', Items.GLOWSTONE_DUST) .define('$', Items.GLOWSTONE_DUST)
.unlockedBy("has_lead",has(Items.LEAD)) .unlockedBy("has_lead",has(Items.LEAD))
.unlockedBy("has_glowstone_dust",has(Items.GLOWSTONE_DUST)) .unlockedBy("has_glowstone_dust",has(Items.GLOWSTONE_DUST))
.save(this.output,"leash_rope_arrow_shape"); .save(pRecipeOutput,"spectral_leash_rope_arrow_with_glowstone_dust");
this.shaped(RecipeCategory.MISC, ModItemRegister.AMETHYST_SHEARS.get(),1)
.pattern("#%")
.pattern("%#")
.define('#', Items.AMETHYST_SHARD)
.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 {
public Runner(PackOutput pPackOutput, CompletableFuture<HolderLookup.Provider> providerCompletableFuture) {
super(pPackOutput, providerCompletableFuture);
}
@Override
@NotNull
public RecipeProvider createRecipeProvider(HolderLookup.@NotNull Provider provider, @NotNull RecipeOutput output) {
return new ModRecipeProvider(provider, output);
}
@Override
public @NotNull String getName() {
return "LeashedPlayer Recipes";
}
} }

View File

@ -1,37 +0,0 @@
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)
)
);
}
}

View File

@ -1,39 +0,0 @@
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<JukeboxSong> FOX_MUSIC = create("what_does_the_fox_say");
public static void bootstrap(BootstrapContext<JukeboxSong> pContext) {
JukeboxSongBootstrap(pContext);
}
public static void JukeboxSongBootstrap(BootstrapContext<JukeboxSong> pContext) {
register(pContext, FOX_MUSIC, ModSoundRegister.FOX_MUSIC, 121, 15);
}
private static void register(
BootstrapContext<JukeboxSong> pContext, ResourceKey<JukeboxSong> pKey, Holder<SoundEvent> 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<JukeboxSong> create(String pName) {
return ResourceKey.create(Registries.JUKEBOX_SONG, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, pName));
}
}

View File

@ -3,13 +3,10 @@ package com.r3944realms.leashedplayer.datagen.provider.attributes;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.data.worldgen.BootstrapContext;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.decoration.PaintingVariant; import net.minecraft.world.entity.decoration.PaintingVariant;
import java.util.Optional;
public class ModPaintingVariants { public class ModPaintingVariants {
public static final ResourceKey<PaintingVariant> GROUP_PHOTO = create("group_photo"); public static final ResourceKey<PaintingVariant> GROUP_PHOTO = create("group_photo");
@ -17,10 +14,10 @@ public class ModPaintingVariants {
PaintingVariantBootstrap(pContext); PaintingVariantBootstrap(pContext);
} }
public static void PaintingVariantBootstrap(BootstrapContext<PaintingVariant> pContext) { public static void PaintingVariantBootstrap(BootstrapContext<PaintingVariant> pContext) {
ModPaintingVariants.register(pContext, ModPaintingVariants.GROUP_PHOTO, 4, 3, Component.translatable(ModPaintingVariants.getPaintingVariantTitleKey(ModPaintingVariants.GROUP_PHOTO)), Component.translatable(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO))); ModPaintingVariants.register(pContext, ModPaintingVariants.GROUP_PHOTO, 4, 3);
} }
private static void register(BootstrapContext<PaintingVariant> pContext, ResourceKey<PaintingVariant> pKey, int pWidth, int pHeight, Component title, Component author) { private static void register(BootstrapContext<PaintingVariant> pContext, ResourceKey<PaintingVariant> pKey, int pWidth, int pHeight) {
pContext.register(pKey, new PaintingVariant(pWidth, pHeight, pKey.location(), Optional.of(title), Optional.of(author))); pContext.register(pKey, new PaintingVariant(pWidth, pHeight, pKey.location()));
} }
private static ResourceKey<PaintingVariant> create(String pName) { private static ResourceKey<PaintingVariant> create(String pName) {
return ResourceKey.create(Registries.PAINTING_VARIANT, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, pName)); return ResourceKey.create(Registries.PAINTING_VARIANT, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, pName));

View File

@ -1,10 +1,8 @@
package com.r3944realms.leashedplayer.mixin.both; package com.r3944realms.leashedplayer.mixin.both;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.Leashable;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -14,8 +12,6 @@ import org.spongepowered.asm.mixin.injection.Redirect;
public abstract class MixinEntity { public abstract class MixinEntity {
@Shadow public abstract void igniteForSeconds(float pSeconds); @Shadow public abstract void igniteForSeconds(float pSeconds);
@Shadow public abstract Level level();
/** /**
* 这里重定向当实体类实现了{@link PlayerLeashable}接口时<br/> * 这里重定向当实体类实现了{@link PlayerLeashable}接口时<br/>
* 阻止原版的{@link Leashable} 的tickLeash方法调用将其<br/> * 阻止原版的{@link Leashable} 的tickLeash方法调用将其<br/>
@ -25,11 +21,11 @@ public abstract class MixinEntity {
*/ */
@Redirect( @Redirect(
method = "baseTick", method = "baseTick",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Leashable;tickLeash(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Entity;)V") at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Leashable;tickLeash(Lnet/minecraft/world/entity/Entity;)V")
) )
<E extends Entity & Leashable> void checkAndCancelIfTure(ServerLevel f, E entity) { <E extends Entity & Leashable> void checkAndCancelIfTure(E entity) {
if(!(entity instanceof PlayerLeashable) && level() instanceof ServerLevel serverLevel_) { if(!(entity instanceof PlayerLeashable)) {
Leashable.tickLeash(serverLevel_, entity); Leashable.tickLeash(entity);
} }
} }

View File

@ -2,6 +2,7 @@ package com.r3944realms.leashedplayer.mixin.both;
import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.commands.LeashCommand; 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.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
@ -11,6 +12,7 @@ import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.Leashable;
@ -201,6 +203,12 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl
ILivingEntityExtension iEntityExtension = this;//获取设定值 ILivingEntityExtension iEntityExtension = this;//获取设定值
float leashLengthSelf = iEntityExtension.getLeashLength(); float leashLengthSelf = iEntityExtension.getLeashLength();
leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE; 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) { if (entity != null) {
double breakDistanceTime = (entity instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1(); 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)){ if(!isAlive() || !entity.isAlive() ||( distanceTo(entity) > Math.max(leashLength * breakDistanceTime, LeashCommand.MIN_VALUE * breakDistanceTime) && keepLeashTick == 0)){

View File

@ -0,0 +1,30 @@
package com.r3944realms.leashedplayer.mixin.client;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(EntityRenderer.class)
public abstract class MixinEntityRenderer {
@Redirect(
method = {"renderLeash"},
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/Entity;getLeashOffset(F)Lnet/minecraft/world/phys/Vec3;"
)
)
private @NotNull Vec3 ret(Entity instance, float pPartialTick) {
if(instance instanceof AbstractClientPlayer) {
//为了使拴绳在在第三视角下位于玩家脖子处
return instance.getLeashOffset(pPartialTick).add(0, -0.2, -0.2);//TODO:待擴展Vec3
}
return instance.getLeashOffset(pPartialTick);//非实现这个接口则不变
}
}

View File

@ -1,12 +1,27 @@
package com.r3944realms.leashedplayer.mixin.client; package com.r3944realms.leashedplayer.mixin.client;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.r3944realms.leashedplayer.client.renders.LeashRendererUtil; import com.mojang.datafixers.util.Either;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import net.minecraft.client.Camera; import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker; import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
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.joml.Matrix4f; import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -16,7 +31,8 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;
@Mixin(LevelRenderer.class) @Mixin(LevelRenderer.class)
public abstract class MixinLevelRenderer { public abstract class MixinLevelRenderer {
@ -24,19 +40,91 @@ public abstract class MixinLevelRenderer {
@Nullable @Nullable
private ClientLevel level; private ClientLevel level;
@Shadow protected abstract void renderEntity(Entity pEntity, double pCamX, double pCamY, double pCamZ, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource);
@Shadow @Final
private Minecraft minecraft;
@Shadow @Final private RenderBuffers renderBuffers; @Shadow @Final private RenderBuffers renderBuffers;
@Inject( @Inject(
method = {"renderLevel"}, method = {"renderLevel"},
at = @At(value = "HEAD") at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/RenderBuffers;bufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;",
shift = At.Shift.AFTER
) )
private void renderLevel(GraphicsResourceAllocator pGraphicsResourceAllocator, DeltaTracker pDeltaTracker, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pFrustumMatrix, Matrix4f pProjectionMatrix, CallbackInfo ci) { )
private void renderLevel(DeltaTracker pDeltaTracker, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pFrustumMatrix, Matrix4f pProjectionMatrix, CallbackInfo ci) {
assert this.level != null; assert this.level != null;
PoseStack poseStack = new PoseStack(); PoseStack poseStack = new PoseStack();
MultiBufferSource.BufferSource multibuffersource$buffersource = this.renderBuffers.bufferSource(); MultiBufferSource.BufferSource multibuffersource$buffersource = this.renderBuffers.bufferSource();
LeashRendererUtil.levelRenderLeash(level, pCamera, poseStack, multibuffersource$buffersource); for(Entity entity : this.level.entitiesForRendering()) {
} //对于玩家实体拴绳渲染从第一人称视角
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;
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
if(delayedLeashInfo != null) {
float partialTickTime = pCamera.getPartialTickTime();
Vec3 position = pCamera.getPosition();
double dX = Mth.lerp(partialTickTime, abstractClientPlayer.xOld, abstractClientPlayer.getX()) - position.x;
double dY = Mth.lerp(partialTickTime, abstractClientPlayer.yOld, abstractClientPlayer.getY()) - position.y;
double dZ = Mth.lerp(partialTickTime, abstractClientPlayer.zOld, abstractClientPlayer.getZ()) - position.z;
Vec3 vec3 = playerRenderer.getRenderOffset(abstractClientPlayer, partialTickTime);
double dX_ = dX + vec3.x();
double dY_ = dY + vec3.y();
double dZ_ = dZ + vec3.z();
poseStack.pushPose();
poseStack.translate(dX_, dY_, dZ_);
ClientLevel level = mc.level;
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
assert level != null;
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()));
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
assert level != null;
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
if (playerByUUID != null) {
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID);
} else {
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
List<Entity> entities = level.getEntities(
null,
new AABB(
abstractClientPlayer.getX() - MaxLeashLength,
abstractClientPlayer.getY() - MaxLeashLength,
abstractClientPlayer.getZ() - MaxLeashLength,
abstractClientPlayer.getX() + MaxLeashLength,
abstractClientPlayer.getY() + MaxLeashLength,
abstractClientPlayer.getZ() + MaxLeashLength
)
);
Entity holder = null;
for (Entity entity_ : entities) {
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
holder = entity_;
break;
}
}
if (holder != null) {
if(holder instanceof LeashRopeArrow) {
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3吗
}
else playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder);
}
}
break;
}
}
}
}
}
}
} }

View File

@ -1,39 +0,0 @@
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;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@SuppressWarnings({"AddedMixinMembersNamePattern"})
@Mixin(PlayerRenderState.class)
public class MixinPlayerRenderState implements IPlayerRenderStateExtension {
@Unique
@Nullable
private PlayerLeashState playerLeashState;
@Unique
private PlayerSlotItemLayerState playerSlotItemLayerState;
@Override
public @Nullable PlayerLeashState getPlayerLeashState() {
return playerLeashState;
}
@Override
public void setPlayerLeashState(@Nullable PlayerLeashState playerRenderState) {
this.playerLeashState = playerRenderState;
}
@Override
public PlayerSlotItemLayerState getPlayerSlotItemLayerState() {
return playerSlotItemLayerState;
}
@Override
public void setPlayerSlotItemLayerState(PlayerSlotItemLayerState playerRenderState) {
this.playerSlotItemLayerState = playerRenderState;
}
}

View File

@ -1,30 +1,275 @@
package com.r3944realms.leashedplayer.mixin.client; package com.r3944realms.leashedplayer.mixin.client;
import com.r3944realms.leashedplayer.client.renders.LeashRendererUtil; import com.mojang.blaze3d.vertex.PoseStack;
import com.r3944realms.leashedplayer.client.renders.PlayerSlotItemLayerState; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension; import com.mojang.datafixers.util.Either;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension; import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.client.renderer.entity.state.PlayerRenderState; import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.UUID;
@Mixin(PlayerRenderer.class) @Mixin(PlayerRenderer.class)
public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, PlayerRenderState, PlayerModel> implements IPlayerRendererExtension { public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> implements IPlayerRendererExtension {
public MixinPlayerRenderer(EntityRendererProvider.Context pContext, PlayerModel pModel, float pShadowRadius) { public MixinPlayerRenderer(EntityRendererProvider.Context pContext, PlayerModel<AbstractClientPlayer> pModel, float pShadowRadius) {
super(pContext, pModel, pShadowRadius); super(pContext, pModel, pShadowRadius);
} }
@Inject(method = {"extractRenderState(Lnet/minecraft/client/player/AbstractClientPlayer;Lnet/minecraft/client/renderer/entity/state/PlayerRenderState;F)V"}, at = @At("TAIL"))
public void extractRenderState(AbstractClientPlayer abstractClientPlayer, PlayerRenderState playerRenderState, float partTicks, CallbackInfo ci) { @Inject(
LeashRendererUtil.createPlayerLeashState(abstractClientPlayer, (IPlayerRenderStateExtension) playerRenderState, partTicks); at = @At("HEAD"),
((IPlayerRenderStateExtension)playerRenderState).setPlayerSlotItemLayerState(new PlayerSlotItemLayerState(abstractClientPlayer)); method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V"
)
private void renderMixin(AbstractClientPlayer pEntity, float pEntityYaw, float pPartialTicks, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight, CallbackInfo ci) {
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) pEntity).getLeashDataFromEntityData();
if(leashDataFromEntityData == null) return;
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
if(delayedLeashInfo != null) {
Minecraft mc = Minecraft.getInstance();
ClientLevel level = mc.level;
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
assert level != null;
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()));
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
assert level != null;
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
if (playerByUUID != null) {
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, playerByUUID);
} else {
double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
double MaxLeashLength = ((ILivingEntityExtension) pEntity).getLeashLength() * breakDistanceTime;
List<Entity> entities = level.getEntities(
null,
new AABB(
pEntity.getX() - MaxLeashLength,
pEntity.getY() - MaxLeashLength,
pEntity.getZ() - MaxLeashLength,
pEntity.getX() + MaxLeashLength,
pEntity.getY() + MaxLeashLength,
pEntity.getZ() + MaxLeashLength
)
);
Entity holder = null;
for (Entity entity_ : entities) {
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
holder = entity_;
break;
}
}
if (holder != null) {
if(holder instanceof LeashRopeArrow) {
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder, new Vec3(0,0, 0));//TODO: 待擴展Vec3
}
else renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder);
}
}
}
}
}
/**
* <h1>1. 角度与弧度转换</h1>
* {@snippet lang=java :
* double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float)(Math.PI / 180.0)) + (Math.PI / 2);
* }
* <ul>
* <li><code>pEntity.getPreciseBodyRotation(pPartialTick)</code> 返回实体的旋转角度通常是以度为单位/li>
* <li> <code>(Math.PI / 180.0)</code> 是将度数转换为弧度的乘数因为大多数三角函数 <code>cos</code> <code>sin</code>都需要弧度值</li>
* <li><code>+ (Math.PI / 2)</code> 用于将结果平移90度四分之一圆可能是为了校正方向或设置起始方向 </li>
* </ul>
*
* <p>
* <h1> 2. 三角函数计算位移</h1>
* {@snippet lang=java :
* double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
* double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
* }
* <ul>
* <li><code>d1</code> <code>d2</code> 是利用三角函数 <code>cos</code> <code>sin</code> 计算出来的位移量用于确定实体相对于其旋转的实际位置</li>
* <li><code>Math.cos(d0) * vec31.z</code> <code>Math.sin(d0) * vec31.x</code> 分别计算沿 X Z 轴的位移分量这种计算通常用于旋转一个点或向量</li>
* <li>两个公式结合起来用于旋转平面内的一个点 <code>(vec31.x, vec31.z)</code>从而得到旋转后的新坐标</li>
* </ul>
* <p>
* <h1> 3. 线性插值 (Lerp) </h1>
* {@snippet lang=java :
* double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
* double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
* double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
* }
* <ul>
* <li><code>Mth.lerp</code> 是线性插值函数通常用于在两个值之间平滑过渡</li>
* <li><code>pEntity.xo</code>, <code>pEntity.yo</code>, <code>pEntity.zo</code> 是实体在上一个刻度tick中的位置 <code>pEntity.getX()</code>, <code>pEntity.getY()</code>, <code>pEntity.getZ()</code> 是当前刻度的位置</li>
* <li><code>pPartialTick</code> 介于 <code>0</code> <code>1</code> 之间用来平滑过渡使得动画更加流畅</li>
* </ul>
* <p>
* <h1> 4. 向量差值 </h1>
* {@snippet lang=java :
* float f = (float)(vec3.x - d3);
* float f1 = (float)(vec3.y - d4);
* float f2 = (float)(vec3.z - d5);
* }
* <ul>
* <li>计算两个点<code>vec3</code> <code>(d3, d4, d5)</code>之间的差值得到的 <code>f</code><code>f1</code><code>f2</code> 是向量差用于后续的渲染计算</li>
* </ul>
* <p>
* <h1> 5. 逆平方根与比例因子 </h1>
* {@snippet lang=java :
* float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
* }
* <ul>
* <li><code>Mth.invSqrt</code> 计算的是逆平方根通常用于归一化向量或调整比例</li>
* <li><code>f * f + f2 * f2</code> 是计算向量 <code>(f, f2)</code> 的平方和用于得到其长度的平方</li>
* <li>乘以 <code>0.025F / 2.0F</code> 用于缩放结果使得线条在渲染时具有合适的比例</li>
* </ul>
* <p>
* <h1> 6. 循环绘制 </h1>
* {@snippet lang=java :
* for (int i1 = 0; i1 <= 24; i1++) {
* addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
* }
* }
* <ul>
* <li>循环从 <code>0</code> <code>24</code>用于创建24个顶点对形成一个链状结构或绳索的外观</li>
* <li>每个循环迭代都会更新顶点的位置颜色光照等属性使得链状结构被绘制出来</li>
* </ul>
* <p>
* <h1> 总结 </h1>
* 这些数学运算主要用于计算实体在三维空间中的位置和方向以确保在渲染链状结构如拴住的绳索链条能够跟随实体的移动和旋转并正确显示在图形编程中这些计算非常常见尤其是在处理旋转插值和光照效果时
*/
@SuppressWarnings("AddedMixinMembersNamePattern")
@Unique
public <E extends net.minecraft.world.entity.Entity> void renderLeashForCamera(
Camera camera,
float partialTick,
com.mojang.blaze3d.vertex.PoseStack poseStack,
net.minecraft.client.renderer.MultiBufferSource bufferSource,
E leashHolder,
Vec3 holderOffset
) {
poseStack.pushPose();
// 获得绳索持有者的位置
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick).add(holderOffset);
// 获取当前观察的实体
Entity cameraEntity = camera.getEntity();
// 计算实体的朝向角度弧度
double entityRotationAngleRadians = (double)(cameraEntity.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
// 计算实体的绳索偏移此处add偏移让渲染拴绳显示在玩家头部下大约在脖子处
Vec3 cameraEntityLeashOffset = cameraEntity.getLeashOffset(partialTick).add(0, -0.2, -0.5);
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
// 计算实体当前的实际位置
double entityPosX = Mth.lerp(partialTick, cameraEntity.xo, cameraEntity.getX()) + leashOffsetX;
double entityPosY = Mth.lerp(partialTick, cameraEntity.yo, cameraEntity.getY()) + cameraEntityLeashOffset.y;
double entityPosZ = Mth.lerp(partialTick, cameraEntity.zo, cameraEntity.getZ()) + leashOffsetZ;
// 在当前变换矩阵上应用偏移
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y , leashOffsetZ);
// 计算绳索的相对位置差
float deltaX = (float)(leashHolderPosition.x - entityPosX);
float deltaY = (float)(leashHolderPosition.y - entityPosY);
float deltaZ = (float)(leashHolderPosition.z - entityPosZ);
// 获取顶点消费者用于绘制绳索
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.leash());
Matrix4f matrix = poseStack.last().pose();
// 计算比例因子用于调节绳索的粗细
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
float leashXZScaleX = deltaZ * leashLengthRatio;
float leashXZScaleZ = deltaX * leashLengthRatio;
// 获取光照信息
BlockPos cameraEntityBlockPos = BlockPos.containing(cameraEntity.getEyePosition(partialTick));
BlockPos leashHolderBlockPos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
int cameraEntityBlockLightLevel = this.getBlockLightLevel((AbstractClientPlayer) cameraEntity, cameraEntityBlockPos);
int leashHolderBlockLightLevel = 0; //getBlockLightLevel(leashHolder, leashHolderBlockPos);
int cameraEntitySkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, cameraEntityBlockPos);
int leashHolderSkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, leashHolderBlockPos);
// 绘制绳索的上半部分
for (int segment = 0; segment <= 24; segment++) {
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.025F, leashXZScaleX, leashXZScaleZ, segment, false);
} }
// 绘制绳索的下半部分
for (int segment = 24; segment >= 0; segment--) {
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.0F, leashXZScaleX, leashXZScaleZ, segment, true);
}
poseStack.popPose();
}
@SuppressWarnings("AddedMixinMembersNamePattern")
@Unique
protected <E extends Entity> void renderLeash(AbstractClientPlayer pEntity, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource, E pLeashHolder, Vec3 holderOffset) {
pPoseStack.pushPose();
Vec3 vec3 = pLeashHolder.getRopeHoldPosition(pPartialTick).add(holderOffset);
double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
Vec3 vec31 = pEntity.getLeashOffset(pPartialTick).add(0, -0.2, -0.2);//TODO:待擴展Vec3);
double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
pPoseStack.translate(d1, vec31.y, d2);
float f = (float)(vec3.x - d3);
float f1 = (float)(vec3.y - d4);
float f2 = (float)(vec3.z - d5);
float f3 = 0.025F;
VertexConsumer vertexconsumer = pBufferSource.getBuffer(RenderType.leash());
Matrix4f matrix4f = pPoseStack.last().pose();
float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
float f5 = f2 * f4;
float f6 = f * f4;
BlockPos blockpos = BlockPos.containing(pEntity.getEyePosition(pPartialTick));
BlockPos blockpos1 = BlockPos.containing(pLeashHolder.getEyePosition(pPartialTick));
int i = this.getBlockLightLevel(pEntity, blockpos);
int j = 0;
int k = pEntity.level().getBrightness(LightLayer.SKY, blockpos);
int l = pEntity.level().getBrightness(LightLayer.SKY, blockpos1);
for (int i1 = 0; i1 <= 24; i1++) {
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
}
for (int j1 = 24; j1 >= 0; j1--) {
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.0F, f5, f6, j1, true);
}
pPoseStack.popPose();
}
} }

View File

@ -1,16 +0,0 @@
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<Boolean> cir) {
cir.setReturnValue(true);
}
}

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