Compare commits

...

36 Commits

Author SHA1 Message Date
6f69a24ed4 202/01/03
Some checks failed
Build / build (push) Failing after 1h8m30s
4.0.0.3->4.0.0.4
1.填完了对JEI适配的坑
(希望是Teacon的)最后一个版本
2.修补可能会存在的问题
2025-01-03 22:00:58 +08:00
8490da915d 2024/12/16
4.0.0.2->4.0.0.3
2024-12-16 23:59:38 +08:00
ab54ed1521 2024/12/15
消息小调整
2024-12-16 23:56:15 +08:00
cf930334cb 2024/12/15
更新版本 4.0.0.1 -> 4.0.0.2
修复了
1.小纰漏(
2024-12-16 23:52:17 +08:00
0b5b011eb8 2024/12/16
更新版本 4.0.0.0 -> 4.0.0.1
修复了
1.第三者不可见拴绳箭的问题
调整了
1.拴绳调整消息为调整双方都可见
2024-12-16 23:10:37 +08:00
24af58d4a4 2024/12/15
更新版本 3.9.9.9 -> 4.0.0
修复了
1.创造模式不能正确拾取先前发射的拴绳箭的BUG
2.发射器里的拴绳箭不能正常关注的问题
2024-12-15 17:53:29 +08:00
8b759259ad 2024/12/07
修复发射器发射拴绳类箭矢拾取时数量直接copy发射器里的数量的BUG
2024-12-07 17:10:55 +08:00
0ecfe88683 2024/12/07
修复些可能会存在的问题
2024-12-07 13:46:04 +08:00
22fc64797d 2024/12/07
实装了贴贴拴绳箭的内容
整理了下代码结构
先推测试
2024-12-07 13:33:46 +08:00
f10221a2c0 2024/12/07
实装了贴贴拴绳箭的内容
整理了下代码结构
先推测试
2024-12-07 13:33:39 +08:00
e615fc6f09 2024/12/03
小修复
2024-12-03 10:53:36 +08:00
d53481150a 2024/12/01
小更新
修改长时间不动掉落物
2024-12-01 11:05:26 +08:00
800a60ab97 2024/11/26
联动内容#3
增加一些提示内容
添加了按键
2024-11-27 00:25:37 +08:00
52f30a4275 2024/11/26
联动内容#2
增加一些提示内容
2024-11-26 17:21:15 +08:00
b6cbcdd677 2024/11/25
提升版本号,联动内容#1
2024-11-26 07:30:49 +08:00
78c92d4e42 2024/11/24
修改了下+2
2024-11-24 22:09:08 +08:00
8e0c06f392 2024/11/24
修改了下
2024-11-24 19:53:13 +08:00
094143c522 2024/11/24
修改了下
2024-11-24 18:36:45 +08:00
c80f53d5c9 2024/11/23
进一步完善了一下
2024-11-23 19:30:26 +08:00
f81569bde3 2024/11/23
搞了一个TOP检测关闭GUI
2024-11-23 16:16:19 +08:00
eedf4b64cf 2024/11/23
搞了一个TOP检测
和重命名了
2024-11-23 11:49:24 +08:00
ce337667dc 2024/11/22
好玩(
2024-11-22 17:50:55 +08:00
00eb0e8d68 2024/11/17
修复了部分纰漏
2024-11-17 11:53:26 +08:00
f416520f5d 2024/11/16
补充了一些内容
2024-11-16 17:55:39 +08:00
db41f395f7 2024/11/11
優化了彩蛋物品的獲取方式
2024-11-11 17:40:36 +08:00
6c9f27041d 2024/11/11
添加了彩蛋物品的獲取方式
2024-11-11 13:56:19 +08:00
087f203e00 2024/11/11
修复成就BUG
添加了种新的拴绳药水箭的合成方式:药水箭+拴绳
2024-11-11 00:55:55 +08:00
17134e0d84 2024/11/11
修复成就BUG
添加了种新的拴绳药水箭的合成方式:药水箭+拴绳
2024-11-11 00:54:07 +08:00
e236e4a718 2024/11/08
优化部分逻辑
扩展了新的箭矢
添加了使用时的音效
2024-11-08 22:09:13 +08:00
7f8b24beb8 2024/11/05
Expend Item Capacity
2024-11-05 23:07:42 +08:00
7d0ae3beef 2024/11/02
Update version
2024-11-03 13:49:24 +08:00
6471f956fa 2024/11/02
Add New Entity
2024-11-03 12:37:33 +08:00
3cb1cc3ccc 2024/11/02
Fix some little bug
Add areaTalk Command
2024-11-02 23:25:07 +08:00
6fcdbefe61 2024/11/01
Up
2024-11-01 07:41:27 +08:00
b4f592be46 2024/11/01
Fix some BUG and Add new Item to break lead rope
2024-11-01 00:13:56 +08:00
0cce76511f 2024-10-28
修复了有关箭不能正常显示的BUG
将默认值调高减少拴绳断裂的可能性
2024/10/28
Fix some BUG
2024-10-28 22:47:18 +08:00
142 changed files with 4104 additions and 424 deletions

View File

@ -1,4 +1,4 @@
# 版本 0.0.3.9.4 提前介绍c[最终版本对于0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
# 版本 0.0.4.0.4 提前介绍c[没有BUG的话TeaCon最终版本将会是0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
## 简介
现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧(
@ -15,9 +15,11 @@
4. 拴绳箭最大存活时间
## 新物品 和 实体
### 拴绳箭 [有普通和荧光种箭矢]
### 拴绳箭 [有普通和荧光和药水三种箭矢]
获得飞一样的感觉(操作不当可能会摔死
+ 拴绳箭可以拴其它可拴LivingEntity了
### 紫水晶剪刀
剪断拴绳链接,在发射器里可使用,对自己也可使用,但耗费更多耐久
#### 射中实体时会将射击者拴绳绑定在改实体上该实体父类必须是有LivingEntity类型同时拴绳箭会以普通的箭矢掉落
#### 射中栅栏时,会自动将玩家拴在上面 ,同时拴绳箭会以普通的箭矢掉落
#### 在地面上的箭可以通过按Shift靠近来捡起如果捡起实体为发射箭矢玩家则直接获取拴绳箭矢如果捡起者为非发射者则成为发送者的拴绳持有者并获得普通箭矢
@ -42,8 +44,13 @@
* `/lp motion [<实体[可多个对象]>] add/set/multiply <x> <y> <z>` - 给实体添加/设置/倍乘 加速度
* `/lp talkArea <[<玩家[可多个对象]>]> set/setPreference/unlimited/currentConfig <数值>` - 设置玩家聊天可见半径/设置半径预期/应用预期/取消限制/获取目前配置
* `/lp tick ...` - 用法同原版Tick但权限降为2只用于调试切勿滥用后期考虑可能写成区域性的
* `/lp debug ...` - Debug指令未来可能会移除
## 游戏规则
* `LP.TeleportWithLeashedPlayers` - 此規則啓用后, 被栓玩家將會随玩家拴绳持有者一起传送 [默认值: True]
@ -52,4 +59,12 @@
* `LP.KeepLeashNotDropTime` - 此规则决定,当拴绳关系创建时一段时间里,即是距离已经达到了断裂距离,也保持其不断裂 [默认值: 240ticks ,可设置范围[80, 1200]ticks]
* `LP.DisableMoveCheck` - 此规则启用将会禁止服务器对玩家进行速度过快修正 [默认值: True]
* `LP.DefaultTalkArea` - 此规则决定,聊天半径最小正值 [默认值: -1]
* `LP.OpenTOPNeededModeWhenScreenIsNotNull` - 此规则决定,是否在在打开 屏幕{除Top的NoteGui 和 聊天GUI外} 情况下改变Top的显示模式为NEEDED [默认值: true]
* `LP.CanCommonPlayerChangeSelfTalkArea` - 此规则决定,是否普通玩家可以修改自己的聊天可见区域 [默认值: true]
## 联动内容
# 与Nestle 的 贴贴拴绳箭
射中实体生成贴贴拴绳实体并绑定在一起,解除需用到贴贴拴绳(不太好个人觉得)

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

8
Resource/neoforge.json Normal file
View File

@ -0,0 +1,8 @@
{
"credit": "Made with Blockbench",
"parent": "minecraft:item/generated",
"textures": {
"1": "leashedplayer:item/neoforge",
"particle": "leashedplayer:item/neoforge"
}
}

BIN
Resource/nestle-0.1.1.jar Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

View File

@ -19,6 +19,19 @@ version = mod_version
group = mod_group_id
repositories {
maven {
// location of the maven that hosts JEI files since January 2023
name = "Jared's maven"
url = "https://maven.blamejared.com/"
}
maven {
// location of a maven mirror for JEI files, as a fallback
name = "ModMaven"
url = "https://modmaven.dev"
}
maven { // TOP
url "https://maven.k-4u.nl"
}
mavenLocal()
}
@ -59,7 +72,6 @@ runs {
server {
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
programArgument '--nogui'
}
// This run config launches GameTestServer and runs all registered gametests, then exits.
@ -97,7 +109,14 @@ dependencies {
// And its provides the option to then use net.minecraft as the group, and one of; client, server or joined as the module name, plus the game version as version.
// For all intends and purposes: You can treat this dependency as if it is a normal library you would use.
implementation "net.neoforged:neoforge:${neo_version}"
compileOnly "mcjty.theoneprobe:theoneprobe:${top_version}"
runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
// compile against the JEI API but do not include it at runtime
compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
compileOnly(files("Resource/nestle-0.1.1.jar"))
runtimeOnly(files("Resource/nestle-0.1.1.jar"))
// at runtime, use the full JEI jar for NeoForge
// compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
// Example optional mod dependency with JEI
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
@ -157,6 +176,16 @@ publishing {
maven {
url "file://${project.projectDir}/repo"
}
// maven {
// // location of the maven that hosts JEI files since January 2023
// name = "Jared's maven"
// url = "https://maven.blamejared.com/"
// }
// maven {
// // location of a maven mirror for JEI files, as a fallback
// name = "ModMaven"
// url = "https://modmaven.dev"
// }
}
}

View File

@ -21,7 +21,10 @@ neo_version=21.0.157
neo_version_range=[21.0.0-beta,)
# The loader version range can only use the major version of FML as bounds
loader_version_range=[4,)
top_version = 1.21_neo-12.0.4-6
#jei_setting
jei_version=19.8.2.99
mc_version=1.21
## Mod Properties
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
@ -32,7 +35,7 @@ mod_name=Leashed Player
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT
# The mod version. See https://semver.org/
mod_version=0.0.3.9.4
mod_version=0.0.4.0.4
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View File

@ -9,3 +9,5 @@ pluginManagement {
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
}
include 'leashedplayer_1_21_3'

View File

@ -1,8 +1,16 @@
// 1.21 2024-10-23T13:15:06.1102778 Item Models: leashedplayer
// 1.21 2024-11-25T23:55:52.7726677 Item Models: leashedplayer
766c487fbf0c59e9045eeaf81daf583eb679b0e1 assets/leashedplayer/models/item/amethyst_shears.json
5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json
845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json
5bd1f9f28b91005c587f1c38fb77cd19b59495e3 assets/leashedplayer/models/item/bow_lra_pulling_2.json
90909de0fcb2a6b0b9731bb998f8d866841de6d2 assets/leashedplayer/models/item/bow_nra_pulling_0.json
de6fed69522a94812c66ba1864ae6df7465aad9c assets/leashedplayer/models/item/bow_nra_pulling_1.json
1e34de6579d5c250eff9871e589c584d888c3c6d assets/leashedplayer/models/item/bow_nra_pulling_2.json
83946f4d60d0fb1758d6553c36330506c8e48ada assets/leashedplayer/models/item/crossbow_leash_rope_arrow.json
7d9d1678faf41b58d2934d0335f700e17c372c10 assets/leashedplayer/models/item/crossbow_nestle_rope_arrow.json
bb0d76077719c83c8a8bd4346a24ea1766175125 assets/leashedplayer/models/item/fabric.json
63ec6c618a3a23eab4cab9c52d7d3250de9b516e assets/leashedplayer/models/item/kid_spawn_egg.json
114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json
f77241714f5233f127eee3c7521b448add1eaad2 assets/leashedplayer/models/item/nestle_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,2 +1,3 @@
// 1.21 2024-10-23T13:15:06.1082841 Registries
// 1.21 2024-11-05T23:00:18.5223698 Registries
f2536789df7f06362718a59ba4a96890e2f9b8aa data/leashedplayer/jukebox_song/what_does_the_fox_say.json
6f79a674215db9f9d2820b1c7f052c60ce729fee data/leashedplayer/painting_variant/group_photo.json

View File

@ -1,2 +1,7 @@
// 1.21 2024-10-23T13:15:06.1012494 Tags for minecraft:item mod id leashedplayer
36c1cccc1dfa448620c4e9cbc4a7d73986ff9e47 data/minecraft/tags/item/arrows.json
// 1.21 2024-11-25T23:24:58.9769291 Tags for minecraft:item mod id leashedplayer
84707301f1fe2490a899deb51302d413cfff5a89 data/c/tags/item/tools/shear.json
a91f0f4956d65c981d76c9f41de5272b2e0b5786 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 2024-10-23T14:43:16.8619078 Languages: en_us for mod: leashedplayer
4dc2ca922a540c7133a4a6867dfcd8bfec5a1db4 assets/leashedplayer/lang/en_us.json
// 1.21 2024-12-15T17:40:40.0369665 Languages: en_us for mod: leashedplayer
d88b57505584fdfde48b00652789cb078b469830 assets/leashedplayer/lang/en_us.json

View File

@ -0,0 +1,2 @@
// 1.21 2024-11-05T22:44:13.1754334 Sound Definitions
81f1cc9f404c2670bf7cc679107177ffb0b48c77 assets/leashedplayer/sounds.json

View File

@ -1,2 +1,2 @@
// 1.21 2024-10-23T13:15:06.1042677 Languages: lzh for mod: leashedplayer
bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f assets/leashedplayer/lang/lzh.json
// 1.21 2024-11-03T11:56:02.1150382 Languages: lzh for mod: leashedplayer
a9b5a3116c6381872e174909553b8dac080dede8 assets/leashedplayer/lang/lzh.json

View File

@ -1,7 +1,15 @@
// 1.21 2024-10-23T13:15:06.1092763 Recipes
// 1.21 2024-11-26T16:39:25.2156177 Recipes
13ebe9a580731296eb10c05d1844657d58e07cc1 data/leashedplayer/advancement/recipes/misc/amethyst_shears.json
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
a89ec35176f84a580181c5839d6f249e482a65a9 data/leashedplayer/advancement/recipes/misc/nestle_rope_arrow.json
04bd2d8a0c7288776da2119eb9a9f9cf694be1b6 data/leashedplayer/recipe/amethyst_shears.json
974d74538b3e172946f2e169036b453b6eb6bc0a data/leashedplayer/recipe/leash_rope_arrow.json
093bae9d2e24a901ce8450d802ad5d142d1d74ed data/leashedplayer/recipe/nestle_rope_arrow.json
8de575d00dcc51fce8ebfa2542e193ffda1bafa8 data/minecraft/advancement/recipes/misc/nestle_rope_arrow_with_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
fb35ec6670c3711b7e1d0e96f39ad914cb2419ae data/minecraft/recipe/nestle_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
4dffdb7a2a537b409d1ec2630d9b74300649e1d8 data/minecraft/recipe/tipped_leash_rope_arrow_a.json
7810cb5e8c165f479fc6cd030bd1cf7bc508993b data/minecraft/recipe/tipped_leash_rope_arrow_b.json

View File

@ -1,2 +1,2 @@
// 1.21 2024-10-23T14:43:16.860909 Languages: zh_cn for mod: leashedplayer
35bc6c3001138c5306d1ee9d55ef3dfbfd417e08 assets/leashedplayer/lang/zh_cn.json
// 1.21 2024-12-15T17:48:33.0549249 Languages: zh_cn for mod: leashedplayer
72797aa9107025df7d91eaff3ea51745d410261c assets/leashedplayer/lang/zh_cn.json

View File

@ -1,4 +1,4 @@
// 1.21 2024-10-23T14:19:10.2054361 Advancements
// 1.21 2024-11-26T16:52:31.259654 Advancements
4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json
f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json
bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json
@ -6,4 +6,8 @@ bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_a
25f6b476b194a27c0fe0e75d74ac3a7ff4054789 data/leashedplayer/advancement/leashed_self.json
a69a455855fb6dd8a8ac131a55099de5de45d7c4 data/leashedplayer/advancement/leash_arrow.json
133f844ffafd37b9ba57cafa96350f035cac57f9 data/leashedplayer/advancement/leash_start.json
2d8bce7fd078f9cc6b73b77f2fbab30e6cc197f4 data/leashedplayer/advancement/leash_terminator.json
4e567c22e18462ad367fe1817140d1ffa13a6294 data/leashedplayer/advancement/neo_fox.json
95486932f200c278f23444adca2e328a82e7f863 data/leashedplayer/advancement/nestle_arrow.json
4b0bcf6b372f52e954edcef37a6b04435ec2b4e8 data/leashedplayer/advancement/no_leash.json
72f40eb5816d1e8c296bdf4df6b599c15ba7e7e9 data/leashedplayer/advancement/tipped_leash_arrow.json

View File

@ -1,2 +1,2 @@
// 1.21 2024-10-23T14:43:16.8589078 Languages: zh_tw for mod: leashedplayer
c6df14a1f53a3e892ebc6b396b552ff27f1a7580 assets/leashedplayer/lang/zh_tw.json
// 1.21 2024-12-15T17:48:33.0539432 Languages: zh_tw for mod: leashedplayer
a01c64ca969974766c47baadd465b24b6fb5803b assets/leashedplayer/lang/zh_tw.json

View File

@ -9,32 +9,83 @@
"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.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.desc": "Be Bond by player with lead",
"advancement.leashedplayer.leashed_self": "Stable Connection",
"advancement.leashedplayer.leashed_self.desc": "“Restrain oneself with a rope",
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
"advancement.leashedplayer.neo_fox.desc": "It seems can be equipped.",
"advancement.leashedplayer.nestle_arrow": "Arrow with the Power of Nestle!",
"advancement.leashedplayer.nestle_arrow.desc": "The Power of Nestle!!!",
"advancement.leashedplayer.no_leash": "Don't tie me up",
"advancement.leashedplayer.no_leash.desc": "You cannot be leashed by ANY",
"advancement.leashedplayer.tipped_leash_arrow": "God said there should be more arrows",
"advancement.leashedplayer.tipped_leash_arrow.desc": "A dazzling array of Leash Rope arrows",
"creativetab.leashedplayer.leashedplayer_tab": "Leashed Player",
"effect.leashedplayer.no_leash": "No Leash",
"entity.leashedplayer.kid_player": "Kid",
"entity.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
"entity.leashedplayer.nestle_rope_arrow": "Nestle Rope Arrow",
"entity.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow",
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea": "Should Non-OP Player can change their TalkArea",
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea.description": "Above on its Name",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence",
"gamerule.LP.DisablePlayerMoveCheck": "Disable Player Move Check",
"gamerule.LP.DisablePlayerMoveCheck.description": "Disable the player's movement Check And Correct it.",
"gamerule.LP.DefaultTalkArea": "Default Area Talk",
"gamerule.LP.DefaultTalkArea.description": "When the global setting is non-negative, it limits the chat range for all players. If a player's configured chat range is smaller than this value, this rule applies. Otherwise, the player's custom value is used.",
"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.OpenTOPNeededModeWhenScreenIsNotNull": "Open TOP NEEDED Mode When Screen isn't null",
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull.description": "The One Probe will automatic to be in the Needed Mode when Gui Screen is not NULL",
"gamerule.LP.TeleportWithLeashedPlayers": "Teleport leashed player with player holder",
"gamerule.LP.TeleportWithLeashedPlayers.description": "Holder will teleport with their leashed players ",
"item.leash_rope_arrow.desc.1": "§7This arrow will carry the owner along with its flight:",
"item.leash_rope_arrow.desc.2": "§c1.§r If it hits a fence or an entity, it will leash the owner to it and drop as a normal arrow.",
"item.leash_rope_arrow.desc.3": "§c2.§r Crouching near the arrow allows for faster retrieval. If the arrow's owner is not the player, the owner will be leashed to the player who picks it up.",
"item.leash_rope_arrow.desc.4": "§c3.§r When fired from its launcher, the first entity hit will become the arrow's owner and will fly along with it.",
"item.leash_rope_arrow.desc.5": "§c4.§r Under the §c§l\"no_leash\"§r effect, the behavior of the arrow when fired will follow the launchers behavior.",
"item.leash_rope_arrow.description": "Arrows with ropes attached?",
"item.leashedplayer.amethyst_shears": "Amethyst Shears",
"item.leashedplayer.fabric": "Fabric",
"item.leashedplayer.kid_spawn_egg": "Kid Spawn Egg",
"item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
"item.leashedplayer.neoforge": "NeoForge",
"item.leashedplayer.nestle_rope_arrow": "Nestle 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.potion.effect.no_leash": "No Leash Potion",
"item.minecraft.splash_potion.effect.no_leash": "Splash No Leash Potion",
"item.minecraft.tipped_arrow.effect.no_leash": "Arrow of No Leash",
"item.nestle_rope_arrow.desc.1": "§7This arrow will carry the owner along with its flight:",
"item.nestle_rope_arrow.desc.2": "§c1.§r If it hits an entity, it will leash the owner with the entity and drop as a normal arrow;",
"item.nestle_rope_arrow.desc.3": "§c2.§r When fired from its launcher, the first player hit will become the arrow's owner and will fly along with it.",
"item.nestle_rope_arrow.desc.4": "",
"item.nestle_rope_arrow.desc.5": "",
"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.apply_talkarea_preference": "Apply TalkArea Preference",
"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.chat.none_heard_you": "Nobody heard your message",
"leashedplayer.command.chat.message.no_right": "You haven't the right to do that!",
"leashedplayer.command.chat.message.talkarea.current_config": "%s 's §6TalkArea Current§7:§e %d §6blocks §f(§aPrefence§7:§e %d §ablocks§f)§r",
"leashedplayer.command.chat.message.talkarea.preference.set": "%s 's §atalk area preference set to §e%d§a blocks!§r",
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s 's talk area preference is not set!",
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6TalkArea Current§7:§e %d §6blocks §f(§aPrefence§7:§e %d §ablocks§f)§r",
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§aTalk area preference set to §e%d§a blocks!§r",
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "Your talk area preference is not set!",
"leashedplayer.command.chat.message.talkarea.self.set": "§aTalk area set to §e%d§a blocks!§r",
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§aTalk area unlimited!§r",
"leashedplayer.command.chat.message.talkarea.set": "%s 's §atalk area set to §e%d§a blocks!§r",
"leashedplayer.command.chat.message.talkarea.unlimited": "%s 's §atalk area unlimited!§r",
"leashedplayer.command.leash.message.leash.data.clear": "%1$s's LeashData(LeashHolderEntity: %2$s) now is clear",
"leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s has no LeashData can be clear",
"leashedplayer.command.leash.message.leash.data.null": "%1$s has no LeashDataEntity",
@ -50,6 +101,17 @@
"leashedplayer.command.motion.message.adder.successful": "§bAdd Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.command.motion.message.multiply.successful": "§bMultiply Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.command.motion.message.setter.successful": "§bSet Successfully.§a%s§7:§f[§eVec§7: §a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.lead_breaker.item.desc": "§7can break the link of leash",
"leashedplayer.lead_breaker.item.use_fai": "§cFailed to break §f%1$s§c 's Leashed Link to §f%2$s",
"leashedplayer.lead_breaker.item.use_suf": "§aSuccessfully break §f%1$s§a 's Leashed Link to §f%2$s ",
"leashedplayer.leash_rope.length.decrease": "§Decrease the §f%s §cLength of Leash Rope§7(§bLength§7:§e%d§7)",
"leashedplayer.leash_rope.length.decrease.self": "§cDecrease the Length of Leash Rope§7(§bLength§7:§e%d§7)",
"leashedplayer.leash_rope.length.failed": "§cFailed",
"leashedplayer.leash_rope.length.increase": "§aIncrease the §f%s §aLength of Leash Rope§7(§bLength§7:§e%d§7)",
"leashedplayer.leash_rope.length.increase.self": "§aIncrease the Length of Leash Rope§7(§bLength§7:§e%d§7)",
"leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§aPush §f§lShift§a to pick up quickly",
"multiplayer.disconnect.addiction": "You've triggered the anti-addiction mechanic, and you'll come back when you rest!",
"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 +1,15 @@
{}
{
"entity.leashedplayer.kid_player": "幼",
"gamerule.LP.DefaultTalkArea.description": "阖局初置非负数,则限一顾之日下,若立聊城小在直则用其常,若用玩义直上跻之地",
"leashedplayer.chat.none_heard_you": "无人受子问",
"leashedplayer.command.chat.message.talkarea.current_config": "%s§6今聊城可知半径置§e %d§6格§f(§a默§7§e%d格§f)§r",
"leashedplayer.command.chat.message.talkarea.preference.set": "%s§6默置§e %d§6格§r",
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s未置默视之",
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6今聊城可知半径置§e %d§6格§f(§a默§7§e%d格§f)§r",
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§6默置§e %d§6格§r",
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "未置默视之",
"leashedplayer.command.chat.message.talkarea.self.set": "§6今聊城可知半径置§e%d §6格§r",
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§a语矢无限§r",
"leashedplayer.command.chat.message.talkarea.set": "%s§6今聊城可知半径置§e%d §6格§r",
"leashedplayer.command.chat.message.talkarea.unlimited": "%s§a语矢无限§r"
}

View File

@ -9,32 +9,83 @@
"advancement.leashedplayer.leash_arrow.desc": "也许可以用它来发射生物?",
"advancement.leashedplayer.leash_start": "牵引之力",
"advancement.leashedplayer.leash_start.desc": "拴绳大师之路",
"advancement.leashedplayer.leash_terminator": "拴绳终结者",
"advancement.leashedplayer.leash_terminator.desc": "我來终结拴绳者!",
"advancement.leashedplayer.leashed_friend": "拴绳链接",
"advancement.leashedplayer.leashed_friend.desc": "被玩家用拴绳链接",
"advancement.leashedplayer.leashed_self": "稳固联结",
"advancement.leashedplayer.leashed_self.desc": "用拴绳拴住自己",
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
"advancement.leashedplayer.neo_fox.desc": "似乎可以戴头上",
"advancement.leashedplayer.nestle_arrow": "贴贴之箭!",
"advancement.leashedplayer.nestle_arrow.desc": "贴贴之力!!!",
"advancement.leashedplayer.no_leash": "勿拴我",
"advancement.leashedplayer.no_leash.desc": "你不会被任何东西拴住",
"advancement.leashedplayer.tipped_leash_arrow": "神说要有更多箭矢",
"advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅满目啊",
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
"effect.leashedplayer.no_leash": "禁拴",
"entity.leashedplayer.kid_player": "小孩",
"entity.leashedplayer.leash_rope_arrow": "拴绳箭",
"entity.leashedplayer.nestle_rope_arrow": "贴贴拴绳箭",
"entity.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea": "非OP应该可以修改自己的聊天可见半径吗?",
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea.description": "同名",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它",
"gamerule.LP.DisablePlayerMoveCheck": "禁止检查玩家移动",
"gamerule.LP.DisablePlayerMoveCheck.description": "禁止检查玩家移动并且纠正它",
"gamerule.LP.DefaultTalkArea": "默认聊天区域可见半径",
"gamerule.LP.DefaultTalkArea.description": "全局区域设置为非负数时,则限制全体玩家的聊天区域。若玩家设置的聊天区域小于该值则采用该规则,反之则采用玩家自定义值",
"gamerule.LP.KeepLeashNotDropTime": "保持拴绳不掉落的时间",
"gamerule.LP.KeepLeashNotDropTime.description": "当距离过远时,保持新建拴绳不掉落的时间 (刻)",
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull": "当屏幕不为空时自动打开探测器的Needed模式",
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull.description": "当屏幕不为空时自动打开探测器的Needed模式",
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者传送",
"gamerule.LP.TeleportWithLeashedPlayers.description": "传送时将被拴玩家与持有者一起传送",
"item.leash_rope_arrow.desc.1": "§7该箭将会携带拥有者随其飞行",
"item.leash_rope_arrow.desc.2": "§c1.§r 若击中栅栏或生物时,将持有者拴在其上并已普通箭形式掉落;",
"item.leash_rope_arrow.desc.3": "§c2.§r 靠近该箭下蹲可以更快拾取该箭,如果该箭持有者不是自己,则持有者将被拾取者拴住;",
"item.leash_rope_arrow.desc.4": "§c3.§r 当前其发射器里发射,第一个射中的生物将成为此箭的持有者并随箭飞行;",
"item.leash_rope_arrow.desc.5": "§c4.§r 在§c§l禁拴§7(§c§lno_leash§7)§r效果下射出的箭行为同发射器。",
"item.leash_rope_arrow.description": "带有拴绳的箭矢?",
"item.leashedplayer.amethyst_shears": "紫水晶剪刀",
"item.leashedplayer.fabric": "Fabric",
"item.leashedplayer.kid_spawn_egg": "小孩生成蛋",
"item.leashedplayer.leash_rope_arrow": "拴绳箭",
"item.leashedplayer.neoforge": "NeoForge",
"item.leashedplayer.nestle_rope_arrow": "贴贴拴绳箭",
"item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
"item.minecraft.lingering_potion.effect.no_leash": "滞留型禁拴药水",
"item.minecraft.potion.effect.no_leash": "禁拴药水",
"item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水",
"item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭",
"item.nestle_rope_arrow.desc.1": "§7该箭将会携带拥有者随其飞行",
"item.nestle_rope_arrow.desc.2": "§c1.§r 若击中生物时,将持有者与其拴在一起并已普通箭形式掉落;",
"item.nestle_rope_arrow.desc.3": "§c2.§r 当前其发射器里发射,第一个射中的玩家将成为此箭的持有者并随箭飞行.",
"item.nestle_rope_arrow.desc.4": "",
"item.nestle_rope_arrow.desc.5": "",
"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.apply_talkarea_preference": "应用可见区域预设",
"key.leashedplayer.category": "可拴玩家",
"key.leashedplayer.leash_length.add": "增加拴绳长度",
"key.leashedplayer.leash_length.not_support_to_not_player_entity": "只在玩家身上有效",
"key.leashedplayer.leash_length.sub": "减小拴绳长度",
"leashedplayer.chat.none_heard_you": "沒有人接收到你的消息",
"leashedplayer.command.chat.message.no_right": "你无权这样做!",
"leashedplayer.command.chat.message.talkarea.current_config": "%s§6目前聊天区域可见半径设置§7:§e %d §6格 §f(§a默认值§7:§e %d §a格§f)§r",
"leashedplayer.command.chat.message.talkarea.preference.set": "%s§a默认聊天区域可见消息半径设置为 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s未设置默认可见消息聊天区域半径",
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6目前聊天区域可见半径设置§7:§e %d §6格 §f(§a默认值§7:§e %d §a格§f)§r",
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§a默认聊天区域可见消息半径设置为 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "未设置默认可见消息聊天区域半径",
"leashedplayer.command.chat.message.talkarea.self.set": "§a聊天区域可见消息半径设置为 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§a聊天区域半径无限制§r",
"leashedplayer.command.chat.message.talkarea.set": "%s§a聊天区域可见消息半径设置为 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.unlimited": "%s§a聊天区域半径无限制§r",
"leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴绳数据拴绳持有者实体%2$s现在已清除",
"leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴绳数据可清除",
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴绳数据实体",
@ -50,6 +101,17 @@
"leashedplayer.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.command.motion.message.setter.successful": "§b设置成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.lead_breaker.item.desc": "§7可以破坏拴绳链接",
"leashedplayer.lead_breaker.item.use_fai": "§c无法剪断§f%2$s§c对§f%1$s§c拴绳链接",
"leashedplayer.lead_breaker.item.use_suf": "§a成功剪断§f%2$s§a对§f%1$s§a拴绳链接",
"leashedplayer.leash_rope.length.decrease": "§c减少§f%s的拴绳长度§c§7(§b长度§7:§e%d§7)",
"leashedplayer.leash_rope.length.decrease.self": "§c减少拴绳长度§c§7(§b长度§7:§e%d§7)",
"leashedplayer.leash_rope.length.failed": "§c失败",
"leashedplayer.leash_rope.length.increase": "§a增加§f%s的拴绳长度§a§7(§b长度§7:§e%d§7)",
"leashedplayer.leash_rope.length.increase.self": "§a增加拴绳长度§a§7(§b长度§7:§e%d§7)",
"leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§a按下§f§lShift键§a以加快拾取",
"multiplayer.disconnect.addiction": "你触发了防沉迷机制,休息会再来吧!",
"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,32 +9,83 @@
"advancement.leashedplayer.leash_arrow.desc": "也許可以用它發射生物?",
"advancement.leashedplayer.leash_start": "牽引之力",
"advancement.leashedplayer.leash_start.desc": "拴繩大師之路",
"advancement.leashedplayer.leash_terminator": "拴繩終結者",
"advancement.leashedplayer.leash_terminator.desc": "吾將終結拴繩!",
"advancement.leashedplayer.leashed_friend": "拴繩鏈接",
"advancement.leashedplayer.leashed_friend.desc": "被玩家用拴繩鏈接",
"advancement.leashedplayer.leashed_self": "穩固聯結",
"advancement.leashedplayer.leashed_self.desc": "用栓繩拴住自己",
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
"advancement.leashedplayer.neo_fox.desc": "似乎可以戴著",
"advancement.leashedplayer.nestle_arrow": "貼貼之箭!",
"advancement.leashedplayer.nestle_arrow.desc": "貼貼之力!!!",
"advancement.leashedplayer.no_leash": "請恁勿拴唔",
"advancement.leashedplayer.no_leash.desc": "恁不會被任何拴住",
"advancement.leashedplayer.tipped_leash_arrow": "神說要有更多箭矢",
"advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅滿目啊",
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
"effect.leashedplayer.no_leash": "禁拴",
"entity.leashedplayer.kid_player": "小孩",
"entity.leashedplayer.leash_rope_arrow": "拴繩箭",
"entity.leashedplayer.nestle_rope_arrow": "貼貼拴繩箭",
"entity.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea": "非OP應該可以修改自己的聊天可見半徑嗎",
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea.description": "同名",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結",
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它",
"gamerule.LP.DisablePlayerMoveCheck": "禁止檢查玩家移動",
"gamerule.LP.DisablePlayerMoveCheck.description": "禁止檢查玩家移動並糾正他它",
"gamerule.LP.DefaultTalkArea": "默認聊天區域可見半徑",
"gamerule.LP.DefaultTalkArea.description": "儅全局區域為非負時,則限制全服玩家聊天區域。若玩家自定義值小於該規則則采用,反之則用玩家自定義值",
"gamerule.LP.KeepLeashNotDropTime": "保持其不掉落的時間",
"gamerule.LP.KeepLeashNotDropTime.description": "儅距離過遠時,保持其不掉落的時間(刻)",
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull": "避免糠測器糠屏幕",
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull.description": "避免糠測器糠屏幕",
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者傳送",
"gamerule.LP.TeleportWithLeashedPlayers.description": "將被拴玩家將隨持有者一起傳送",
"item.leash_rope_arrow.desc.1": "§7該箭將會攜帶擁有者隨其飛行",
"item.leash_rope_arrow.desc.2": "§c1.§r 若擊中柵欄或生物時,將持有者拴在其上並以普通箭的形式掉落;",
"item.leash_rope_arrow.desc.3": "§c2.§r 靠近該箭下蹲可以更快拾取該箭,如果該箭的持有者不是自己,則持有者將被拾取者拴住;",
"item.leash_rope_arrow.desc.4": "§c3.§r 當箭從發射器發射時,第一個射中的生物將成為此箭的持有者並隨箭飛行;",
"item.leash_rope_arrow.desc.5": "§c4.§r 在§c§l禁拴§7(§c§lno_leash§7)§r效果下射出的箭行為將與發射器的行為相同。",
"item.leash_rope_arrow.description": "帶有拴繩的箭矢?",
"item.leashedplayer.amethyst_shears": "紫水晶剪刀",
"item.leashedplayer.fabric": "Fabric",
"item.leashedplayer.kid_spawn_egg": "小孩生成蛋",
"item.leashedplayer.leash_rope_arrow": "拴繩箭",
"item.leashedplayer.neoforge": "NeoForge",
"item.leashedplayer.nestle_rope_arrow": "貼貼拴繩箭",
"item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
"item.minecraft.lingering_potion.effect.no_leash": "滯留型禁拴藥水",
"item.minecraft.potion.effect.no_leash": "禁拴藥水",
"item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水",
"item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭",
"item.nestle_rope_arrow.desc.1": "§7該箭將會攜帶擁有者隨其飛行",
"item.nestle_rope_arrow.desc.2": "§c1.§r 若擊中生物時,將持有者與其拴在一起其上並以普通箭的形式掉落;",
"item.nestle_rope_arrow.desc.3": "§c2.§r 當箭從發射器發射時,第一個射中的玩家將成為此箭的持有者並隨箭飛行;",
"item.nestle_rope_arrow.desc.4": "",
"item.nestle_rope_arrow.desc.5": "",
"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.apply_talkarea_preference": "應用設置可見區域預設",
"key.leashedplayer.category": "可拴玩家",
"key.leashedplayer.leash_length.add": "增加拴繩長度",
"key.leashedplayer.leash_length.not_support_to_not_player_entity": "僅對玩家有效",
"key.leashedplayer.leash_length.sub": "減小拴繩長度",
"leashedplayer.chat.none_heard_you": "無人接收到你的訊息",
"leashedplayer.command.chat.message.no_right": "你無權這麽做!",
"leashedplayer.command.chat.message.talkarea.current_config": "%s§6目前可見訊息聊天半徑設置§7:§e%d §6格 §f(§a默認值§7:§e%d §a格§f)§r",
"leashedplayer.command.chat.message.talkarea.preference.set": "%s§a默認聊天區域可見訊息半徑設置為 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s未設置可見訊息聊天半徑",
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6目前可見訊息聊天半徑設置§7:§e%d §6格 §f(§a默認值§7:§e%d §a格§f)§r",
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§a默認聊天區域可見訊息半徑設置為 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "未設置可見訊息聊天半徑",
"leashedplayer.command.chat.message.talkarea.self.set": "§a聊天區域可見半徑為 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§a聊天區域半徑無限制§r",
"leashedplayer.command.chat.message.talkarea.set": "%s§a聊天區域可見半徑為 §e%d §a格!§r",
"leashedplayer.command.chat.message.talkarea.unlimited": "%s§a聊天區域半徑無限制§r",
"leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴繩數據拴繩持有者實體%2$s現在已清除",
"leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴繩數據實體可被清除",
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴繩數據實體",
@ -50,6 +101,17 @@
"leashedplayer.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.command.motion.message.setter.successful": "§b設置成功.§a%s§7:§f[§e加速度§7:§a(§f%f§7,§f%f§7,§f%f§a)§f]§r",
"leashedplayer.lead_breaker.item.desc": "§7可以破壞拴繩鏈接",
"leashedplayer.lead_breaker.item.use_fai": "§c未能剪斷§f%2$s§c對§f%1$s§c拴繩鏈接",
"leashedplayer.lead_breaker.item.use_suf": "§a成功剪斷§f%2$s§a對§f%1$s§a拴繩鏈接",
"leashedplayer.leash_rope.length.decrease": "§c減少§f%s§c的拴繩長度§7(§長度§7:§e%d§7)",
"leashedplayer.leash_rope.length.decrease.self": "§c減少拴繩長度§7(§長度§7:§e%d§7)",
"leashedplayer.leash_rope.length.failed": "§c失敗",
"leashedplayer.leash_rope.length.increase": "§a增加§f%s§a的拴繩長度§7(§長度§7:§e%d§7)",
"leashedplayer.leash_rope.length.increase.self": "§a增加拴繩長度§7(§長度§7:§e%d§7)",
"leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§a按下§f§lShift鍵§a以加速拾取",
"multiplayer.disconnect.addiction": "你觸發了防沉迷機制,休息會再來吧!",
"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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}

View File

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

View File

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

View File

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

View File

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

View File

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

@ -0,0 +1,36 @@
{
"parent": "leashedplayer:leash_start",
"criteria": {
"has_neo_fox": {
"conditions": {
"items": [
{
"items": "leashedplayer:neoforge"
}
]
},
"trigger": "minecraft:inventory_changed"
}
},
"display": {
"announce_to_chat": false,
"description": {
"translate": "advancement.leashedplayer.neo_fox.desc"
},
"frame": "goal",
"hidden": true,
"icon": {
"count": 1,
"id": "leashedplayer:neoforge"
},
"title": {
"translate": "advancement.leashedplayer.neo_fox"
}
},
"requirements": [
[
"has_neo_fox"
]
],
"sends_telemetry_event": true
}

View File

@ -0,0 +1,35 @@
{
"parent": "leashedplayer:leash_arrow",
"criteria": {
"has_nestle_rope_arrow": {
"conditions": {
"items": [
{
"items": "leashedplayer:nestle_rope_arrow"
}
]
},
"trigger": "minecraft:inventory_changed"
}
},
"display": {
"description": {
"translate": "advancement.leashedplayer.nestle_arrow.desc"
},
"frame": "goal",
"hidden": true,
"icon": {
"count": 1,
"id": "leashedplayer:nestle_rope_arrow"
},
"title": {
"translate": "advancement.leashedplayer.nestle_arrow"
}
},
"requirements": [
[
"has_nestle_rope_arrow"
]
],
"sends_telemetry_event": true
}

View File

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

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

View File

@ -0,0 +1,35 @@
{
"parent": "leashedplayer:leash_arrow",
"criteria": {
"has_tipped_leash_arrow": {
"conditions": {
"items": [
{
"items": "leashedplayer:tipped_leash_rope_arrow"
}
]
},
"trigger": "minecraft:inventory_changed"
}
},
"display": {
"description": {
"translate": "advancement.leashedplayer.tipped_leash_arrow.desc"
},
"frame": "goal",
"hidden": true,
"icon": {
"count": 1,
"id": "leashedplayer:tipped_leash_rope_arrow"
},
"title": {
"translate": "advancement.leashedplayer.tipped_leash_arrow"
}
},
"requirements": [
[
"has_tipped_leash_arrow"
]
],
"sends_telemetry_event": true
}

View File

@ -0,0 +1,8 @@
{
"comparator_output": 15,
"description": {
"translate": "jukebox_song.leashedplayer.what_does_the_fox_say"
},
"length_in_seconds": 121.0,
"sound_event": "leashedplayer:what_does_the_fox_say"
}

View File

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

View File

@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shapeless",
"category": "misc",
"ingredients": [
{
"item": "nestle:nestle_lead"
},
{
"item": "minecraft:arrow"
}
],
"result": {
"count": 1,
"id": "leashedplayer:nestle_rope_arrow"
}
}

View File

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

View File

@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shapeless",
"category": "misc",
"ingredients": [
{
"item": "nestle:nestle"
},
{
"item": "leashedplayer:leash_rope_arrow"
}
],
"result": {
"count": 1,
"id": "leashedplayer:nestle_rope_arrow"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,42 +1,204 @@
package com.r3944realms.leashedplayer;
import com.r3944realms.leashedplayer.client.renders.entities.LeashRopeArrowRenderer;
import com.r3944realms.leashedplayer.client.renders.entities.SpectralLeashRopeArrowRenderer;
import com.r3944realms.leashedplayer.client.renders.entities.*;
import com.r3944realms.leashedplayer.content.ModKeyMapping;
import com.r3944realms.leashedplayer.content.commands.Command;
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow;
import com.r3944realms.leashedplayer.content.items.type.INestleRopeArrow;
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 mcjty.theoneprobe.config.Config;
import mcjty.theoneprobe.gui.GuiNote;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.client.gui.screens.DisconnectedScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.DisconnectionDetails;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.FastColor;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.component.ChargedProjectiles;
import net.minecraft.world.phys.HitResult;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModList;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import net.neoforged.neoforge.client.event.*;
import net.neoforged.neoforge.network.PacketDistributor;
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID)
public class ClientEventHandler {
@SubscribeEvent
public static void onRegisterItemProperties(FMLClientSetupEvent event) {
event.enqueueWork(() -> {
ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow"),
import java.util.List;
public abstract class ClientEventHandler {
public static final String ADDICTION = "multiplayer.disconnect.addiction";
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME, modid = LeashedPlayer.MOD_ID)
public static class Game extends ClientEventHandler {
private static int oldSelect;
private static boolean configSaved = false;
private static final boolean IS_TOP_LOADED = ModList.get().isLoaded("theoneprobe");
@SubscribeEvent
public static void onClientTick(ClientTickEvent.Pre event) {
Minecraft mc = Minecraft.getInstance();
if (mc.level == null) return;
if (GameruleRegistry.getGameruleBoolValue(mc.level, OpenTOPNeededModeWhenScreenIsNotNull.ID)){
Screen currentScreen = mc.screen;
if (IS_TOP_LOADED) {
if (currentScreen != null) {
if (currentScreen instanceof GuiNote || currentScreen instanceof ChatScreen) {
configSaved = false;
oldSelect = Config.needsProbe.get();
} else {
if (!configSaved) {
oldSelect = Config.needsProbe.get();
Config.setProbeNeeded(Config.PROBE_NEEDED);
configSaved = true;
} else {
Config.setProbeNeeded(Config.PROBE_NEEDED);
}
}
} else {
Config.setProbeNeeded(oldSelect);
configSaved = false;
}
}
}
}
@SubscribeEvent
public static void onScreenOpen(ScreenEvent.Opening opening) {
if(opening.getNewScreen() instanceof DisconnectedScreen screen) {
if (screen.details.reason().getString().equals("You are already connected to this proxy!")) {
screen.details = new DisconnectionDetails(Component.translatable(ADDICTION).withStyle(ChatFormatting.RED));
}
}
}
@SubscribeEvent
public static void onKetBoardInput(InputEvent.Key event) {
Minecraft minecraft = Minecraft.getInstance();
LocalPlayer player = minecraft.player;
assert player != null;
if (ModKeyMapping.KEY_APPLY_TALKAREA_PREFERENCE.isDown()) {
String prefix = (Command.SHOULD_USE_PREFIX ? Command.PREFIX : "") + " ";
player.connection.sendCommand(prefix + "talkArea usePreference");
}
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)
public static class Mod extends ClientEventHandler {
@SubscribeEvent
public static void onRegisterItemProperties (FMLClientSetupEvent event){
event.enqueueWork(() -> {
ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow"),
((pStack, pLevel, pEntity, pSeed) -> {
ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES);
return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.LEASH_ROPE_ARROW.get()) || chargedProjectiles.contains(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) ? 1.0F : 0.0F;}
));
ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("nestle_rope_arrow"),
((pStack, pLevel, pEntity, pSeed) -> {
ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES);
return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.LEASH_ROPE_ARROW.get()) || chargedProjectiles.contains(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) ? 1.0F : 0.0F;
}));
ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow_pulling"),
((pStack, pLevel, pEntity, pSeed) ->
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F
));
});
ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES);
return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.NESTLE_ROPE_ARROW.get())) ? 1.0F : 0.0F;}
));
ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow_pulling"),
((pStack, pLevel, pEntity, pSeed) ->
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F : 0.0F
));
ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("nestle_rope_arrow_pulling"),
((pStack, pLevel, pEntity, pSeed) ->
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && INestleRopeArrow.isNestleRopeArrow(pStack, pEntity)) ? 1.0F : 0.0F
));
});
}
@SubscribeEvent
public static void registerKeyMapping(RegisterKeyMappingsEvent event) {
event.register(ModKeyMapping.KEY_APPLY_TALKAREA_PREFERENCE);
event.register(ModKeyMapping.KEY_ADD_LEASH_LENGTH);
event.register(ModKeyMapping.KEY_SUB_LEASH_LENGTH);
}
@SubscribeEvent
public static void onRegisterRenderer (EntityRenderersEvent.RegisterRenderers event) {
event.registerEntityRenderer(ModEntityRegister.NESTLE_ROPE_ARROW.get(), NestleRopeArrowRenderer::new);
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new);
event.registerEntityRenderer(ModEntityRegister.KID.get(), KidPlayerRenderer::create);
}
@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().getItemInHandRenderer()));
}
PlayerRenderer slimRenderer = event.getSkin(PlayerSkin.Model.SLIM);
if (slimRenderer instanceof PlayerRenderer slimPlayerRenderer) {
slimPlayerRenderer.addLayer(new ChestItemLayerRenderer<>(slimPlayerRenderer, event.getContext().getItemInHandRenderer()));
}
}
@SubscribeEvent
public static void onRegisterItemColorHandlers (RegisterColorHandlersEvent.Item event){
event.register(
(color, i) -> i > 0
? -1
: FastColor.ARGB32.opaque(color.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).getColor()),
ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get()
);
}
}
@SubscribeEvent
public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new);
}
}

View File

@ -1,29 +1,45 @@
package com.r3944realms.leashedplayer;
import com.mojang.brigadier.CommandDispatcher;
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
import com.r3944realms.leashedplayer.content.commands.MotionCommand;
import com.r3944realms.leashedplayer.content.commands.TickCommand;
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
import com.r3944realms.leashedplayer.content.commands.*;
import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior;
import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData;
import com.r3944realms.leashedplayer.utils.Logger;
import com.r3944realms.leashedplayer.utils.Util;
import io.github.kunosayo.nestle.init.ModCreativeTab;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Leashable;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.animal.Fox;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DispenserBlock;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.event.AnvilUpdateEvent;
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent;
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.tick.EntityTickEvent;
import net.neoforged.neoforge.network.PacketDistributor;
public class CommonEventHandler {
@ -34,48 +50,108 @@ public class CommonEventHandler {
CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
LeashCommand.register(dispatcher);
MotionCommand.register(dispatcher);
ChatCommand.register(dispatcher);
TickCommand.register(dispatcher);
DebugCommand.register(dispatcher);
}
@SubscribeEvent
public static void onJoinServer(PlayerEvent.PlayerLoggedInEvent event) {
PacketDistributor.sendToPlayer((ServerPlayer) event.getEntity(),
new BooleanGameRuleValueChangeData(
OpenTOPNeededModeWhenScreenIsNotNull.ID,
GameruleRegistry.getGameruleBoolValue(
event.getEntity().level(),
OpenTOPNeededModeWhenScreenIsNotNull.ID)
)
);
}
@SubscribeEvent
public static void OnRegisterPotionBrewing(RegisterBrewingRecipesEvent event) {
PotionBrewing.Builder builder = event.getBuilder();
builder.addMix(Potions.WATER, Items.SLIME_BALL, ModPotionRegister.NO_LEASH);
}
@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);
}
}
@SubscribeEvent
public static void OnLivingTickEvent(EntityTickEvent.Post event) {
Entity entity = event.getEntity();
if (entity.level().isClientSide()) {
Level level = entity.level();
if (level.isClientSide()) {
return;
}
if (entity instanceof LivingEntity living) {
MobEffectInstance effect = living.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
if(effect != null && effect.getDuration() > 0){
if (entity instanceof PlayerLeashable player) {
if (player.getLeashHolder() != null) {
if (player.getLeashHolder() instanceof LeashRopeArrow arrow)
arrow.setOwner(null);
player.dropLeash(true, !(player.getLeashHolder() instanceof LeashRopeArrow));
}
} else if (entity instanceof Leashable leashable) {
if (leashable.getLeashHolder() != null) {
if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow)
arrow.setOwner(null);
leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow));
}
if (entity instanceof Fox fox) {
if (fox.getMainHandItem().is(ItemTags.ANVIL)) {
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
Util.throwItemTowardsLook(fox, ModItemRegister.NEOFORGE.get(), 0.3f, 0.1f);
fox.playSound(fox.getEatingSound(ItemStack.EMPTY));
} else if (fox.getMainHandItem().is(ModItemRegister.NEOFORGE.get())) {
// 繞圈參數
float rotationSpeed = 10.0f; // tick 旋轉的角度
// 計算新的旋轉角度
fox.yBodyRot += rotationSpeed; // 身體旋轉
fox.yHeadRot += rotationSpeed; // 頭部旋轉
fox.yRotO += rotationSpeed; // 當前旋轉角度
fox.yHeadRotO += rotationSpeed; // 頭部的當前旋轉角度
// 確保旋轉角度不超出 360 重置為 0 以便持續旋轉
if (fox.yBodyRot >= 360) fox.yBodyRot -= 360;
if (fox.yHeadRot >= 360) fox.yHeadRot -= 360;
}
}
}
}
}
@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public static class Mod extends CommonEventHandler {
@SubscribeEvent
public static void onCommonSetup(FMLCommonSetupEvent event) {
DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get());
DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get());
@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public static class Mod extends CommonEventHandler {
@SubscribeEvent
public static void onCommonSetup(FMLCommonSetupEvent event) {
event.enqueueWork(() -> {
if (LeashedPlayer.IS_NESTLE_LOADED) {
Logger.logger.info("[LeashedPlayer] Hello, Nestle");
DispenserBlock.registerProjectileBehavior(ModItemRegister.NESTLE_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.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior());
});
}
@SubscribeEvent
public static void onEntityAttributeEvent(EntityAttributeCreationEvent event) {
event.put(ModEntityRegister.KID.get(), LittlePlayer.createAttributes().build());
}
@SubscribeEvent
public static void onBuiltCreativeModeTabContents(BuildCreativeModeTabContentsEvent event) {
if (LeashedPlayer.IS_NESTLE_LOADED){
CreativeModeTab tab = event.getTab();
if (tab == ModCreativeTab.MAIN_TABS.get()) {
event.accept(ModItemRegister.NESTLE_ROPE_ARROW.get());
}
}
}
}
}
}

View File

@ -7,9 +7,12 @@ import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.items.ModCreativeTab;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.content.items.repcipe.ModRecipeRegister;
import com.r3944realms.leashedplayer.content.paintings.ModPaintingsRegister;
import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister;
import com.r3944realms.leashedplayer.utils.Util;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModList;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
@ -18,20 +21,27 @@ import static com.r3944realms.leashedplayer.utils.Logger.logger;
@Mod(LeashedPlayer.MOD_ID)
public class LeashedPlayer {
public static final String MOD_ID = "leashedplayer";
public static boolean IS_NESTLE_LOADED;
private static Double M1;//拴繩掉落距離倍基數
private static Double M2;//繩箭拴繩掉落距離倍基數
private static Integer M3; //拴绳最小长度
private static Integer M4; //拴绳最大长度
public LeashedPlayer(IEventBus event) {
ModItemRegister.register(event);
ModPaintingsRegister.register(event);
ModSoundRegister.register(event);
ModEffectRegister.register(event);
ModPotionRegister.register(event);
ModEntityRegister.register(event);
ModCreativeTab.register(event);
ModCriteriaTriggers.register(event);
ModRecipeRegister.register(event);
initiation();
}
private void initiation() {
logger.info("Initializing LeashedPlayer Mod");
IS_NESTLE_LOADED = ModList.get().isLoaded("nestle");
String leashedPlayerCommonConfig = "LeashedPlayerCommonConfig";
Util.configFileCreate(new String[]{leashedPlayerCommonConfig});
ModLoadingContext.get().getActiveContainer().registerConfig(ModConfig.Type.COMMON, LeashPlayerCommonConfig.SPEC, MOD_ID + "/" + leashedPlayerCommonConfig + "/LeashPlayer.toml");
@ -48,6 +58,18 @@ public class LeashedPlayer {
}
return M2;
}
public static Integer M3() {
if(M3 == null) {
M3 = LeashPlayerCommonConfig.MinimumLeashLengthCanBeSet.get();
}
return M3;
}
public static Integer M4() {
if(M4 == null) {
M4 = LeashPlayerCommonConfig.MaximumLeashLengthCanBeSet.get();
}
return M4;
}
}

View File

@ -0,0 +1,115 @@
package com.r3944realms.leashedplayer.client.renders.entities;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
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.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<T extends LivingEntity, M extends EntityModel<T>> extends RenderLayer<T, M> {
private final ItemInHandRenderer heldItemRenderer;
public ChestItemLayerRenderer(RenderLayerParent<T, M> context, ItemInHandRenderer heldItemRenderer) {
super(context);
this.heldItemRenderer = heldItemRenderer;
}
@Override
public void render(@NotNull PoseStack matrices, @NotNull MultiBufferSource vertexConsumers, int light, @NotNull T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
ItemDisplayContext mode = ItemDisplayContext.FIXED;
ItemStack chestStack = entity.getItemBySlot(EquipmentSlot.CHEST);
if (!chestStack.isEmpty()) {
if (!(entity.getEquipmentSlotForItem(chestStack).equals(EquipmentSlot.CHEST))) {
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).body.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.translate(0, -1 / 4f, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
matrices.scale(1.01f, 1.01f, 1.01f);
matrices.translate(0, -1 / 4f, 0);
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).rightArm.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.scale(2/3f, 2/3f, 2/3f);
matrices.translate(-1/12f, 0, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
matrices.scale(0.99f, 0.99f, 0.99f);
matrices.translate(0, -1/2f, 0);
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).leftArm.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.scale(2/3f, 2/3f, 2/3f);
matrices.translate(1/12f, 0, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
matrices.scale(0.99f, 0.99f, 0.99f);
matrices.translate(0, -1/2f, 0);
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
}
}
ItemStack legsStack = entity.getItemBySlot(EquipmentSlot.LEGS);
if (!legsStack.isEmpty()) {
if (!(entity.getEquipmentSlotForItem(legsStack).equals(EquipmentSlot.LEGS))) {
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).rightLeg.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.scale(2/3f, 2/3f, 2/3f);
matrices.translate(0, -1/6f, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
matrices.scale(1.01f, 1.01f, 1.01f);
matrices.translate(0, -1/3f, 0);
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).leftLeg.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.scale(2/3f, 2/3f, 2/3f);
matrices.translate(0, -1/6f, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
matrices.scale(1.01f, 1.01f, 1.01f);
matrices.translate(0, -1/3f, 0);
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
}
}
ItemStack feetStack = entity.getItemBySlot(EquipmentSlot.FEET);
if (!feetStack.isEmpty()) {
if (!(entity.getEquipmentSlotForItem(feetStack).equals(EquipmentSlot.FEET))) {
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).rightLeg.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.scale(0.75f, 0.75f, 0.75f);
matrices.translate(0, -0.8f, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, feetStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
matrices.pushPose();
((PlayerModel<?>) this.getParentModel()).leftLeg.translateAndRotate(matrices);
matrices.mulPose(Axis.XP.rotationDegrees(180));
matrices.scale(0.75f, 0.75f, 0.75f);
matrices.translate(0, -0.8f, 0);
matrices.mulPose(Axis.YP.rotationDegrees(180));
this.heldItemRenderer.renderItem(entity, feetStack, mode, false, matrices, vertexConsumers, light);
matrices.popPose();
}
}
}
}

View File

@ -0,0 +1,107 @@
package com.r3944realms.leashedplayer.client.renders.entities;
import com.mojang.blaze3d.vertex.PoseStack;
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.HumanoidMobRenderer;
import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.CrossbowItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.UseAnim;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
@OnlyIn(Dist.CLIENT)
public class KidPlayerRenderer extends HumanoidMobRenderer<LittlePlayer, PlayerModel<LittlePlayer>> {
public static @NotNull KidPlayerRenderer create(@NotNull EntityRendererProvider.Context pContext) {
if (pContext instanceof PlayerContext pc) {
return new KidPlayerRenderer(pc);
}
return new KidPlayerRenderer(new PlayerContext(pContext, true));
}
public static class PlayerContext extends EntityRendererProvider.Context {
boolean isUseSlimModel;
public PlayerContext(EntityRendererProvider.Context pContext, boolean pIsSlimModel) {
super(pContext.getEntityRenderDispatcher(), pContext.getItemRenderer(), pContext.getBlockRenderDispatcher(), pContext.getItemInHandRenderer(), pContext.getResourceManager(), pContext.getModelSet(), pContext.getFont());
this.isUseSlimModel = pIsSlimModel;
}
public boolean isUseSlimModel() {
return isUseSlimModel;
}
}
public KidPlayerRenderer(PlayerContext pContext) {
super(pContext, new PlayerModel<>(pContext.bakeLayer(pContext.isUseSlimModel() ? ModelLayers.PLAYER_SLIM : ModelLayers.PLAYER), pContext.isUseSlimModel()), 0.5F);
this.addLayer(new HumanoidArmorLayer<>(this,
new HumanoidModel<>(pContext.bakeLayer(ModelLayers.PLAYER_INNER_ARMOR)),
new HumanoidModel<>(pContext.bakeLayer(ModelLayers.PLAYER_OUTER_ARMOR)),
pContext.getModelManager()
));
}
@Override
public @NotNull ResourceLocation getTextureLocation(@NotNull LittlePlayer pEntity) {
return pEntity.getSkin().texture();
}
public void render(@NotNull LittlePlayer companion, float companionYaw, float pPartialTicks, @NotNull PoseStack pMatrixStack,
@NotNull MultiBufferSource pBuffer, int pPackedLight) {
this.setModelProperties(companion);
super.render(companion, companionYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight);
}
private void setModelProperties(LittlePlayer companion) {
PlayerModel<LittlePlayer> companionModel = this.getModel();
HumanoidModel.ArmPose humanoidmodel$armpose = getArmPose(companion, InteractionHand.MAIN_HAND);
HumanoidModel.ArmPose humanoidmodel$armpose1 = getArmPose(companion, InteractionHand.OFF_HAND);
if (companion.getMainArm() == HumanoidArm.RIGHT) {
companionModel.rightArmPose = humanoidmodel$armpose;
companionModel.leftArmPose = humanoidmodel$armpose1;
} else {
companionModel.rightArmPose = humanoidmodel$armpose1;
companionModel.leftArmPose = humanoidmodel$armpose;
}
}
private static HumanoidModel.ArmPose getArmPose(LittlePlayer companion, InteractionHand hand) {
ItemStack itemstack = companion.getItemInHand(hand);
if (itemstack.isEmpty()) {
return HumanoidModel.ArmPose.EMPTY;
} else {
if (companion.getUsedItemHand() == hand && companion.getUseItemRemainingTicks() > 0) {
UseAnim useanim = itemstack.getUseAnimation();
if (useanim == UseAnim.BOW) {
return HumanoidModel.ArmPose.BOW_AND_ARROW;
}
if (useanim == UseAnim.CROSSBOW && hand == companion.getUsedItemHand()) {
return HumanoidModel.ArmPose.CROSSBOW_CHARGE;
}
} else if (!companion.swinging && itemstack.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemstack)) {
return HumanoidModel.ArmPose.CROSSBOW_HOLD;
}
return HumanoidModel.ArmPose.ITEM;
}
}
protected void scale(@NotNull LittlePlayer player, PoseStack pPoseStack, float pPartialTickTime) {
float f = 0.9375F;
pPoseStack.scale(f, f, f);
}
}

View File

@ -0,0 +1,21 @@
package com.r3944realms.leashedplayer.client.renders.entities;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.entities.NestleRopeArrow;
import net.minecraft.client.renderer.entity.ArrowRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.NotNull;
public class NestleRopeArrowRenderer extends ArrowRenderer<NestleRopeArrow> {
public static final ResourceLocation NESTLE_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/nestle_rope_arrow.png");
public NestleRopeArrowRenderer(EntityRendererProvider.Context pContext) {
super(pContext);
}
@Override
public @NotNull ResourceLocation getTextureLocation(@NotNull NestleRopeArrow pEntity) {
return NESTLE_ROPE_ARROW;
}
}

View File

@ -0,0 +1,32 @@
package com.r3944realms.leashedplayer.compat.jei;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.compat.jei.common.PotionSubtypeInterpreter;
import com.r3944realms.leashedplayer.compat.jei.crafting.TippedLeashArrowRecipeMaker;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin;
import mezz.jei.api.constants.RecipeTypes;
import mezz.jei.api.registration.IRecipeRegistration;
import mezz.jei.api.registration.ISubtypeRegistration;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.NotNull;
@JeiPlugin
public class JEIPlugin implements IModPlugin {
private static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "jei_plugin");
@Override
public @NotNull ResourceLocation getPluginUid() {
return UID;
}
@Override
public void registerItemSubtypes(ISubtypeRegistration registration) {
registration.registerSubtypeInterpreter(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), PotionSubtypeInterpreter.INSTANCE);
}
@Override
public void registerRecipes(@NotNull IRecipeRegistration registration) {
registration.addRecipes(RecipeTypes.CRAFTING, TippedLeashArrowRecipeMaker.createRecipes());
}
}

View File

@ -0,0 +1,28 @@
package com.r3944realms.leashedplayer.compat.jei.common;
import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter;
import mezz.jei.api.ingredients.subtypes.UidContext;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.alchemy.PotionContents;
import org.jetbrains.annotations.NotNull;
public class PotionSubtypeInterpreter implements IIngredientSubtypeInterpreter<ItemStack> {
public static final PotionSubtypeInterpreter INSTANCE = new PotionSubtypeInterpreter();
private PotionSubtypeInterpreter() {
}
@Override
public @NotNull String apply(ItemStack itemStack, @NotNull UidContext context) {
if (itemStack.getComponentsPatch().isEmpty()) {
return IIngredientSubtypeInterpreter.NONE;
}
PotionContents contents = itemStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
String itemDescriptionId = itemStack.getItem().getDescriptionId();
String potionEffectId = contents.potion().map(Holder::getRegisteredName).orElse("none");
return itemDescriptionId + ".effect_id." + potionEffectId;
}
}

View File

@ -0,0 +1,77 @@
package com.r3944realms.leashedplayer.compat.jei.crafting;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.compat.jei.util.RegistryUtil;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import net.minecraft.core.NonNullList;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.crafting.*;
import net.neoforged.neoforge.common.crafting.DataComponentIngredient;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public final class TippedLeashArrowRecipeMaker {
private static List<RecipeHolder<CraftingRecipe>> createRecipesA() {
String group = "jei.tipped.leash_rope_arrow_a";
ItemStack arrowStack = new ItemStack(ModItemRegister.LEASH_ROPE_ARROW.get());
Ingredient arrowIngredient = Ingredient.of(arrowStack);
Registry<Potion> potionRegistry = RegistryUtil.getRegistry(Registries.POTION);
return potionRegistry.holders()
.map(potion -> {
ItemStack input = PotionContents.createItemStack(Items.LINGERING_POTION, potion);
ItemStack output = PotionContents.createItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), potion);
output.setCount(8);
Ingredient potionIngredient = DataComponentIngredient.of(false, input);
NonNullList<Ingredient> inputs = NonNullList.of(Ingredient.EMPTY,
arrowIngredient, arrowIngredient, arrowIngredient,
arrowIngredient, potionIngredient, arrowIngredient,
arrowIngredient, arrowIngredient, arrowIngredient
);
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, group + "." + output.getDescriptionId());
ShapedRecipePattern recipe = new ShapedRecipePattern(3,3, inputs, Optional.empty());
CraftingRecipe recipe_ = new ShapedRecipe(group, CraftingBookCategory.MISC, recipe, output);
return new RecipeHolder<>(id, recipe_);
}).toList();
}
private static List<RecipeHolder<CraftingRecipe>> createRecipesB() {
String group = "jei.tipped.leash_rope_arrow_b";
ItemStack arrowStack = new ItemStack(Items.LEAD);
Ingredient arrowIngredient = Ingredient.of(arrowStack);
Registry<Potion> potionRegistry = RegistryUtil.getRegistry(Registries.POTION);
return potionRegistry.holders()
.map(potion -> {
ItemStack input = PotionContents.createItemStack(Items.TIPPED_ARROW, potion);
ItemStack output = PotionContents.createItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), potion);
output.setCount(1);
Ingredient potionIngredient = DataComponentIngredient.of(false, input);
NonNullList<Ingredient> inputs = NonNullList.of(Ingredient.EMPTY,
arrowIngredient,potionIngredient
);
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, group + "." + output.getDescriptionId());
CraftingRecipe recipe_ = new ShapelessRecipe(group, CraftingBookCategory.MISC, output, inputs);
return new RecipeHolder<>(id, recipe_);
}).toList();
}
public static List<RecipeHolder<CraftingRecipe>> createRecipes() {
List<RecipeHolder<CraftingRecipe>> ret = new ArrayList<>();
ret.addAll(createRecipesA());
ret.addAll(createRecipesB());
return ret;
}
private TippedLeashArrowRecipeMaker() {
}
}

View File

@ -0,0 +1,23 @@
package com.r3944realms.leashedplayer.compat.jei.util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
public class RegistryUtil {
public static <T> Registry<T> getRegistry(ResourceKey<? extends Registry<T>> key) {
RegistryAccess registryAccess = getRegistryAccess();
return registryAccess.registryOrThrow(key);
}
public static RegistryAccess getRegistryAccess() {
Minecraft minecraft = Minecraft.getInstance();
ClientLevel level = minecraft.level;
if (level == null) {
throw new IllegalStateException("Could not get registry, registry access is unavailable because the level is currently null");
}
return level.registryAccess();
}
}

View File

@ -7,7 +7,7 @@ public class LeashPlayerCommonConfig {
public static final ModConfigSpec SPEC;
public static final ModConfigSpec.ConfigValue<String> LeashedPlayerModCommandPrefix;
public static final ModConfigSpec.BooleanValue EnableLeashPlayerCommandPrefix;
public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet, TheLeashArrowMaxLifeTime;
public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet, TheLeashArrowMaxLifeTime, TheNestleArrowMaxLifeTime;
public static ModConfigSpec.DoubleValue TheMultipleThatLeashRopeArrowBreakLength, TheLeashBreakLengthTimesBase;
static {
BUILDER.comment("Leash Player Config");
@ -20,8 +20,9 @@ public class LeashPlayerCommonConfig {
BUILDER.pop();
BUILDER.comment("Leash Player Arrow");
BUILDER.push("LeashRopeArrow");
TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[2.0f, 10.0f] ]").defineInRange("TheMultipleArrowBreak", 5.0f, 2.0f , 10.0f);
TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[2.0f, 10.0f] ]").defineInRange("TheMultipleArrowBreak", 5.0f, 2.0f, 10.0f);
TheLeashArrowMaxLifeTime = BUILDER.comment("If the LeashArrowEntity's life is bigger than this value ,it will be discarded", "[ Default : 2400, Invalid Range:[1200 , 10240]]").defineInRange("TheLeashArrowMaxLifeTime",2400, 1200, 10240);
TheNestleArrowMaxLifeTime = BUILDER.comment("If the NestleArrowEntity's life is bigger than this value ,it will be discarded\", \"[ Default : 2400, Invalid Range:[1200 , 10240]]").defineInRange("TheNestleArrowMaxLifeTime",2400, 1200, 10240);
BUILDER.pop();
BUILDER.comment("Leash Player Misc");
BUILDER.push("Misc");

View File

@ -0,0 +1,44 @@
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 APPLY_TALKAREA_PREFERENCE_KEY = KEY_ROOT_ + "apply_talkarea_preference",
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_APPLY_TALKAREA_PREFERENCE =
new KeyMapping(
APPLY_TALKAREA_PREFERENCE_KEY,
KeyConflictContext.IN_GAME,
KeyModifier.NONE,
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_I,
CATEGORY
);
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

@ -0,0 +1,184 @@
package com.r3944realms.leashedplayer.content.commands;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
import com.r3944realms.leashedplayer.content.gamerules.Server.CanCommonPlayerChangeSelfTalkArea;
import com.r3944realms.leashedplayer.modInterface.ServerPlayerCapacity;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.r3944realms.leashedplayer.content.commands.Command.SHOULD_USE_PREFIX;
import static com.r3944realms.leashedplayer.content.commands.Command.getLiterArgumentBuilderOfCSS;
public class ChatCommand {
private static final String LP_CHAT_MESSAGE_ = "leashedplayer.command.chat.message.";
public static final String NO_RIGHT = LP_CHAT_MESSAGE_ + "no_right";
public static final String SELF_TALK_AREA_SET = LP_CHAT_MESSAGE_ + "talkarea.self.set",
SELF_TALK_AREA_PREFERENCE_SET = LP_CHAT_MESSAGE_ + "talkarea.self.preference.set",
SELF_TALK_AREA_PREFERENCE_NOT_SET = LP_CHAT_MESSAGE_ + "talkarea.self.preference_not_set",
SELF_TALK_AREA_UNLIMITED = LP_CHAT_MESSAGE_ + "talkarea.self.unlimited",
SELF_TALK_AREA_CURRENT_CONFIG = LP_CHAT_MESSAGE_ + "talkarea.self.current_config",
TALK_AREA_SET = LP_CHAT_MESSAGE_ + "talkarea.set",
TALK_AREA_PREFERENCE_SET = LP_CHAT_MESSAGE_ + "talkarea.preference.set",
TALK_AREA_PREFERENCE_NOT_SET = LP_CHAT_MESSAGE_ + "talkarea.preference_not_set",
TALK_AREA_UNLIMITED = LP_CHAT_MESSAGE_ + "talkarea.unlimited",
TALK_AREA_CURRENT_CONFIG = LP_CHAT_MESSAGE_ + "talkarea.current_config";
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = SHOULD_USE_PREFIX ? null : new ArrayList<>();
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
LiteralArgumentBuilder<CommandSourceStack> $$leashRoot = getLiterArgumentBuilderOfCSS("talkArea", !SHOULD_USE_PREFIX, nodeList);
Command<CommandSourceStack> chat$self$talkArea_set = (context -> {
CommandSourceStack source = context.getSource();
ServerPlayer player = source.getPlayerOrException();
ServerPlayerCapacity serverPlayer = (ServerPlayerCapacity) player;
if((!player.hasPermissions(2) && !GameruleRegistry.getGameruleBoolValue(source.getLevel(), CanCommonPlayerChangeSelfTalkArea.ID))) {
source.sendFailure(Component.translatable(NO_RIGHT));
return 1;
}
int integer = IntegerArgumentType.getInteger(context, "talkAreaRadius");
serverPlayer.setTalkArea(integer);
source.sendSuccess(() -> Component.translatable(SELF_TALK_AREA_SET, integer),true);
return 0;
});
Command<CommandSourceStack> chat$self$talkArea_preference_set = (context -> {
CommandSourceStack source = context.getSource();
ServerPlayer player = source.getPlayerOrException();
ServerPlayerCapacity serverPlayer = (ServerPlayerCapacity) player;
if((!player.hasPermissions(2) && !GameruleRegistry.getGameruleBoolValue(source.getLevel(), CanCommonPlayerChangeSelfTalkArea.ID))) {
source.sendFailure(Component.translatable(NO_RIGHT));
return 1;
}
int integer = IntegerArgumentType.getInteger(context, "talkAreaPreferenceRadius");
serverPlayer.setTalkAreaPreference(integer);
source.sendSuccess(() -> Component.translatable(SELF_TALK_AREA_PREFERENCE_SET, integer),true);
return 0;
});
Command<CommandSourceStack> chat$self$talkArea_usePreference = (context -> {
CommandSourceStack source = context.getSource();
ServerPlayer player = source.getPlayerOrException();
ServerPlayerCapacity serverPlayer = (ServerPlayerCapacity) player;
if((!player.hasPermissions(2) && !GameruleRegistry.getGameruleBoolValue(source.getLevel(), CanCommonPlayerChangeSelfTalkArea.ID))) {
source.sendFailure(Component.translatable(NO_RIGHT));
return 1;
}
if(serverPlayer.getTalkAreaPreference() == -1) {
source.sendFailure(Component.translatable(SELF_TALK_AREA_PREFERENCE_NOT_SET));
return 1;
}
int currentPreference = serverPlayer.getTalkAreaPreference();
serverPlayer.setTalkArea(currentPreference);
source.sendSuccess(() -> Component.translatable(SELF_TALK_AREA_PREFERENCE_SET, currentPreference),true);
return 0;
});
Command<CommandSourceStack> chat$self$talkArea_unlimited = (context -> {
CommandSourceStack source = context.getSource();
ServerPlayer player = source.getPlayerOrException();
if((!player.hasPermissions(2) && !GameruleRegistry.getGameruleBoolValue(source.getLevel(), CanCommonPlayerChangeSelfTalkArea.ID))) {
source.sendFailure(Component.translatable(NO_RIGHT));
return 1;
}
source.sendSuccess(() -> Component.translatable(SELF_TALK_AREA_UNLIMITED),true);
return 0;
});
Command<CommandSourceStack> chat$self$talkArea_getCurrentConfig = (context -> {
CommandSourceStack source = context.getSource();
ServerPlayerCapacity serverPlayer = (ServerPlayerCapacity) source.getPlayerOrException();
source.sendSuccess(() -> Component.translatable(SELF_TALK_AREA_CURRENT_CONFIG,serverPlayer.getTalkArea(),serverPlayer.getTalkAreaPreference()),true);
return 0;
});
Command<CommandSourceStack> chat$talkArea_set = (context -> {
CommandSourceStack source = context.getSource();
Collection<ServerPlayer> players = EntityArgument.getPlayers(context, "players");
int integer = IntegerArgumentType.getInteger(context, "talkAreaRadius");
players.forEach(i-> {
((ServerPlayerCapacity)i).setTalkArea(integer);
source.sendSuccess(() -> Component.translatable(TALK_AREA_SET, i.getName().copy().withStyle(), integer),true);
});
return 0;
});
Command<CommandSourceStack> chat$talkArea_preference_set = (context -> {
CommandSourceStack source = context.getSource();
Collection<ServerPlayer> players = EntityArgument.getPlayers(context, "players");
int integer = IntegerArgumentType.getInteger(context, "talkAreaPreferenceRadius");
players.forEach(i-> {
((ServerPlayerCapacity)i).setTalkAreaPreference(integer);
source.sendSuccess(() -> Component.translatable(TALK_AREA_PREFERENCE_SET, i.getName().copy().withStyle(), integer),true);
});
return 0;
});
Command<CommandSourceStack> chat$talkArea_usePreference = (context -> {
CommandSourceStack source = context.getSource();
Collection<ServerPlayer> players = EntityArgument.getPlayers(context, "players");
players.forEach(i-> {
int talkAreaPreference = ((ServerPlayerCapacity)i).getTalkAreaPreference();
if(talkAreaPreference == -1) {
source.sendFailure(Component.translatable(TALK_AREA_PREFERENCE_NOT_SET,i.getName().copy().withStyle()));
} else {
((ServerPlayerCapacity) i).setTalkArea(talkAreaPreference);
source.sendSuccess(() -> Component.translatable(TALK_AREA_PREFERENCE_SET, i.getName().copy().withStyle(), talkAreaPreference),true);
}
});
return 0;
});
Command<CommandSourceStack> chat$talkArea_unlimited = (context -> {
CommandSourceStack source = context.getSource();
Collection<ServerPlayer> players = EntityArgument.getPlayers(context, "players");
players.forEach(i-> {
((ServerPlayerCapacity)i).setTalkArea(-1);
source.sendSuccess(() -> Component.translatable(TALK_AREA_UNLIMITED, i.getName().copy().withStyle()),true);
});
return 0;
});
Command<CommandSourceStack> chat$talkArea_getCurrentConfig = (context -> {
CommandSourceStack source = context.getSource();
Collection<ServerPlayer> players = EntityArgument.getPlayers(context, "players");
players.forEach(i-> source.sendSuccess(() -> Component.translatable(TALK_AREA_CURRENT_CONFIG, i.getName().copy().withStyle(),((ServerPlayerCapacity)i).getTalkArea(),((ServerPlayerCapacity)i).getTalkAreaPreference()), true));
return 0;
});
LiteralArgumentBuilder<CommandSourceStack> selfTalkAreaSet = $$leashRoot.then(Commands.literal("set")
.then(Commands.argument("talkAreaRadius", IntegerArgumentType.integer(0))
.executes(chat$self$talkArea_set)))
.then(Commands.literal("setPreference")
.then(Commands.argument("talkAreaPreferenceRadius", IntegerArgumentType.integer(0))
.executes(chat$self$talkArea_preference_set)))
.then(Commands.literal("usePreference")
.executes(chat$self$talkArea_usePreference))
.then(Commands.literal("unlimited")
.executes(chat$self$talkArea_unlimited))
.then(Commands.literal("currentConfig")
.executes(chat$self$talkArea_getCurrentConfig));
LiteralArgumentBuilder<CommandSourceStack> TalkAreaCommon = $$leashRoot.then(Commands.argument("players", EntityArgument.players()).requires(cs -> cs.hasPermission(2))
.then(Commands.literal("set")
.then(Commands.argument("talkAreaRadius", IntegerArgumentType.integer(0))
.executes(chat$talkArea_set)))
.then(Commands.literal("setPreference")
.then(Commands.argument("talkAreaPreferenceRadius", IntegerArgumentType.integer(0))
.executes(chat$talkArea_preference_set)))
.then(Commands.literal("usePreference")
.executes(chat$talkArea_usePreference))
.then(Commands.literal("unlimited")
.executes(chat$talkArea_unlimited))
.then(Commands.literal("currentConfig")
.executes(chat$talkArea_getCurrentConfig)));
if(SHOULD_USE_PREFIX) {
literalArgumentBuilder.then(selfTalkAreaSet);
literalArgumentBuilder.then(TalkAreaCommon);
dispatcher.register(literalArgumentBuilder);
} else {
nodeList.forEach(dispatcher::register);
}
}
}

View File

@ -10,7 +10,7 @@ import java.util.List;
public class Command {
public static final String PREFIX = LeashPlayerCommonConfig.LeashedPlayerModCommandPrefix.get();
public static boolean SHOULD_USE_PREFIX = LeashPlayerCommonConfig.EnableLeashPlayerCommandPrefix.get();
static LiteralArgumentBuilder<CommandSourceStack> getLiterArgumentBuilderOfCSS(String name, boolean shouldAddToList, @Nullable List<LiteralArgumentBuilder<CommandSourceStack>> list) {
LiteralArgumentBuilder<CommandSourceStack> literal = Commands.literal(name);
if (shouldAddToList) {

View File

@ -0,0 +1,58 @@
package com.r3944realms.leashedplayer.content.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.Connection;
import net.minecraft.network.PacketSendListener;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.protocol.common.ClientboundDisconnectPacket;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import static com.r3944realms.leashedplayer.content.commands.Command.SHOULD_USE_PREFIX;
import static com.r3944realms.leashedplayer.content.commands.Command.getLiterArgumentBuilderOfCSS;
public class DebugCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = SHOULD_USE_PREFIX ? null : new ArrayList<>();
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
LiteralArgumentBuilder<CommandSourceStack> $$DebugRoot = getLiterArgumentBuilderOfCSS("debug", !SHOULD_USE_PREFIX, nodeList);
com.mojang.brigadier.Command<CommandSourceStack> kickTargets = context -> {
for(ServerPlayer entity : EntityArgument.getPlayers(context, "targets")){
MutableComponent literal = Component.literal("You are already connected to this proxy!");
Connection connection = entity.connection.getConnection();
connection.send(new ClientboundDisconnectPacket(literal), PacketSendListener.thenRun(() -> connection.disconnect(literal)));
}
return 0;
};
com.mojang.brigadier.Command<CommandSourceStack> kickSelf = context -> {
CommandSourceStack source = context.getSource();
if (source.getEntity() instanceof ServerPlayer serverPlayer) {
MutableComponent literal = Component.literal("You are already connected to this proxy!");
Connection connection = serverPlayer.connection.getConnection();
connection.send(new ClientboundDisconnectPacket(literal), PacketSendListener.thenRun(() -> connection.disconnect(literal)));
}
return 0;
};
LiteralArgumentBuilder<CommandSourceStack> debugKick = $$DebugRoot.requires(commandSourceStack -> commandSourceStack.hasPermission(2))
.then(
Commands.literal("kick").executes(kickSelf)
.then(Commands.argument("targets", EntityArgument.entities())
.executes(kickTargets)
)
);
if(SHOULD_USE_PREFIX){
literalArgumentBuilder.then(debugKick);
dispatcher.register(literalArgumentBuilder);
} else {
nodeList.forEach(dispatcher::register);
}
}
}

View File

@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static com.r3944realms.leashedplayer.content.commands.Command.SHOULD_USE_PREFIX;
import static com.r3944realms.leashedplayer.content.commands.Command.getLiterArgumentBuilderOfCSS;
public class LeashCommand {
@ -54,10 +55,9 @@ public class LeashCommand {
;
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
boolean shouldUsePrefix = LeashPlayerCommonConfig.EnableLeashPlayerCommandPrefix.get();
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = shouldUsePrefix ? null : new ArrayList<>();
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = SHOULD_USE_PREFIX ? null : new ArrayList<>();
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
LiteralArgumentBuilder<CommandSourceStack> $$leashRoot = getLiterArgumentBuilderOfCSS("leash", !shouldUsePrefix, nodeList);
LiteralArgumentBuilder<CommandSourceStack> $$leashRoot = getLiterArgumentBuilderOfCSS("leash", !SHOULD_USE_PREFIX, nodeList);
Command<CommandSourceStack> getSelfLeashLength = context -> {
CommandSourceStack source = context.getSource();
@ -250,9 +250,7 @@ public class LeashCommand {
CommandSourceStack source = context.getSource();
try {
Collection<ServerPlayer> playerCol = EntityArgument.getPlayers(context, "targetPlayers");
playerCol.forEach(player -> {
LeashDataBlockPosSetResultInt(context, source, player);
});
playerCol.forEach(player -> LeashDataBlockPosSetResultInt(context, source, player));
} catch (Exception e) {
source.sendFailure(Component.translatable(LEASH_FAILED));
@ -292,7 +290,7 @@ public class LeashCommand {
try {
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
Integer x = LeashDataClearResultInt(source, PlayerLeashable.getLeashDataEntity(player, source.getLevel()),player);
if (x != null) return x;
} catch (Exception e) {
source.sendFailure(Component.translatable(LEASH_FAILED));
return -1;
@ -395,7 +393,7 @@ public class LeashCommand {
)
);
if(shouldUsePrefix) {
if(SHOULD_USE_PREFIX) {
literalArgumentBuilder
.then(RefPlayerLeashLength)
.then(SelfLeashLength)

View File

@ -4,7 +4,6 @@ import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
import com.r3944realms.leashedplayer.network.client.UpdatePlayerMovement;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
@ -19,6 +18,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import static com.r3944realms.leashedplayer.content.commands.Command.SHOULD_USE_PREFIX;
import static com.r3944realms.leashedplayer.content.commands.Command.getLiterArgumentBuilderOfCSS;
public class MotionCommand {
@ -27,10 +27,9 @@ public class MotionCommand {
MOTION_ADDER_SUCCESSFUL = LEASHED_PLAYER_MOTION_MESSAGE_ + "adder.successful",
MOTION_MULTIPLY_SUCCESSFUL = LEASHED_PLAYER_MOTION_MESSAGE_ + "multiply.successful";
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
boolean shouldUsePrefix = LeashPlayerCommonConfig.EnableLeashPlayerCommandPrefix.get();
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = shouldUsePrefix ? null : new ArrayList<>();
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = SHOULD_USE_PREFIX ? null : new ArrayList<>();
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
LiteralArgumentBuilder<CommandSourceStack> $$motionRoot = getLiterArgumentBuilderOfCSS("motion", !shouldUsePrefix, nodeList);
LiteralArgumentBuilder<CommandSourceStack> $$motionRoot = getLiterArgumentBuilderOfCSS("motion", !SHOULD_USE_PREFIX, nodeList);
com.mojang.brigadier.Command<CommandSourceStack> motionVecAdder = context -> {
CommandSourceStack source = context.getSource();
for(Entity entity : EntityArgument.getEntities(context, "targets")){
@ -63,7 +62,7 @@ public class MotionCommand {
entity.setDeltaMovement(motionVec);
}
double vecX = entity.getDeltaMovement().x, vecY = entity.getDeltaMovement().y, vecZ = entity.getDeltaMovement().z;
source.sendSuccess(() -> Component.translatable(MOTION_SETTER_SUCCESSFUL, entity.getName().copy(), vecX, vecY, vecZ), true);
source.sendSuccess(() -> Component.translatable(MOTION_SETTER_SUCCESSFUL, entity.getName().copy().withStyle(), vecX, vecY, vecZ), true);
}
return 0;
};
@ -81,7 +80,7 @@ public class MotionCommand {
entity.setDeltaMovement(entity.getDeltaMovement().multiply(motionFactorVec));
}
double vecX = entity.getDeltaMovement().x, vecY = entity.getDeltaMovement().y, vecZ = entity.getDeltaMovement().z;
source.sendSuccess(() -> Component.translatable(MOTION_MULTIPLY_SUCCESSFUL, entity.getName().copy(), vecX, vecY, vecZ), true);
source.sendSuccess(() -> Component.translatable(MOTION_MULTIPLY_SUCCESSFUL, entity.getName().copy().withStyle(), vecX, vecY, vecZ), true);
}
return 0;
};
@ -116,7 +115,7 @@ public class MotionCommand {
)
)
);
if(shouldUsePrefix){
if(SHOULD_USE_PREFIX){
literalArgumentBuilder.then(Motion);
dispatcher.register(literalArgumentBuilder);
} else {

View File

@ -4,7 +4,6 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
@ -18,17 +17,16 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.r3944realms.leashedplayer.content.commands.Command.SHOULD_USE_PREFIX;
import static com.r3944realms.leashedplayer.content.commands.Command.getLiterArgumentBuilderOfCSS;
public class TickCommand {
private static final float MAX_TICKRATE = 10000.0F;
private static final String DEFAULT_TICKRATE = String.valueOf(20);
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
boolean shouldUsePrefix = LeashPlayerCommonConfig.EnableLeashPlayerCommandPrefix.get();
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = shouldUsePrefix ? null : new ArrayList<>();
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = SHOULD_USE_PREFIX ? null : new ArrayList<>();
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
LiteralArgumentBuilder<CommandSourceStack> $$TickRoot = getLiterArgumentBuilderOfCSS("tick", !shouldUsePrefix, nodeList);
LiteralArgumentBuilder<CommandSourceStack> $$TickRoot = getLiterArgumentBuilderOfCSS("tick", !SHOULD_USE_PREFIX, nodeList);
LiteralArgumentBuilder<CommandSourceStack> Tick = $$TickRoot.requires(p_308941_ -> p_308941_.hasPermission(2))
.then(Commands.literal("query").executes(p_308950_ -> tickQuery(p_308950_.getSource())))
@ -61,7 +59,7 @@ public class TickCommand {
)
.then(Commands.literal("unfreeze").executes(p_309184_ -> setFreeze(p_309184_.getSource(), false)))
.then(Commands.literal("freeze").executes(p_309070_ -> setFreeze(p_309070_.getSource(), true)));
if(shouldUsePrefix){
if(SHOULD_USE_PREFIX){
literalArgumentBuilder.then(Tick);
dispatcher.register(literalArgumentBuilder);
} else {

View File

@ -1,6 +1,7 @@
package com.r3944realms.leashedplayer.content.effects;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.effects.type.NoLeashEffect;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
@ -12,9 +13,9 @@ import java.util.function.Supplier;
public class ModEffectRegister {
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, NoLeashEffect> NO_LEASH_EFFECT = register(
"no_leash",
() -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764)
() -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764)
);
public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> effect) {
return MOB_EFFECT.register(name, effect);

View File

@ -0,0 +1,37 @@
package com.r3944realms.leashedplayer.content.effects.type;
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import net.minecraft.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 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

@ -0,0 +1,11 @@
package com.r3944realms.leashedplayer.content.effects.type;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
public class StunnedEffect extends MobEffect {
public StunnedEffect() {
super(MobEffectCategory.HARMFUL, 0XFFFBC5);
}
}

View File

@ -7,8 +7,16 @@ import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTi
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.particles.ColorParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
@ -21,6 +29,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
@ -28,79 +37,118 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LeashRopeArrow extends AbstractArrow {
private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get();
protected LeashRopeArrow(EntityType<? extends AbstractArrow> entityType,Level pLevel) {
super(entityType, pLevel);
}
public static final String PUSH_SHIFT_TO_PICKUP_QUICKLY = "leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip";
private static final int EXPOSED_POTION_DECAY_TIME = 600;
private static final int NO_EFFECT_COLOR = -1;
private static final EntityDataAccessor<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();
protected LeashRopeArrow(EntityType<? extends AbstractArrow> entityType,Level pLevel) {
super(entityType, pLevel);
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);
if(serverPlayer != null && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
}
private PotionContents getPotionContents() {
ItemStack pickupItemStackOrigin = this.getPickupItemStackOrigin();
pickupItemStackOrigin.setCount(1);
return pickupItemStackOrigin.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
}
public void addEffect(MobEffectInstance pEffectInstance) {
this.setPotionContents(this.getPotionContents().withEffectAdded(pEffectInstance));
}
private void setPotionContents(PotionContents pPotionContents) {
this.getPickupItemStackOrigin().set(DataComponents.POTION_CONTENTS, pPotionContents);
this.updateColor();
}
private void updateColor() {
PotionContents potioncontents = this.getPotionContents();
this.entityData.set(ID_EFFECT_COLOR, potioncontents.equals(PotionContents.EMPTY) ? -1 : potioncontents.getColor());
}
@Override
protected void defineSynchedData(SynchedEntityData.@NotNull Builder pBuilder) {
super.defineSynchedData(pBuilder);
pBuilder.define(ID_EFFECT_COLOR, -1);
}
@Override
protected void setPickupItemStack(@NotNull ItemStack pPickupItemStack) {
super.setPickupItemStack(pPickupItemStack);
this.updateColor();
}
public LeashRopeArrow(EntityType<? 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);
this.updateColor();
if(serverPlayer != null && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);//将先前的箭矢置空
}
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
}
}
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
lPlayer.setLeashedTo(this, true);
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
this.updateColor();
if (pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
lPlayer.setLeashedTo(this, true);
}
}
@Override
protected @NotNull ItemStack getDefaultPickupItem() {
return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
}
@Override
protected @NotNull ItemStack getDefaultPickupItem() {
return new ItemStack(ModItemRegister.LEASH_ROPE_ARROW.get());
}
@Override
public void setOwner(@Nullable Entity pEntity) {
// super.setOwner(pEntity);
boolean isNull = pEntity == null;
this.ownerUUID = isNull ? null : pEntity.getUUID();
this.cachedOwner = isNull ? null : pEntity;
this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
}
@Override
public void setOwner(@Nullable Entity pEntity) {
boolean isNull = pEntity == null;
this.ownerUUID = isNull ? null : pEntity.getUUID();
this.cachedOwner = isNull ? null : pEntity;
this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
}
@Override
protected boolean tryPickup(@NotNull Player pPlayer) {
//时间1.40 禁止
//时间2.240
// 如果(非仅创造拾取)
// 如果 (按Shift )
// 如果(拥有者) -> 拾取到完整箭取消绑定(super给父类处理)
// 否则:时间仍为原需时间 ->不能获取完整的箭重绑定当前拥有者的Holder是否为本箭才重绑定
// 否则: 禁止
// 否则:
// 如果 (按Shift )
// 如果(拥有者) -> 且拾取到完整箭取消绑定
// 否则:时间仍为原需时间 ->不能获取完整的箭重绑定
// 否则: 禁止
//时间3
// 如果(拥有者) -> 拾取到完整箭取消绑定
// 否则:不能获取完整的箭重绑定
@Override
protected boolean tryPickup(@NotNull Player pPlayer) {
//时间1.40 禁止
//时间2.240
// 如果(非仅创造拾取)
// 如果 (按Shift )
// 如果(拥有者) -> 拾取到完整箭取消绑定(super给父类处理)
// 否则:时间仍为原需时间 ->不能获取完整的箭重绑定当前拥有者的Holder是否为本箭才重绑定
// 否则: 禁止
// 否则:
// 如果 (按Shift )
// 如果(拥有者) -> 且拾取到完整箭取消绑定
// 否则:时间仍为原需时间 ->不能获取完整的箭重绑定
// 否则: 禁止
//时间3
// 如果(拥有者) -> 拾取到完整箭取消绑定
// 否则:不能获取完整的箭重绑定
if(life <= 40 ) {
return false;
}
else {
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
if(this.getOwner() == null) {//未有Owner始终可检
return true;
}
if(life <= 40 ) {
return false;
} else {
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
if(this.getOwner() != null) {//未有Owner始终可检
if(life <= 240) {
if(pPlayer.isShiftKeyDown()) {
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
if(this.ownedBy(pPlayer)) {
this.pickup = Pickup.ALLOWED;
if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false);
if(this.equals(leashDataEntity)) {
pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
playerLeashable.dropLeash(true, false);
}
} else {
if(life >= 120) {
Entity owner = getOwner();
@ -108,30 +156,39 @@ public class LeashRopeArrow extends AbstractArrow {
// if(this.equals(leashDataEntity)) {
if(owner instanceof PlayerLeashable player) {
player.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
} else if(owner instanceof Leashable leashable) {
leashable.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
}
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
level().addFreshEntity(itemEntity);
discard();
// }
} else return true;
}
} else return false;
}
} else return false;
} else {
((ServerPlayer)pPlayer).sendSystemMessage(Component.translatable(PUSH_SHIFT_TO_PICKUP_QUICKLY), true);
return false;
}
}
else {
} else {
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
if(this.ownedBy(pPlayer)) {
this.pickup = Pickup.ALLOWED;
if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false);
if(this.equals(leashDataEntity)) {
pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
playerLeashable.dropLeash(true, false);
}
} else {
Entity owner = getOwner();
if(owner instanceof PlayerLeashable player) {
player.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
} else if(owner instanceof Leashable leashable) {
leashable.setLeashedTo(pPlayer, true);
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
}
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
level().addFreshEntity(itemEntity);
@ -139,138 +196,262 @@ public class LeashRopeArrow extends AbstractArrow {
}
}
}
} else if (this.pickup != Pickup.CREATIVE_ONLY) this.pickup = Pickup.ALLOWED;
else return pPlayer.hasInfiniteMaterials() && this.pickup == Pickup.CREATIVE_ONLY;
return super.tryPickup(pPlayer);
}
protected void hitOnEntityHandler(Entity pEntity) {
//NOOP
}
protected ItemStack getOrginalItemStack() {
return Items.ARROW.getDefaultInstance();
}
protected ItemStack getSelfItemStack() {
return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
}
@Override
protected void tickDespawn() {
this.life++;
if (this.life >= maxLifeTime) {
ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(leash_rope_arrow);
this.discard();
}
}
@Override
protected void onHitBlock(@NotNull BlockHitResult pResult) {
if(!level().isClientSide) {
if (getOwner() instanceof PlayerLeashable pL) {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
}
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(leashKnotFence, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
}
} else if(getOwner() instanceof Leashable L) {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = this.getOwner();
if(leashDataEntity != null) {
L.dropLeash(true, false);
}
Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos());
L.setLeashedTo(leashKnotFence, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
}
return super.tryPickup(pPlayer);
}
protected void hitOnEntityHandler(Entity pEntity) {
if(pEntity instanceof LivingEntity pLiving) {
super.doPostHurtEffects(pLiving);
Entity entity = this.getEffectSource();
PotionContents potioncontents = this.getPotionContents();
if (potioncontents.potion().isPresent()) {
for (MobEffectInstance mobeffectinstance : potioncontents.potion().get().value().getEffects()) {
pLiving.addEffect(
new MobEffectInstance(
mobeffectinstance.getEffect(),
Math.max(mobeffectinstance.mapDuration(p_268168_ -> p_268168_ / 8), 1),
mobeffectinstance.getAmplifier(),
mobeffectinstance.isAmbient(),
mobeffectinstance.isVisible()
),
entity
);
}
}
super.onHitBlock(pResult);
for (MobEffectInstance effectInstance : potioncontents.customEffects()) {
pLiving.addEffect(effectInstance, entity);
}
}
}
protected ItemStack getOrginalItemStack() {
return Items.ARROW.getDefaultInstance();
}
protected ItemStack getSelfItemStack() {
return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
}
@Override
protected void onHitEntity(@NotNull EntityHitResult pResult) {
if(!level().isClientSide()){
Entity entity = pResult.getEntity();
hitOnEntityHandler(entity);
if(this.getOwner() instanceof LivingEntity livingEntity ) {
MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
if(effect != null && effect.getDuration() > 0) {
this.setOwner(null);
}
@Override
protected void tickDespawn() {
this.life++;
if (this.life >= maxLifeTime) {
ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack());
this.level().addFreshEntity(leash_rope_arrow);
this.discard();
}
}
@Override
public void tick() {
super.tick();
if (this.level().isClientSide) {
if (this.inGround) {
if (this.inGroundTime % 5 == 0) {
this.makeParticle(1);
}
if(entity instanceof LivingEntity livingEntity) {
if(livingEntity.equals(this.getOwner())) return;
if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成
setOwner(livingEntity);
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(this, true);
return;
} else if (this.getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(pResult.getEntity(), true);
this.level().addFreshEntity(arrow);
discard();
} else {
if(entity instanceof Leashable leashable) {
if (getOwner() == null) {
Entity leashDataEntity = leashable.getLeashHolder();
if (leashDataEntity != null)
leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
leashable.setLeashedTo(this, true);
this.setOwner(entity);
return;
}
} else {
this.makeParticle(2);
}
} else if (this.inGround && 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
protected void onHitBlock(@NotNull BlockHitResult pResult) {
if(!level().isClientSide) {
if (getOwner() instanceof PlayerLeashable pL) {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
if(entity instanceof LivingEntity living) {
if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
leashable.setLeashedTo(living, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
return;
}
}
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
this.level().addFreshEntity(lead);
}
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(leashKnotFence, true);
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
}
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
if (getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) pL.dropLeash(true, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
pL.setLeashedTo(leashKnotFence, true);
this.level().addFreshEntity(arrow);
discard();
return;
} else if(getOwner() instanceof Leashable L) {
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
Entity leashDataEntity = this.getOwner();
if(leashDataEntity != null) {
leashDataEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
L.dropLeash(true, false);
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.setOwner(null);
}
}
Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos());
L.setLeashedTo(leashKnotFence, true);
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
}
}
}
super.onHitBlock(pResult);
}
@Override
protected void onHitEntity(@NotNull EntityHitResult pResult) {
if (!level().isClientSide()) {
Entity entity = pResult.getEntity();
hitOnEntityHandler(entity);
if (this.getOwner() instanceof LivingEntity livingEntity ) {
MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
if (effect != null && effect.getDuration() != 0) {
this.dropLeashHandler();
}
}
if(entity instanceof LivingEntity livingEntity) {
if(livingEntity.equals(this.getOwner())) return;
if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成
setOwner(livingEntity);
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
}
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
pL.setLeashedTo(this, true);
} else if (this.getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if(leashDataEntity != null) {
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
leashRopeArrow.dropLeashHandler();
}
}
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
pL.setLeashedTo(pResult.getEntity(), true);
this.level().addFreshEntity(arrow);
discard();
} else {
if (entity instanceof Leashable leashable) {
if (getOwner() == null) {
Entity leashDataEntity = leashable.getLeashHolder();
if (leashDataEntity != null) {
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);
this.setOwner(entity);
return;
}
}
if (entity instanceof LivingEntity living) {
if (this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
leashable.setLeashedTo(living, true);
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
this.level().addFreshEntity(arrow);
discard();
return;
}
}
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
this.level().addFreshEntity(lead);
}
}
if(!level().isClientSide()) super.onHitEntity(pResult);
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
if (getOwner() instanceof PlayerLeashable pL) {
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
if (leashDataEntity != null) {
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());
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
pL.setLeashedTo(leashKnotFence, true);
this.level().addFreshEntity(arrow);
discard();
}
} else {
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
this.level().addFreshEntity(lead);
}
}
}
/**
* 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

@ -0,0 +1,80 @@
package com.r3944realms.leashedplayer.content.entities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.PlayerInfo;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.Objects;
import static net.minecraft.world.entity.EquipmentSlot.*;
public class LittlePlayer extends AgeableMob {
private static final EntityDataAccessor<Integer> DATA_TYPE_ID = SynchedEntityData.defineId(LittlePlayer.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> BASE_HEALTH = SynchedEntityData.defineId(LittlePlayer.class,EntityDataSerializers.INT);
public EquipmentSlot[] armorTypes = new EquipmentSlot[]{FEET, LEGS,
CHEST, EquipmentSlot.HEAD};
@Nullable
private PlayerInfo playerInfo;
protected LittlePlayer(EntityType<? extends AgeableMob> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}
public static AttributeSupplier.Builder createAttributes() {
return AgeableMob.createMobAttributes()
.add(Attributes.MAX_HEALTH, 20.0D)
.add(Attributes.MOVEMENT_SPEED, 0.32D);
}
@Nullable
public PlayerInfo getPlayerInfo() {
if (this.playerInfo == null) {
try {
this.playerInfo = Objects.requireNonNull(Minecraft.getInstance().getConnection()).getPlayerInfo(this.getUUID());
} catch (Exception ignored) {
}
}
return this.playerInfo;
}
public PlayerSkin getSkin() {
PlayerInfo playerinfo = this.getPlayerInfo();
return playerinfo == null ? DefaultPlayerSkin.get(this.getUUID()) : playerinfo.getSkin();
}
@Override
public AgeableMob getBreedOffspring(@NotNull ServerLevel pLevel, @NotNull AgeableMob pOtherParent) {
return ModEntityRegister.KID.get().create(pLevel);
}
@Override
protected void defineSynchedData(SynchedEntityData.@NotNull Builder pBuilder) {
super.defineSynchedData(pBuilder);
pBuilder.define(DATA_TYPE_ID, 1);
pBuilder.define(BASE_HEALTH, 20);
}
public void setBaseHealth(int health) {
this.entityData.set(BASE_HEALTH, health);
}
public float getBaseHealth() {
return this.entityData.get(BASE_HEALTH);
}
@Override
public boolean isBaby() {
return true;
}
}

View File

@ -28,6 +28,20 @@ public class ModEntityRegister {
.updateInterval(20)
.build("spectral_leash_rope_arrow")
);
public static final DeferredHolder<EntityType<?>, EntityType<NestleRopeArrow>> NESTLE_ROPE_ARROW = ENTITY_TYPE.register(
"nestle_rope_arrow",
() -> EntityType.Builder.<NestleRopeArrow>of(NestleRopeArrow::new, MobCategory.MISC)
.sized(0.5F, 0.5F)
.eyeHeight(0.13F)
.clientTrackingRange(4)
.updateInterval(20)
.build("nestle_rope_arrow")
);
public static final DeferredHolder<EntityType<?>, EntityType<LittlePlayer>> KID = ENTITY_TYPE.register("kid_player",
() -> EntityType.Builder.of(LittlePlayer::new, MobCategory.MISC)
.sized(0.6f,1.08f)
.build("kid_player")
);
// public static final DeferredHolder<EntityType<?>, EntityType<ChainTieEntity>> CHAIN_TIE = ENTITY_TYPE.register(
// "chain_tie",
// () -> EntityType.Builder.<ChainTieEntity>of(ChainTieEntity::new, MobCategory.MISC)

View File

@ -0,0 +1,156 @@
package com.r3944realms.leashedplayer.content.entities;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import io.github.kunosayo.nestle.entity.NestleLeadNormalEntity;
import io.github.kunosayo.nestle.entity.NestleLeadPlayerEntity;
import io.github.kunosayo.nestle.entity.data.NestleLeadData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class NestleRopeArrow extends AbstractArrow {
private static final int maxLifeTime = LeashPlayerCommonConfig.TheNestleArrowMaxLifeTime.get();
protected NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}
public NestleRopeArrow(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);
if (serverPlayer != null && !level().isClientSide) {
if(serverPlayer.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) {
nestleRopeArrow.removePassenger(serverPlayer);//重置先前的箭矢
nestleRopeArrow.setOwner(null);
}
serverPlayer.startRiding(this);
this.setOwner(serverPlayer);
} else this.setOwner(null);
}
public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
if (!level().isClientSide) {
if(pOwner.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) {
nestleRopeArrow.removePassenger(pOwner);//重置先前的箭矢
nestleRopeArrow.setOwner(null);
}
pOwner.startRiding(this);
this.setOwner(pOwner);
}
}
@Override
protected @NotNull ItemStack getDefaultPickupItem() {
return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
}
protected ItemStack getOrginalItemStack() {
return Items.ARROW.getDefaultInstance();
}
protected ItemStack getSelfItemStack() {
return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
}
protected void hitOnEntityHandler(Entity pEntity) {
//NOOP
}
@Override
public void setOwner(@Nullable Entity pEntity) {
boolean isNull = pEntity == null;
this.ownerUUID = isNull ? null : pEntity.getUUID();
this.cachedOwner = isNull ? null : pEntity;
this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
}
@Override
protected void tickDespawn() {
this.life++;
if (this.life >= maxLifeTime) {
ItemEntity nestle_arrow_item = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack());
this.level().addFreshEntity(nestle_arrow_item);
this.discard();
}
}
@Override
protected boolean tryPickup(@NotNull Player pPlayer) {
if (life <= 40)
return false;
else {
this.pickup = Pickup.ALLOWED;
}
return super.tryPickup(pPlayer);
}
@Override
public void tick() {
super.tick();
Entity owner = getOwner();
if (owner != null && !owner.level().isClientSide) {
if (!inGround) {
if (owner.getVehicle() == null) owner.startRiding(this);
}
else {
owner.stopRiding();
setOwner(null);
}
}
if (this.inGround && this.inGroundTime != 0) {
this.level().broadcastEntityEvent(this, (byte)0);
this.setPickupItemStack(new ItemStack(getSelfItemStack().getItem()));
}
}
@Override
protected void onHitEntity(@NotNull EntityHitResult pResult) {
if(!level().isClientSide) {
Entity entity = pResult.getEntity();
hitOnEntityHandler(entity);
Entity owner = this.getOwner();
if (owner == null && entity instanceof Player player) {
this.setOwner(player);
}
else if (owner != null && entity != owner ) {
if (entity instanceof LivingEntity livingEntity && LeashedPlayer.IS_NESTLE_LOADED) {//保证即使没Nestle 也不会导致使用该物品会抛异常
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
if (livingEntity instanceof Player player) {
if (NestleLeadData.isNestle(player, livingEntity)) {
arrow.setItem(getSelfItemStack());
} else {
NestleLeadData.nestleTwo((Player) owner, player);
NestleLeadPlayerEntity.inParamFrom = player.getUUID();
NestleLeadPlayerEntity.inParamTarget = entity.getUUID();
NestleLeadPlayerEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT);
}
} else {
Player player = (Player) owner;
if (NestleLeadData.isNestle(player, livingEntity)) {
arrow.setItem(getSelfItemStack());
} else {
NestleLeadData.nestleTwo(player, livingEntity);
NestleLeadNormalEntity.inParamFrom = player;
NestleLeadNormalEntity.inParamTarget = livingEntity;
NestleLeadNormalEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT);
NestleLeadNormalEntity.inParamFrom = null;
NestleLeadNormalEntity.inParamTarget = null;
}
}
this.level().addFreshEntity(arrow);
discard();
}
}
}
else super.onHitEntity(pResult);
}
}

View File

@ -11,11 +11,11 @@ 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 class CanCommonPlayerChangeSelfTalkArea {
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 String ID = Util.getGameruleName(CanCommonPlayerChangeSelfTalkArea.class);
public static final String DESCRIPTION_KEY = Gamerules.getDescriptionKey(CanCommonPlayerChangeSelfTalkArea.class);
public static final String NAME_KEY = Gamerules.getNameKey(CanCommonPlayerChangeSelfTalkArea.class);
public static final GameRules.Category CATEGORY = GameRules.Category.PLAYER;
@SubscribeEvent

View File

@ -0,0 +1,26 @@
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 DefaultTalkArea {
public static final String CHAT_NONE_HEARD_YOU = "leashedplayer.chat.none_heard_you";
public static final int DEFAULT_VALUE = -1;
public static final String ID = Util.getGameruleName(DefaultTalkArea.class);
public static final String DESCRIPTION_KEY = Gamerules.getDescriptionKey(DefaultTalkArea.class);
public static final String NAME_KEY = Gamerules.getNameKey(DefaultTalkArea.class);
public static final GameRules.Category CATEGORY = GameRules.Category.CHAT;
@SubscribeEvent
public static void commonSetup(final FMLCommonSetupEvent event) {
GAMERULE_REGISTRY.registerGamerule(ID, CATEGORY, DEFAULT_VALUE);
}
}

View File

@ -0,0 +1,29 @@
package com.r3944realms.leashedplayer.content.gamerules.Server;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.gamerules.Gamerules;
import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData;
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 net.neoforged.neoforge.network.PacketDistributor;
import static com.r3944realms.leashedplayer.content.gamerules.Gamerules.GAMERULE_REGISTRY;
@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
public class OpenTOPNeededModeWhenScreenIsNotNull {
public static final boolean DEFAULT_VALUE = true;
public static final String ID = Util.getGameruleName(OpenTOPNeededModeWhenScreenIsNotNull.class);
public static final String DESCRIPTION_KEY = Gamerules.getDescriptionKey(OpenTOPNeededModeWhenScreenIsNotNull.class);
public static final String NAME_KEY = Gamerules.getNameKey(OpenTOPNeededModeWhenScreenIsNotNull.class);
public static final GameRules.Category CATEGORY = GameRules.Category.MISC;
@SubscribeEvent
public static void onCommonSetup(final FMLCommonSetupEvent event) {
GAMERULE_REGISTRY.registerGamerule(ID, CATEGORY, DEFAULT_VALUE, (server, value)->{
PacketDistributor.sendToAllPlayers(new BooleanGameRuleValueChangeData(ID, value.get()));
});
}
}

View File

@ -4,8 +4,9 @@ import com.r3944realms.leashedplayer.LeashedPlayer;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.decoration.PaintingVariant;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionContents;
@ -22,7 +23,7 @@ public class ModCreativeTab {
DeferredRegister.create(Registries.CREATIVE_MODE_TAB, LeashedPlayer.MOD_ID);
public static final String LEASHED_PLAYER_TAB_STRING = "creativetab." + LeashedPlayer.MOD_ID;
public static final String LEASHED_PLAYER_ITEM = "leashedplayer_tab";
public static final Supplier<CreativeModeTab> TEST_TAB = CREATIVE_MODE_TABS.register(LEASHED_PLAYER_ITEM,() -> CreativeModeTab.builder()
public static final Supplier<CreativeModeTab> MODE_TAB_SUPPLIER = CREATIVE_MODE_TABS.register(LEASHED_PLAYER_ITEM,() -> CreativeModeTab.builder()
.title(Component.translatable(getCreativeMod(LEASHED_PLAYER_ITEM)))
.icon(() -> ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance())
.displayItems(((pParameters, pOutput) -> {
@ -31,6 +32,8 @@ public class ModCreativeTab {
pOutput.accept(Items.CROSSBOW);
pOutput.accept(ModItemRegister.LEASH_ROPE_ARROW.get());
pOutput.accept(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get());
if(LeashedPlayer.IS_NESTLE_LOADED) pOutput.accept(ModItemRegister.NESTLE_ROPE_ARROW.get());
pOutput.accept(ModItemRegister.AMETHYST_SHEARS.get());
HolderLookup.RegistryLookup<Potion> potionRegistryLookup = CommonHooks.resolveLookup(Registries.POTION);
if(potionRegistryLookup != null) {
potionRegistryLookup.listElements()
@ -46,7 +49,27 @@ public class ModCreativeTab {
.map(p_330083_ -> PotionContents.createItemStack(Items.LINGERING_POTION, p_330083_))
.forEach(pOutput::accept);
}
pOutput.accept(ModItemRegister.NEOFORGE.get());
pParameters.holders()
.lookup(Registries.POTION)
.ifPresent(
pPotions -> generatePotionEffectTypes(
pOutput,
pPotions,
ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(),
CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS,
pParameters.enabledFeatures()
)
);
})).build());
private static void generatePotionEffectTypes(
CreativeModeTab.Output pOutput, HolderLookup<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) {
return LEASHED_PLAYER_TAB_STRING + "." + tabs;
}

View File

@ -1,12 +1,18 @@
package com.r3944realms.leashedplayer.content.items;
import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem;
import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem;
import com.r3944realms.leashedplayer.content.items.type.TestItem;
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.items.type.*;
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.JukeboxSong;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.alchemy.PotionContents;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.common.DeferredSpawnEggItem;
import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.ArrayList;
@ -16,17 +22,38 @@ import java.util.function.Supplier;
public class ModItemRegister {
public static final DeferredRegister<Item> ITEMS =
DeferredRegister.create(BuiltInRegistries.ITEM, LeashedPlayer.MOD_ID);
public static final List<Supplier<Item>> ITEM_SUPPLIER = new ArrayList<>();
public static final Supplier<Item> LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow",
() -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16))
);
public static final Supplier<Item> SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow",
() -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16)));
public static final Supplier<Item> TIPPED_LEASH_ROPE_ARROW = ModItemRegister.register("tipped_leash_rope_arrow",
() -> new TippedLeashRopeArrow(new Item.Properties().stacksTo(16).component(DataComponents.POTION_CONTENTS, PotionContents.EMPTY)));
public static final Supplier<Item> NESTLE_ROPE_ARROW = ModItemRegister.register("nestle_rope_arrow",
() -> new NestleRopeArrowItem(new Item.Properties().stacksTo(16)));
public static final Supplier<Item> AMETHYST_SHEARS = ModItemRegister.register("amethyst_shears",
() -> new LeadBreakerItem(ModToolTier.AMETHYST, new Item.Properties().component(DataComponents.TOOL, LeadBreakerItem.createToolProperties())
.stacksTo(1)));
public static final Supplier<Item> KID_SPAWN_EGG = ModItemRegister.register("kid_spawn_egg",
() -> new DeferredSpawnEggItem(ModEntityRegister.KID, 0x3F4F1F, 0x3D0D4D, new Item.Properties()));
public static final Supplier<Item> FABRIC = ModItemRegister.register("fabric",
() -> new TestItem(new Item.Properties().stacksTo(1))
() -> new TestProcessBarItem(new Item.Properties().stacksTo(1))
);
public static final Supplier<Item> NEOFORGE = ModItemRegister.register("neoforge",
() -> new CanEquipOnHead(DistProperties(ModJukeboxSongs.FOX_MUSIC)));
public static Item.Properties DistProperties(ResourceKey<JukeboxSong> song) {
return new Item.Properties().stacksTo(1).rarity(Rarity.RARE).jukeboxPlayable(song);
}
public static Supplier<Item> register(String name, Supplier<Item> supplier) {
return register(name, supplier, true);
}

View File

@ -0,0 +1,62 @@
package com.r3944realms.leashedplayer.content.items;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
public enum ModToolTier implements Tier {
AMETHYST(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 100, 8.0F, 2.0F, 15, () -> Ingredient.of(Items.AMETHYST_SHARD));
private final TagKey<Block> incorrectBlocksForDrops;
private final int uses;
private final float speed;
private final float attackDamageBonus;
private final int enchantmentValue;
private final Supplier<Ingredient> repairIngredient;
ModToolTier(TagKey<Block> incorrectBlocksForDrops, int uses, float speed, float attackDamageBonus, int enchantmentValue, Supplier<Ingredient> repairIngredient) {
this.incorrectBlocksForDrops = incorrectBlocksForDrops;
this.uses = uses;
this.speed = speed;
this.attackDamageBonus = attackDamageBonus;
this.enchantmentValue = enchantmentValue;
this.repairIngredient = repairIngredient;
}
@Override
public int getUses() {
return this.uses;
}
@Override
public float getSpeed() {
return this.speed;
}
@Override
public float getAttackDamageBonus() {
return this.attackDamageBonus;
}
@Override
public @NotNull TagKey<Block> getIncorrectBlocksForDrops() {
return this.incorrectBlocksForDrops;
}
@Override
public int getEnchantmentValue() {
return this.enchantmentValue;
}
@Override
public @NotNull Ingredient getRepairIngredient() {
return this.repairIngredient.get();
}
}

View File

@ -0,0 +1,27 @@
package com.r3944realms.leashedplayer.content.items.repcipe;
import com.r3944realms.leashedplayer.LeashedPlayer;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
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<?>> TIPPED_LEASH_ROPE_ARROW_A_RECIPE =
RECIPE_SERIALIZER.register("tipped_leash_rope_arrow_a_recipe", () ->
new SimpleCraftingRecipeSerializer<>(TippedLeashRopeArrowRecipe.TippedLeashRopeArrowARecipe::new)
);
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<?>> TIPPED_LEASH_ROPE_ARROW_B_RECIPE =
RECIPE_SERIALIZER.register("tipped_leash_rope_arrow_b_recipe", () ->
new SimpleCraftingRecipeSerializer<>(TippedLeashRopeArrowRecipe.TippedLeashRopeArrowBRecipe::new)
);
public static void register(IEventBus eventBus) {
RECIPE_SERIALIZER.register(eventBus);
}
}

View File

@ -0,0 +1,135 @@
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;
import org.jetbrains.annotations.Nullable;
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;
}
}
/**
* Used to determine if this recipe can fit in a grid of the given width/height
*/
@Override
public boolean canCraftInDimensions(int pWidth, int pHeight) {
return pWidth >= 3 && pHeight >= 3;
}
@Override
public @NotNull RecipeSerializer<?> getSerializer() {
return ModRecipeRegister.TIPPED_LEASH_ROPE_ARROW_A_RECIPE.get();
}
@Override
public @NotNull ItemStack getResultItem(@Nullable HolderLookup.Provider pRegistries) {
return new ItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get());
}
public @NotNull ItemStack getResultItem() {
return getResultItem(null);
}
}
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 boolean canCraftInDimensions(int pWidth, int pHeight) {
return pWidth >= 2 && pHeight >= 2;
}
@Override
public @NotNull RecipeSerializer<?> getSerializer() {
return ModRecipeRegister.TIPPED_LEASH_ROPE_ARROW_B_RECIPE.get();
}
@Override
public @NotNull ItemStack getResultItem(@Nullable HolderLookup.Provider pRegistries) {
return new ItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get());
}
public @NotNull ItemStack getResultItem() {
return getResultItem(null);
}
}
}

View File

@ -0,0 +1,17 @@
package com.r3944realms.leashedplayer.content.items.type;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.Equipable;
import net.minecraft.world.item.Item;
import org.jetbrains.annotations.NotNull;
public class CanEquipOnHead extends Item implements Equipable {
public CanEquipOnHead(Properties pProperties) {
super(pProperties);
}
@Override
public @NotNull EquipmentSlot getEquipmentSlot() {
return EquipmentSlot.HEAD;
}
}

View File

@ -0,0 +1,19 @@
package com.r3944realms.leashedplayer.content.items.type;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
public interface INestleRopeArrow {
static boolean isNestleRopeArrow(ItemStack bowStack, LivingEntity entity) {
if (entity instanceof Player player) {
// 获取将要发射的弹药
ItemStack projectileStack = player.getProjectile(bowStack);
// 判断该弹药是否为拴绳箭
return projectileStack.getItem() instanceof INestleRopeArrow;
}
return false;
}
}

View File

@ -0,0 +1,7 @@
package com.r3944realms.leashedplayer.content.items.type;
import net.minecraft.world.item.Tier;
public interface ITierTool {
Tier getTier();
}

View File

@ -0,0 +1,131 @@
package com.r3944realms.leashedplayer.content.items.type;
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
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.InteractionResultHolder;
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.Tier;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.Tool;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class LeadBreakerItem extends ShearsItem implements ITierTool{
private final Tier tier;
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(Tier tier, Properties properties) {
super(properties.durability(tier.getUses()));
this.tier = tier;
}
public static Tool createToolProperties() {
return new Tool(
List.of(
Tool.Rule.minesAndDrops(List.of(Blocks.COBWEB), 18.0F),
Tool.Rule.overrideSpeed(BlockTags.LEAVES, 25.0F),
Tool.Rule.overrideSpeed(BlockTags.WOOL, 8.0F),
Tool.Rule.overrideSpeed(List.of(Blocks.VINE, 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 InteractionResultHolder<ItemStack> 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 InteractionResultHolder.success(pPlayer.getItemInHand(pUsedHand));
}
((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));
}
@Override
public Tier getTier() {
return this.tier;
}
@Override
public int getEnchantmentValue(@NotNull ItemStack stack) {
return this.tier.getEnchantmentValue();
}
@Override
public boolean isValidRepairItem(@NotNull ItemStack pStack, @NotNull ItemStack pRepairCandidate) {
return this.tier.getRepairIngredient().test(pRepairCandidate) || super.isValidRepairItem(pRepairCandidate, pStack);
}
}

View File

@ -20,7 +20,15 @@ import javax.annotation.Nullable;
import java.util.List;
public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
public static final String descKey = "item.leash_rope_arrow.description";
public static final String descKey = "item.leash_rope_arrow.description",
DESC_1 = "item.leash_rope_arrow.desc.1",
DESC_2 = "item.leash_rope_arrow.desc.2",
DESC_3 = "item.leash_rope_arrow.desc.3",
DESC_4 = "item.leash_rope_arrow.desc.4",
DESC_5 = "item.leash_rope_arrow.desc.5";
public static final String
DESC_V_1 = "item.variant.leash_rope_arrow.desc.1",
DESC_V_2 = "item.variant.leash_rope_arrow.desc.2";
public LeashRopeArrowItem(Item.Properties pProperties) {
super(pProperties);
}
@ -31,7 +39,7 @@ public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
@Override
public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) {
LeashRopeArrow arrow = new LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, this.getDefaultInstance(),null, null);
LeashRopeArrow arrow = new LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, pStack,null, null);
arrow.pickup = AbstractArrow.Pickup.DISALLOWED;
return arrow;
}
@ -41,7 +49,13 @@ public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
}
public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
//TODO:也许会做
pTooltipComponents.addAll(List.of(
Component.translatable(DESC_1),
Component.translatable(DESC_2),
Component.translatable(DESC_3),
Component.translatable(DESC_4),
Component.translatable(DESC_5)
));
}
}

View File

@ -0,0 +1,52 @@
package com.r3944realms.leashedplayer.content.items.type;
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
import com.r3944realms.leashedplayer.content.entities.NestleRopeArrow;
import net.minecraft.core.Direction;
import net.minecraft.core.Position;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ArrowItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
public class NestleRopeArrowItem extends ArrowItem implements INestleRopeArrow {
public static final String descKey = "item.nestle_rope_arrow.description",
DESC_1 = "item.nestle_rope_arrow.desc.1",
DESC_2 = "item.nestle_rope_arrow.desc.2",
DESC_3 = "item.nestle_rope_arrow.desc.3",
DESC_4 = "item.nestle_rope_arrow.desc.4",
DESC_5 = "item.nestle_rope_arrow.desc.5";
public NestleRopeArrowItem(Item.Properties pProperties) {
super(pProperties);
}
public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) {
return new com.r3944realms.leashedplayer.content.entities.NestleRopeArrow(ModEntityRegister.NESTLE_ROPE_ARROW.get(),pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon);
}
@Override
public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) {
NestleRopeArrow arrow = new NestleRopeArrow(ModEntityRegister.NESTLE_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, pStack, null, null);
arrow.pickup = AbstractArrow.Pickup.DISALLOWED;
return arrow;
}
public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
pTooltipComponents.addAll(List.of(
Component.translatable(DESC_1),
Component.translatable(DESC_2),
Component.translatable(DESC_3),
Component.translatable(DESC_4),
Component.translatable(DESC_5)
));
}
}

View File

@ -20,8 +20,10 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
public static final String descKey = "item.spectral_leash_rope_arrow.description";
public static final String descKey = "item.spectral_leash_rope_arrow.description",
DESC = "item.spectral_leash_rope_arrow.desc";
public SpectralLeashRopeArrowItem(Properties pProperties) {
super(pProperties);
}
@ -41,6 +43,10 @@ public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeA
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
}
public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
//TODO:也许会做
pTooltipComponents.addAll(List.of(
Component.translatable(LeashRopeArrowItem.DESC_V_1),
Component.translatable(LeashRopeArrowItem.DESC_V_2),
Component.translatable(DESC)
));
}
}

View File

@ -14,9 +14,9 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
public class TestItem extends Item {
public class TestProcessBarItem extends Item {
public TestProcessBar testProcessBar = null;
public TestItem(Properties pProperties) {
public TestProcessBarItem(Properties pProperties) {
super(pProperties);
}

View File

@ -0,0 +1,62 @@
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.Item;
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 TippedLeashRopeArrow 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 TippedLeashRopeArrow(Item.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, Item.@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 String getDescriptionId(ItemStack pStack) {
// return Potion.getName(pStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(), this.getDescriptionId() + ".effect.");
// }
@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

@ -0,0 +1,77 @@
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

@ -0,0 +1,35 @@
package com.r3944realms.leashedplayer.content.sounds;
import com.r3944realms.leashedplayer.LeashedPlayer;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.function.Supplier;
public class ModSoundRegister {
public static DeferredRegister<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,6 +15,10 @@ public enum ModAdvancementKey {
FOLLOW_LEASH_ARROW("follow_arrow", LEASH_ARROW),
DOG_RUNNING_PLAYER("dog_running_player", LEASH_ARROW),
NO_LEASH("no_leash", LEASH_START),
LEASH_TERMINATOR("leash_terminator", LEASH_START),
TIPPED_LEASH_ARROW("tipped_leash_arrow", LEASH_ARROW),
NEO_FOX("neo_fox", LEASH_START),
NESTLE_ARROW("nestle_arrow", LEASH_ARROW),
;
private final String Name;
@Nullable

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