2024-09-05
版本0.0.3.0-Beta.0.1 增加: 1. 增加了新的指令 data clear 2. 添加了配置文件,方便修改本模组的部分行为 3. 增加新的内容,如拴绳箭(但是有点BUG 修改与调整: 1.调整了原语言部分错别字 2.更改了之前的逻辑【栓绳运动逻辑】 具體新内容請見 README.md 介紹
This commit is contained in:
parent
3da99bc6f3
commit
987ec866c3
18
README.md
18
README.md
|
|
@ -1,15 +1,23 @@
|
||||||
# 版本 0.0.2.2 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
|
# 版本 0.0.3.0-Beta.0.1 提前介绍 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
|
||||||
## 简介
|
## 简介
|
||||||
现在开始你可以用拴绳栓住玩家,也可以栓住自己了,不如尝试栓住彼此来通关我的世界吧(
|
现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧(
|
||||||
|
|
||||||
|
|
||||||
你可以:
|
你可以:
|
||||||
1. 拴绳可以拴住玩家
|
1. 拴绳可以拴住玩家
|
||||||
2. 在无任何栓住实体的情况下用拴绳对准栅栏可以拴住自己
|
2. 在无任何拴住实体的情况下用拴绳对准栅栏可以拴住自己
|
||||||
3. 可以用指令来获取和调整玩家实体的拴绳的长度
|
3. 可以用指令来获取和调整玩家实体的拴绳的长度和设置拴绳数据实体
|
||||||
4. 目前有游戏规则来决定被栓玩家是否在传送时能随拴绳持有者一起传送
|
4. 目前有游戏规则来决定被栓玩家是否在传送时能随拴绳持有者一起传送
|
||||||
|
## 配置文件
|
||||||
|
1. 可改变指令前命名空间和关闭命名空间
|
||||||
|
2. 修改命令拴绳的可设置的长度范围
|
||||||
|
3. 设置拴绳在达到多少倍的拴绳长度后掉落
|
||||||
|
|
||||||
|
## 新物品 和 实体
|
||||||
|
### 拴绳箭
|
||||||
|
获得飞一样的感觉(操作不当可能会摔死
|
||||||
|
#### 射中实体时,会将射击者拴绳绑定在改实体上(该实体父类必须是有LivingEntity类型),同时拴绳箭会以普通的箭矢掉落
|
||||||
|
#### 射中栅栏时,会自动将玩家拴在上面 ,同时拴绳箭会以普通的箭矢掉落
|
||||||
## 指令
|
## 指令
|
||||||
|
|
||||||
* `/lp leash length [<玩家>] set <长度> ` - 设置该玩家的拴绳长度 [ 如果<玩家>为空则代表执行对象是自己 ,<长度> 为在 5 ~ 1024之间的浮点数 ]
|
* `/lp leash length [<玩家>] set <长度> ` - 设置该玩家的拴绳长度 [ 如果<玩家>为空则代表执行对象是自己 ,<长度> 为在 5 ~ 1024之间的浮点数 ]
|
||||||
|
|
|
||||||
BIN
Resource/leashed_rope_arrow.png
Normal file
BIN
Resource/leashed_rope_arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 268 B |
|
|
@ -1,5 +1,5 @@
|
||||||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||||
org.gradle.jvmargs=-Xmx3G
|
org.gradle.jvmargs=-Xmx8G
|
||||||
org.gradle.daemon=false
|
org.gradle.daemon=false
|
||||||
org.gradle.debug=false
|
org.gradle.debug=false
|
||||||
|
|
||||||
|
|
@ -10,13 +10,13 @@ neogradle.subsystems.parchment.mappingsVersion=2024.07.28
|
||||||
# Environment Properties
|
# Environment Properties
|
||||||
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
|
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
|
||||||
# The Minecraft version must agree with the Neo version to get a valid artifact
|
# The Minecraft version must agree with the Neo version to get a valid artifact
|
||||||
minecraft_version=1.21
|
minecraft_version=1.21.1
|
||||||
# The Minecraft version range can use any release version of Minecraft as bounds.
|
# The Minecraft version range can use any release version of Minecraft as bounds.
|
||||||
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
|
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
|
||||||
# as they do not follow standard versioning conventions.
|
# as they do not follow standard versioning conventions.
|
||||||
minecraft_version_range=[1.21,1.21.1)
|
minecraft_version_range=[1.21,1.22)
|
||||||
# The Neo version must agree with the Minecraft version to get a valid artifact
|
# The Neo version must agree with the Minecraft version to get a valid artifact
|
||||||
neo_version=21.0.167
|
neo_version=21.1.35
|
||||||
# The Neo version range can use any version of Neo as bounds
|
# The Neo version range can use any version of Neo as bounds
|
||||||
neo_version_range=[21.0.0-beta,)
|
neo_version_range=[21.0.0-beta,)
|
||||||
# The loader version range can only use the major version of FML as bounds
|
# The loader version range can only use the major version of FML as bounds
|
||||||
|
|
@ -32,7 +32,7 @@ mod_name=Leashed Player
|
||||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=All Rights Reserved
|
mod_license=All Rights Reserved
|
||||||
# The mod version. See https://semver.org/
|
# The mod version. See https://semver.org/
|
||||||
mod_version=0.0.2.2
|
mod_version=0.0.3.0-Beta.0.1
|
||||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||||
# This should match the base package used for the mod sources.
|
# This should match the base package used for the mod sources.
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
|
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.8-bin.zip
|
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.9-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
// 1.21.1 2024-09-05T13:27:19.7536653 Item Models: leashedplayer
|
||||||
|
114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
// 1.21.1 2024-09-05T15:23:52.4523518 Tags for minecraft:item mod id leashedplayer
|
||||||
|
a8cd7ac5b7e37b7dea044004a42a2f137d4027d6 data/minecraft/tags/item/arrows.json
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// 1.21 2024-09-04T14:54:14.4635752 Languages: en_us for mod: leashedplayer
|
// 1.21.1 2024-09-05T21:38:59.0514122 Languages: en_us for mod: leashedplayer
|
||||||
3e231f3b588ab61d2990c49bf1f1deca5593dbbf assets/leashedplayer/lang/en_us.json
|
06d246d0f55a53cc97a63426253e9328cf4a189d assets/leashedplayer/lang/en_us.json
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
// 1.21.1 2024-09-05T15:23:52.4543401 Tags for minecraft:block mod id leashedplayer
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// 1.21 2024-09-03T17:46:39.9787945 Languages: lzh for mod: leashedplayer
|
// 1.21.1 2024-09-05T10:26:39.4122865 Languages: lzh for mod: leashedplayer
|
||||||
bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f assets/leashedplayer/lang/lzh.json
|
bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f assets/leashedplayer/lang/lzh.json
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
// 1.21.1 2024-09-05T13:20:35.9705404 Recipes
|
||||||
|
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
|
||||||
|
974d74538b3e172946f2e169036b453b6eb6bc0a data/leashedplayer/recipe/leash_rope_arrow.json
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// 1.21 2024-09-04T14:54:14.4585471 Languages: zh_cn for mod: leashedplayer
|
// 1.21.1 2024-09-05T21:38:59.0494103 Languages: zh_cn for mod: leashedplayer
|
||||||
6db8ccbbd7d3bf13e819c2ae1762f37e2c332043 assets/leashedplayer/lang/zh_cn.json
|
283bed8b7a38bb5927f126c4002a772cd64fc274 assets/leashedplayer/lang/zh_cn.json
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
// 1.21 2024-09-04T14:54:14.4535174 Languages: zh_tw for mod: leashedplayer
|
// 1.21.1 2024-09-05T21:38:59.0474148 Languages: zh_tw for mod: leashedplayer
|
||||||
86fa3a80c53a50ad5af47129384e506cddda79aa assets/leashedplayer/lang/zh_tw.json
|
056a2c46a8ee17f5326e70d397cd3c8b2950df2d assets/leashedplayer/lang/zh_tw.json
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,21 @@
|
||||||
{
|
{
|
||||||
|
"creativetab.leashedplayer.leashedplayer_tab": "Leashed Player",
|
||||||
|
"entity.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
|
||||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent",
|
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent",
|
||||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence",
|
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence",
|
||||||
"gamerule.LP.TeleportWithLeashedPlayers": "Teleport leashed player with player holder",
|
"gamerule.LP.TeleportWithLeashedPlayers": "Teleport leashed player with player holder",
|
||||||
"gamerule.LP.TeleportWithLeashedPlayers.description": "Holder will teleport with their leashed players ",
|
"gamerule.LP.TeleportWithLeashedPlayers.description": "Holder will teleport with their leashed players ",
|
||||||
|
"item.leash_rope_arrow.description": "Arrows with ropes attached?",
|
||||||
|
"item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
|
||||||
|
"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",
|
"leashedplayer.command.leash.message.leash.data.null": "%1$s has no LeashDataEntity",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set": "%1$s LeashDataEntity now is set as %2$s",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.diff_level": "%1$s and %2$s are not at a same level",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.forbid_same_entity": "Prohibit setting the same entity",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.no_knot_exist_in_that_pos": "No knot found at (X:%f,Y:%f,Z:%f)",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.too_far": "The distance between %1$s and %2$s is larger than the 1.2 times of LeashLength, LeashLength is %3$s blocks",
|
||||||
"leashedplayer.command.leash.message.leash.data.show": "%1$s's LeashDataEntity is %2$s",
|
"leashedplayer.command.leash.message.leash.data.show": "%1$s's LeashDataEntity is %2$s",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set": "%1$s LeashDataEntity now is set as %2$s",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.diff_level": "%1$s and %2$s are not at a same level",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.forbid_same_entity": "Prohibit setting the same entity",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.no_knot_exist_in_that_pos": "No knot found at (X:%f,Y:%f,Z:%f)",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.too_far": "The distance between %1$s and %2$s is larger than the 1.2 times of LeashLength, LeashLength is %3$s blocks",
|
|
||||||
"leashedplayer.command.leash.message.leash.length.failed": "Failed (Internal Error, maybe your command is incorrect)",
|
"leashedplayer.command.leash.message.leash.length.failed": "Failed (Internal Error, maybe your command is incorrect)",
|
||||||
"leashedplayer.command.leash.message.leash.length.set": "The Leash length of %1$s is set to %2$s blocks",
|
"leashedplayer.command.leash.message.leash.length.set": "The Leash length of %1$s is set to %2$s blocks",
|
||||||
"leashedplayer.command.leash.message.leash.length.show": "The Leash Length of %1$s is %2$s blocks"
|
"leashedplayer.command.leash.message.leash.length.show": "The Leash Length of %1$s is %2$s blocks"
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,21 @@
|
||||||
{
|
{
|
||||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建栓绳结",
|
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
|
||||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失栓绳结,则创建它",
|
"entity.leashedplayer.leash_rope_arrow": "拴绳箭",
|
||||||
"gamerule.LP.TeleportWithLeashedPlayers": "被栓玩家随玩家持有者传送",
|
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结",
|
||||||
"gamerule.LP.TeleportWithLeashedPlayers.description": "传送时将被栓玩家与持有者一起传送",
|
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它",
|
||||||
|
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者传送",
|
||||||
|
"gamerule.LP.TeleportWithLeashedPlayers.description": "传送时将被拴玩家与持有者一起传送",
|
||||||
|
"item.leash_rope_arrow.description": "带有拴绳的箭矢?",
|
||||||
|
"item.leashedplayer.leash_rope_arrow": "拴绳箭",
|
||||||
|
"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沒有拴绳数据实体",
|
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴绳数据实体",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set": "%1$s拴绳数据实体被设置为%2$s",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.diff_level": "%1$s和%2$s不在同一维度上",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.forbid_same_entity": "禁止设置同一实体",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.no_knot_exist_in_that_pos": "未找到拴绳结在(X:%f, Y:%f, Z:%f)处",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.too_far": "%1$s到%2$s的距离超过了1.2倍 拴绳长度,原长:%3$s 格",
|
||||||
"leashedplayer.command.leash.message.leash.data.show": "%1$s的拴绳数据实体为%2$s",
|
"leashedplayer.command.leash.message.leash.data.show": "%1$s的拴绳数据实体为%2$s",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set": "%1$s拴绳数据实体被设置为%2$s",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.diff_level": "%1$s和%2$s不在同一维度上",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.forbid_same_entity": "禁止设置同一实体",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.no_knot_exist_in_that_pos": "未找到栓绳结在(X:%f, Y:%f, Z:%f)处",
|
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.too_far": "%1$s到%2$s的距离超过了1.2倍 栓绳长度,原长:%3$s 格",
|
|
||||||
"leashedplayer.command.leash.message.leash.length.failed": "失败(内部错误,可能是你输的指令有误)",
|
"leashedplayer.command.leash.message.leash.length.failed": "失败(内部错误,可能是你输的指令有误)",
|
||||||
"leashedplayer.command.leash.message.leash.length.set": "%1$s的拴绳长度被设置为%2$s格",
|
"leashedplayer.command.leash.message.leash.length.set": "%1$s的拴绳长度被设置为%2$s格",
|
||||||
"leashedplayer.command.leash.message.leash.length.show": "%1$s的拴绳长度为%2$s格"
|
"leashedplayer.command.leash.message.leash.length.show": "%1$s的拴绳长度为%2$s格"
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
{
|
{
|
||||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建栓繩結",
|
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
|
||||||
|
"entity.leashedplayer.leash_rope_arrow": "拴繩箭",
|
||||||
|
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結",
|
||||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它",
|
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它",
|
||||||
"gamerule.LP.TeleportWithLeashedPlayers": "被栓玩家随玩家持有者傳送",
|
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者傳送",
|
||||||
"gamerule.LP.TeleportWithLeashedPlayers.description": "將被栓玩家將隨持有者一起傳送",
|
"gamerule.LP.TeleportWithLeashedPlayers.description": "將被拴玩家將隨持有者一起傳送",
|
||||||
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有栓繩數據實體",
|
"item.leash_rope_arrow.description": "帶有拴繩的箭矢?",
|
||||||
"leashedplayer.command.leash.message.leash.data.show": "%1$s栓繩數據實體為%2$s",
|
"item.leashedplayer.leash_rope_arrow": "拴繩箭",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set": "%1$s栓繩數據實體設置為%2$s",
|
"leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴繩數據(拴繩持有者實體:%2$s)現在已清除",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.diff_level": "%1$s和%2$s不在同一緯度上",
|
"leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴繩數據實體可被清除",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.forbid_same_entity": "禁止設置同一實體",
|
"leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴繩數據實體",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.no_knot_exist_in_that_pos": "未找到栓繩結在(X:%f, Y:%f, Z:%f)処",
|
"leashedplayer.command.leash.message.leash.data.set": "%1$s拴繩數據實體設置為%2$s",
|
||||||
"leashedplayer.command.leash.message.leash.leash_data.set.failed.too_far": "%1$s到%2$s的距離超過了1.2倍栓繩長度,原長:%3$s 格",
|
"leashedplayer.command.leash.message.leash.data.set.failed.diff_level": "%1$s和%2$s不在同一緯度上",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.forbid_same_entity": "禁止設置同一實體",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.no_knot_exist_in_that_pos": "未找到拴繩結在(X:%f, Y:%f, Z:%f)処",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.set.failed.too_far": "%1$s到%2$s的距離超過了1.2倍拴繩長度,原長:%3$s 格",
|
||||||
|
"leashedplayer.command.leash.message.leash.data.show": "%1$s拴繩數據實體為%2$s",
|
||||||
"leashedplayer.command.leash.message.leash.length.failed": "失敗(内部錯誤,,可能你輸入的指令有誤)",
|
"leashedplayer.command.leash.message.leash.length.failed": "失敗(内部錯誤,,可能你輸入的指令有誤)",
|
||||||
"leashedplayer.command.leash.message.leash.length.set": "%1$s的栓繩長度被設置為%2$s格",
|
"leashedplayer.command.leash.message.leash.length.set": "%1$s的拴繩長度被設置為%2$s格",
|
||||||
"leashedplayer.command.leash.message.leash.length.show": "%1$s的栓繩長度為%2$s格"
|
"leashedplayer.command.leash.message.leash.length.show": "%1$s的拴繩長度為%2$s格"
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "leashedplayer:item/leash_rope_arrow"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"criteria": {
|
||||||
|
"has_lead": {
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"items": "minecraft:lead"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"trigger": "minecraft:inventory_changed"
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "leashedplayer:leash_rope_arrow"
|
||||||
|
},
|
||||||
|
"trigger": "minecraft:recipe_unlocked"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_the_recipe",
|
||||||
|
"has_lead"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"leashedplayer:leash_rope_arrow"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shapeless",
|
||||||
|
"category": "misc",
|
||||||
|
"ingredients": [
|
||||||
|
{
|
||||||
|
"item": "minecraft:lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item": "minecraft:arrow"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"id": "leashedplayer:leash_rope_arrow"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
"leashedplayer:leash_rope_arrow"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.r3944realms.leashedplayer;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.client.renders.LeashRopeArrowRenderer;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||||
|
import net.neoforged.api.distmarker.Dist;
|
||||||
|
import net.neoforged.bus.api.SubscribeEvent;
|
||||||
|
import net.neoforged.fml.common.EventBusSubscriber;
|
||||||
|
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
||||||
|
|
||||||
|
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID)
|
||||||
|
public class ClientEventHandler {
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {
|
||||||
|
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,46 @@
|
||||||
package com.r3944realms.leashedplayer;
|
package com.r3944realms.leashedplayer;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||||
|
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.utils.Util;
|
||||||
|
import net.neoforged.bus.api.IEventBus;
|
||||||
|
import net.neoforged.fml.ModLoadingContext;
|
||||||
import net.neoforged.fml.common.Mod;
|
import net.neoforged.fml.common.Mod;
|
||||||
|
import net.neoforged.fml.config.ModConfig;
|
||||||
|
|
||||||
|
import static com.r3944realms.leashedplayer.utils.Logger.logger;
|
||||||
@Mod(LeashedPlayer.MOD_ID)
|
@Mod(LeashedPlayer.MOD_ID)
|
||||||
public class LeashedPlayer {
|
public class LeashedPlayer {
|
||||||
public static final String MOD_ID = "leashedplayer";
|
public static final String MOD_ID = "leashedplayer";
|
||||||
|
private static Float M1;//拴繩掉落距離倍基數
|
||||||
|
private static Float M2;//繩箭拴繩掉落距離倍基數
|
||||||
|
public LeashedPlayer(IEventBus event) {
|
||||||
|
ModItemRegister.register(event);
|
||||||
|
ModEntityRegister.register(event);
|
||||||
|
ModCreativeTab.register(event);
|
||||||
|
initiation();
|
||||||
|
}
|
||||||
|
private void initiation() {
|
||||||
|
logger.info("Initializing LeashedPlayer Mod");
|
||||||
|
String leashedPlayerCommonConfig = "LeashedPlayerCommonConfig";
|
||||||
|
Util.configFileCreate(new String[]{leashedPlayerCommonConfig});
|
||||||
|
ModLoadingContext.get().getActiveContainer().registerConfig(ModConfig.Type.COMMON, LeashPlayerCommonConfig.SPEC, MOD_ID + "/" + leashedPlayerCommonConfig + "/LeashPlayer.toml");
|
||||||
|
}
|
||||||
|
public static Float M1() {
|
||||||
|
if(M1 == null) {
|
||||||
|
M1 = LeashPlayerCommonConfig.TheLeashBreakLengthTimesBase.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
return M1;
|
||||||
|
}
|
||||||
|
public static Float M2() {
|
||||||
|
if(M2 == null) {
|
||||||
|
M2 = LeashPlayerCommonConfig.TheMultipleThatLeashRopeArrowBreakLength.get();
|
||||||
|
}
|
||||||
|
return M2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.r3944realms.leashedplayer.client.renders;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||||
|
import net.minecraft.client.renderer.entity.ArrowRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.neoforged.api.distmarker.Dist;
|
||||||
|
import net.neoforged.api.distmarker.OnlyIn;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public class LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow> {
|
||||||
|
public static final ResourceLocation LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/leash_rope_arrow.png");
|
||||||
|
public LeashRopeArrowRenderer(EntityRendererProvider.Context pContext) {
|
||||||
|
super(pContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResourceLocation getTextureLocation(@NotNull LeashRopeArrow pEntity) {
|
||||||
|
return LEASH_ROPE_ARROW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.r3944realms.leashedplayer.config;
|
||||||
|
|
||||||
|
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class LeashPlayerCommonConfig {
|
||||||
|
public static ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder();
|
||||||
|
public static final ModConfigSpec SPEC;
|
||||||
|
public static final ModConfigSpec.ConfigValue<String> LeashedPlayerModCommandPrefix;
|
||||||
|
public static final ModConfigSpec.BooleanValue EnableLeashPlayerCommandPrefix;
|
||||||
|
public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet;
|
||||||
|
public static ModConfigSpec.ConfigValue<Float> TheMultipleThatLeashRopeArrowBreakLength, TheLeashBreakLengthTimesBase;
|
||||||
|
static {
|
||||||
|
BUILDER.comment("Leash Player Config");
|
||||||
|
|
||||||
|
|
||||||
|
BUILDER.push("Command");
|
||||||
|
EnableLeashPlayerCommandPrefix = BUILDER.comment("The prefix of this mod's commands"," [ Default: true] ").define("Enable Leash Player Command", true);
|
||||||
|
LeashedPlayerModCommandPrefix = BUILDER.comment("The prefix of this mod's commands"," [ Default:'lp'] ").define("LeashedPlayerModCommandPrefix", "lp");
|
||||||
|
|
||||||
|
BUILDER.pop();
|
||||||
|
|
||||||
|
BUILDER.push("Leash Rope Arrow");
|
||||||
|
TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[1.0f, 10.0f] ]").define("TheMultipleArrowBreak", 5.0f, o -> (o instanceof Float f) && f >= 2.0f && f <= 10.0f);
|
||||||
|
|
||||||
|
BUILDER.pop();
|
||||||
|
|
||||||
|
BUILDER.push("Misc");
|
||||||
|
|
||||||
|
BUILDER.push("LeashLength");
|
||||||
|
TheLeashBreakLengthTimesBase = BUILDER.comment("When it exceeds how many times, the leash will drop","[ Default:2.0f, Invalid Range:[2.0f, 5.0f] ]").define("BreakLengthTimeBase", 2.0f, o -> (o instanceof Float f) && f >= 2.0f && f <= 5.0f);
|
||||||
|
MinimumLeashLengthCanBeSet = BUILDER.comment("The minimum integer's length of Leash", "[ Default:5, Invalid Range:[2,10] ]").defineInRange("MinLeashLength", 5, 2, 10);
|
||||||
|
MaximumLeashLengthCanBeSet = BUILDER.comment("The maximum integer's length of Leash", "[ Default:1024, Invalid Range:[32, 1024] ]").defineInRange("MaxLeashLength", 1024, 32, 1024);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SPEC = BUILDER.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.r3944realms.leashedplayer.content.commands;
|
package com.r3944realms.leashedplayer.content.commands;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||||
|
|
||||||
public class Command {
|
public class Command {
|
||||||
public static final String PREFIX = "lp";
|
public static final String PREFIX = LeashPlayerCommonConfig.LeashedPlayerModCommandPrefix.get();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent;
|
import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent;
|
||||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||||
|
|
@ -22,25 +23,47 @@ import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.Leashable;
|
import net.minecraft.world.entity.Leashable;
|
||||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class LeashCommand {
|
public class LeashCommand {
|
||||||
|
public static final Integer MIN_VALUE = LeashPlayerCommonConfig.MinimumLeashLengthCanBeSet.get();
|
||||||
|
public static final Integer MAX_VALUE = LeashPlayerCommonConfig.MaximumLeashLengthCanBeSet.get();
|
||||||
private final static String LEASHEDPLAYER_LEASH_MESSAGE_ = "leashedplayer.command.leash.message.";
|
private final static String LEASHEDPLAYER_LEASH_MESSAGE_ = "leashedplayer.command.leash.message.";
|
||||||
public final static String LEASH_FAILED = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.length.failed",
|
|
||||||
LEASH_LENGTH_SHOW = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.length.show",
|
|
||||||
LEASH_LENGTH_SET = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.length.set",
|
|
||||||
NO_LEASH_DATA = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.data.null",
|
|
||||||
LEASH_DATA_SHOW = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.data.show",
|
|
||||||
LEASH_DATA_SET = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.leash_data.set",
|
|
||||||
LEASH_DATA_SET_FAILED_DIFF_LEVEL = LEASH_DATA_SET + ".failed.diff_level",
|
|
||||||
LEASH_DATA_SET_FAILED_TOO_FAR = LEASH_DATA_SET + ".failed.too_far",
|
|
||||||
LEASH_DATA_SET_FAILED_NO_KNOT_EXISTED_IN_THAT_POS = LEASH_DATA_SET + ".failed.no_knot_exist_in_that_pos",
|
|
||||||
LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY = LEASH_DATA_SET + ".failed.forbid_same_entity";
|
|
||||||
|
|
||||||
|
public final static String LEASH_FAILED = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.length.failed";
|
||||||
|
|
||||||
|
public final static String LEASH_LENGTH_SHOW = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.length.show",
|
||||||
|
LEASH_LENGTH_SET = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.length.set",
|
||||||
|
LEASH_DATA = LEASHEDPLAYER_LEASH_MESSAGE_ + "leash.data",
|
||||||
|
LEASH_DATA_CLEAR = LEASH_DATA + ".clear"
|
||||||
|
;
|
||||||
|
|
||||||
|
public final static String NO_LEASH_DATA = LEASH_DATA + ".null",
|
||||||
|
LEASH_DATA_SHOW = LEASH_DATA + ".show",
|
||||||
|
LEASH_DATA_SET = LEASH_DATA + ".set",
|
||||||
|
LEASH_DATA_SET_FAILED_DIFF_LEVEL = LEASH_DATA_SET + ".failed.diff_level",
|
||||||
|
LEASH_DATA_SET_FAILED_TOO_FAR = LEASH_DATA_SET + ".failed.too_far",
|
||||||
|
LEASH_DATA_SET_FAILED_NO_KNOT_EXISTED_IN_THAT_POS = LEASH_DATA_SET + ".failed.no_knot_exist_in_that_pos",
|
||||||
|
LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY = LEASH_DATA_SET + ".failed.forbid_same_entity",
|
||||||
|
LEASH_DATA_CLEAR_FAILED_NO_DATA = LEASH_DATA_CLEAR + ".leash.clear.failed.no_data"
|
||||||
|
;
|
||||||
|
private static LiteralArgumentBuilder<CommandSourceStack> getLiterArgumentBuilderOfCSS(String name, boolean shouldAddToList, @Nullable List<LiteralArgumentBuilder<CommandSourceStack>> list) {
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> literal = Commands.literal(name);
|
||||||
|
if (shouldAddToList) {
|
||||||
|
assert list != null;
|
||||||
|
list.add(literal);
|
||||||
|
}
|
||||||
|
return literal;
|
||||||
|
}
|
||||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||||
|
boolean shouldUsePrefix = LeashPlayerCommonConfig.EnableLeashPlayerCommandPrefix.get();
|
||||||
|
@Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = shouldUsePrefix ? null : new ArrayList<>();
|
||||||
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
|
LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(com.r3944realms.leashedplayer.content.commands.Command.PREFIX);
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> $$leashRoot = getLiterArgumentBuilderOfCSS("leash", !shouldUsePrefix, nodeList);
|
||||||
|
|
||||||
Command<CommandSourceStack> getSelfLeashLength = context -> {
|
Command<CommandSourceStack> getSelfLeashLength = context -> {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
|
|
@ -96,7 +119,7 @@ public class LeashCommand {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
ServerPlayer player = source.getPlayerOrException();
|
ServerPlayer player = source.getPlayerOrException();
|
||||||
Integer x = LeashLengthResultInt(player, source);
|
Integer x = LeashLengthGetResultInt(player, source);
|
||||||
if (x != null) return x;
|
if (x != null) return x;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||||
|
|
@ -109,7 +132,7 @@ public class LeashCommand {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||||
Integer x = LeashLengthResultInt(player, source);
|
Integer x = LeashLengthGetResultInt(player, source);
|
||||||
if (x != null) return x;
|
if (x != null) return x;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||||
|
|
@ -122,7 +145,7 @@ public class LeashCommand {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
ServerPlayer player = source.getPlayerOrException();
|
ServerPlayer player = source.getPlayerOrException();
|
||||||
Integer x = LeashDataEntityResultInt(context, player, source);
|
Integer x = LeashDataEntitySetResultInt(context, player, source);
|
||||||
if (x != null) return x;
|
if (x != null) return x;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -135,7 +158,7 @@ public class LeashCommand {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
ServerPlayer player = source.getPlayerOrException();
|
ServerPlayer player = source.getPlayerOrException();
|
||||||
Integer x = LeashDataBlockPosResultInt(context, source, player);
|
Integer x = LeashDataBlockPosSetResultInt(context, source, player);
|
||||||
if (x != null) return x;
|
if (x != null) return x;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -150,7 +173,7 @@ public class LeashCommand {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||||
Integer x = LeashDataEntityResultInt(context, player, source);
|
Integer x = LeashDataEntitySetResultInt(context, player, source);
|
||||||
if (x != null) return x;
|
if (x != null) return x;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -163,7 +186,7 @@ public class LeashCommand {
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
try {
|
try {
|
||||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||||
Integer x = LeashDataBlockPosResultInt(context, source, player);
|
Integer x = LeashDataBlockPosSetResultInt(context, source, player);
|
||||||
if (x != null) return x;
|
if (x != null) return x;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -172,52 +195,73 @@ public class LeashCommand {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
LiteralArgumentBuilder<CommandSourceStack> $$leashRoot = Commands.literal("leash");
|
Command<CommandSourceStack> clearSelfLeashData = context -> {
|
||||||
literalArgumentBuilder.then(
|
CommandSourceStack source = context.getSource();
|
||||||
$$leashRoot.then(Commands.literal("length").executes(getSelfLeashLength)
|
try {
|
||||||
.then(Commands.literal("get").executes(getSelfLeashLength))
|
ServerPlayer player = source.getPlayerOrException();
|
||||||
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
Integer x = LeashDataClearResultInt(source, PlayerLeashable.getLeashDataEntity(player, source.getLevel()), player);
|
||||||
.then(Commands.argument("leashLength", FloatArgumentType.floatArg(5, 1024)).executes(setSelfLengthLeashLength)
|
if (x != null) return x;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
Command<CommandSourceStack> clearRefPlayerLeashData = context -> {
|
||||||
|
CommandSourceStack source = context.getSource();
|
||||||
|
try {
|
||||||
|
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||||
|
Integer x = LeashDataClearResultInt(source, PlayerLeashable.getLeashDataEntityOrThrown(player, source.getLevel()),player);
|
||||||
|
if (x != null) return x;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> SelfLeashLength = $$leashRoot.then(Commands.literal("length").executes(getSelfLeashLength)
|
||||||
|
.then(Commands.literal("get").executes(getSelfLeashLength))
|
||||||
|
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
||||||
|
.then(Commands.argument("leashLength", FloatArgumentType.floatArg(MIN_VALUE, MAX_VALUE)).executes(setSelfLengthLeashLength))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> RefPlayerLeashLength = $$leashRoot.then(
|
||||||
|
Commands.literal("length")
|
||||||
|
.then(Commands.argument("player", EntityArgument.player()).executes(getRefPlayerLeashLength)
|
||||||
|
.then(Commands.literal("get").executes(getRefPlayerLeashLength))
|
||||||
|
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
||||||
|
.then(
|
||||||
|
Commands.argument("leashLength", FloatArgumentType.floatArg(MIN_VALUE, MAX_VALUE)).executes(setLengthLeashLength)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
literalArgumentBuilder.then(
|
|
||||||
$$leashRoot.then(
|
|
||||||
Commands.literal("length")
|
|
||||||
.then(Commands.argument("player", EntityArgument.player()).executes(getRefPlayerLeashLength)
|
|
||||||
.then(Commands.literal("get").executes(getRefPlayerLeashLength))
|
|
||||||
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
|
||||||
.then(
|
|
||||||
Commands.argument("leashLength", FloatArgumentType.floatArg(5, 1024)).executes(setLengthLeashLength)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
LiteralArgumentBuilder<CommandSourceStack> RefPLayerData = $$leashRoot.then(
|
||||||
);
|
Commands.literal("data")
|
||||||
literalArgumentBuilder.then(
|
.then(Commands.argument("targetPlayer", EntityArgument.player()).executes(getRefPlayerLeashData)
|
||||||
$$leashRoot.then(
|
.then(Commands.literal("get")
|
||||||
Commands.literal("data")
|
.executes(getRefPlayerLeashData)
|
||||||
.then(Commands.argument("targetPlayer", EntityArgument.player()).executes(getRefPlayerLeashData)
|
)
|
||||||
.then(Commands.literal("get")
|
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
||||||
.executes(getRefPlayerLeashData)
|
.then(Commands.argument("holderEntity", EntityArgument.entity())
|
||||||
|
.executes(setRefPlayerLeashDataEntity)
|
||||||
)
|
)
|
||||||
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
.then(Commands.argument("BlockPos", BlockPosArgument.blockPos())
|
||||||
.then(Commands.argument("holderEntity", EntityArgument.entity())
|
.executes(setRefPlayerLeashDataByBlockPos)
|
||||||
.executes(setRefPlayerLeashDataEntity)
|
|
||||||
)
|
|
||||||
.then(Commands.argument("BlockPos", BlockPosArgument.blockPos())
|
|
||||||
.executes(setRefPlayerLeashDataByBlockPos)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
.then(Commands.literal("clear").requires(cs -> cs.hasPermission(2)).executes(clearSelfLeashData))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
literalArgumentBuilder.then(
|
|
||||||
$$leashRoot.then(
|
LiteralArgumentBuilder<CommandSourceStack> SelfData = $$leashRoot.then(
|
||||||
Commands.literal("data")
|
Commands.literal("data")
|
||||||
.then(Commands.literal("get")
|
.then(Commands.literal("get")
|
||||||
.executes(geSelfLeashData)
|
.executes(geSelfLeashData)
|
||||||
)
|
)
|
||||||
|
|
@ -229,12 +273,25 @@ public class LeashCommand {
|
||||||
.executes(setSelfLeashDataByBlockPos)
|
.executes(setSelfLeashDataByBlockPos)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
.then(Commands.literal("clear").requires(cs -> cs.hasPermission(2))
|
||||||
|
.executes(clearSelfLeashData)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
dispatcher.register(literalArgumentBuilder);
|
|
||||||
|
if(shouldUsePrefix) {
|
||||||
|
literalArgumentBuilder
|
||||||
|
.then(RefPlayerLeashLength)
|
||||||
|
.then(SelfLeashLength)
|
||||||
|
.then(RefPLayerData)
|
||||||
|
.then(SelfData);
|
||||||
|
dispatcher.register(literalArgumentBuilder);
|
||||||
|
} else {
|
||||||
|
nodeList.forEach(dispatcher::register);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable Integer LeashLengthResultInt(ServerPlayer player, CommandSourceStack source) throws Exception {
|
private static @Nullable Integer LeashLengthGetResultInt(ServerPlayer player, CommandSourceStack source) throws Exception {
|
||||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) player).getLeashDataFromEntityData();
|
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) player).getLeashDataFromEntityData();
|
||||||
|
|
||||||
if(leashDataFromEntityData == null) {
|
if(leashDataFromEntityData == null) {
|
||||||
|
|
@ -247,7 +304,7 @@ public class LeashCommand {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable Integer LeashDataBlockPosResultInt(CommandContext<CommandSourceStack> context, CommandSourceStack source, ServerPlayer player) {
|
private static @Nullable Integer LeashDataBlockPosSetResultInt(CommandContext<CommandSourceStack> context, CommandSourceStack source, ServerPlayer player) {
|
||||||
BlockPos blockPos = BlockPosArgument.getBlockPos(context, "BlockPos");
|
BlockPos blockPos = BlockPosArgument.getBlockPos(context, "BlockPos");
|
||||||
Entity leashDataEntity = PlayerLeashable.getLeashFenceKnotEntity(source.getLevel(), blockPos);
|
Entity leashDataEntity = PlayerLeashable.getLeashFenceKnotEntity(source.getLevel(), blockPos);
|
||||||
PlayerLeashable leashedPlayer = (PlayerLeashable) player;
|
PlayerLeashable leashedPlayer = (PlayerLeashable) player;
|
||||||
|
|
@ -267,10 +324,10 @@ public class LeashCommand {
|
||||||
}
|
}
|
||||||
Component leashDataEntityDisplayName = leashDataEntity.getDisplayName();
|
Component leashDataEntityDisplayName = leashDataEntity.getDisplayName();
|
||||||
|
|
||||||
return LeashDataCommonPartResultInt(source, player, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
return LeashDataCommonPartSetResultInt(source, player, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable Integer LeashDataEntityResultInt(CommandContext<CommandSourceStack> context, ServerPlayer player, CommandSourceStack source) throws CommandSyntaxException {
|
private static @Nullable Integer LeashDataEntitySetResultInt(CommandContext<CommandSourceStack> context, ServerPlayer player, CommandSourceStack source) throws CommandSyntaxException {
|
||||||
Entity leashDataEntity = EntityArgument.getEntity(context, "holderEntity");
|
Entity leashDataEntity = EntityArgument.getEntity(context, "holderEntity");
|
||||||
PlayerLeashable leashedPlayer = (PlayerLeashable) player;
|
PlayerLeashable leashedPlayer = (PlayerLeashable) player;
|
||||||
Component targetPlayerDisplayName = player.getDisplayName();
|
Component targetPlayerDisplayName = player.getDisplayName();
|
||||||
|
|
@ -279,10 +336,10 @@ public class LeashCommand {
|
||||||
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY));
|
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return LeashDataCommonPartResultInt(source, player, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
return LeashDataCommonPartSetResultInt(source, player, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable Integer LeashDataCommonPartResultInt(CommandSourceStack source, ServerPlayer player, Entity leashDataEntity, PlayerLeashable leashedPlayer, Component targetPlayerDisplayName, Component leashDataEntityDisplayName) {
|
private static @Nullable Integer LeashDataCommonPartSetResultInt(CommandSourceStack source, ServerPlayer player, Entity leashDataEntity, PlayerLeashable leashedPlayer, Component targetPlayerDisplayName, Component leashDataEntityDisplayName) {
|
||||||
if(player.level() != leashDataEntity.level()) {
|
if(player.level() != leashDataEntity.level()) {
|
||||||
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_DIFF_LEVEL, targetPlayerDisplayName, leashDataEntityDisplayName));
|
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_DIFF_LEVEL, targetPlayerDisplayName, leashDataEntityDisplayName));
|
||||||
return 2;
|
return 2;
|
||||||
|
|
@ -296,6 +353,15 @@ public class LeashCommand {
|
||||||
source.sendSuccess(() -> Component.translatable(LEASH_DATA_SET, targetPlayerDisplayName, leashDataEntityDisplayName), true);
|
source.sendSuccess(() -> Component.translatable(LEASH_DATA_SET, targetPlayerDisplayName, leashDataEntityDisplayName), true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
private static @Nullable Integer LeashDataClearResultInt(CommandSourceStack source, Entity leashDataEntity, ServerPlayer serverPlayer) {
|
||||||
|
if(leashDataEntity == null) {
|
||||||
|
source.sendFailure(Component.translatable(LEASH_DATA_CLEAR_FAILED_NO_DATA, serverPlayer.getDisplayName()));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
((PlayerLeashable)serverPlayer).dropLeash(true, false);
|
||||||
|
source.sendSuccess(() -> Component.translatable(LEASH_DATA_CLEAR, serverPlayer.getDisplayName(), leashDataEntity.getDisplayName()), true);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
package com.r3944realms.leashedplayer.content.entities;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||||
|
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.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.BlockHitResult;
|
||||||
|
import net.minecraft.world.phys.EntityHitResult;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class LeashRopeArrow extends AbstractArrow {
|
||||||
|
protected LeashRopeArrow(EntityType<? extends AbstractArrow> entityType,Level pLevel) {
|
||||||
|
super(entityType, pLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LeashRopeArrow(double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) {
|
||||||
|
super(ModEntityRegister.LEASH_ROPE_ARROW.get(), pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||||
|
if(serverPlayer != null && !level().isClientSide) {
|
||||||
|
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LeashRopeArrow(LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
||||||
|
super(ModEntityRegister.LEASH_ROPE_ARROW.get(), pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||||
|
if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
|
||||||
|
lPlayer.setLeashedTo(this, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull ItemStack getDefaultPickupItem() {
|
||||||
|
return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOwner(@Nullable Entity pEntity) {
|
||||||
|
super.setOwner(pEntity);
|
||||||
|
|
||||||
|
this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean tryPickup(@NotNull Player pPlayer) {
|
||||||
|
if(life <= 240) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if(life >= 480 || this.ownedBy(pPlayer) && (this.pickup != Pickup.CREATIVE_ONLY) ) {
|
||||||
|
this.pickup = Pickup.ALLOWED;
|
||||||
|
if(this.ownedBy(pPlayer)) {
|
||||||
|
((PlayerLeashable)pPlayer).dropLeash(true, false);
|
||||||
|
} else if (this.getOwner() instanceof PlayerLeashable pL){
|
||||||
|
pL.setLeashedTo(this, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.tryPickup(pPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tickDespawn() {
|
||||||
|
this.life++;
|
||||||
|
if (this.life >= 2400) {//TODO 加到配置中去,修改
|
||||||
|
ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance());
|
||||||
|
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, true);
|
||||||
|
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
|
||||||
|
pL.setLeashedTo(leashKnotFence, true);
|
||||||
|
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance());
|
||||||
|
this.level().addFreshEntity(arrow);
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onHitBlock(pResult);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onHitEntity(@NotNull EntityHitResult pResult) {
|
||||||
|
if(!level().isClientSide()){
|
||||||
|
if(pResult.getEntity() instanceof LivingEntity){
|
||||||
|
if (getOwner() instanceof PlayerLeashable pL) {
|
||||||
|
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||||
|
if(leashDataEntity != null) pL.dropLeash(true, true);
|
||||||
|
pL.setLeashedTo(pResult.getEntity(), true);
|
||||||
|
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance());
|
||||||
|
this.level().addFreshEntity(arrow);
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onHitEntity(pResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.r3944realms.leashedplayer.content.entities;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.MobCategory;
|
||||||
|
import net.neoforged.bus.api.IEventBus;
|
||||||
|
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||||
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
|
|
||||||
|
public class ModEntityRegister {
|
||||||
|
public static final DeferredRegister<EntityType<?>> ENTITY_TYPE = DeferredRegister.create(Registries.ENTITY_TYPE, LeashedPlayer.MOD_ID);
|
||||||
|
public static final DeferredHolder<EntityType<?> ,EntityType<LeashRopeArrow>> LEASH_ROPE_ARROW = ENTITY_TYPE.register(
|
||||||
|
"leash_rope_arrow",
|
||||||
|
() -> EntityType.Builder.<LeashRopeArrow>of(LeashRopeArrow::new, MobCategory.MISC)
|
||||||
|
.sized(0.5F, 0.5F)
|
||||||
|
.eyeHeight(0.13F)
|
||||||
|
.clientTrackingRange(4)
|
||||||
|
.updateInterval(20)
|
||||||
|
.build("leash_rope_arrow")
|
||||||
|
);
|
||||||
|
public static String getEntityNameKey(String entityName) {
|
||||||
|
return "entity." + LeashedPlayer.MOD_ID + "." + entityName;
|
||||||
|
}
|
||||||
|
public static void register(IEventBus eventBus) {
|
||||||
|
ENTITY_TYPE.register(eventBus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.r3944realms.leashedplayer.content.items;
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||||
|
import net.minecraft.world.item.ArrowItem;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class LeashRopeArrowItem extends ArrowItem {
|
||||||
|
public static final String descKey = "item.leash_rope_arrow.description";
|
||||||
|
public LeashRopeArrowItem(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.LeashRopeArrow(pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Component getDescription() {
|
||||||
|
return Component.translatable(descKey).withStyle(ChatFormatting.GRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.r3944realms.leashedplayer.content.items;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
|
import net.minecraft.world.item.CreativeModeTabs;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.neoforged.bus.api.IEventBus;
|
||||||
|
|
||||||
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ModCreativeTab {
|
||||||
|
public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS =
|
||||||
|
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()
|
||||||
|
.withTabsBefore(CreativeModeTabs.COMBAT)
|
||||||
|
.title(Component.translatable(getCreativeMod(LEASHED_PLAYER_ITEM)))
|
||||||
|
.icon(() -> ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance())
|
||||||
|
.displayItems(((pParameters, pOutput) -> {
|
||||||
|
pOutput.accept(Items.LEAD);
|
||||||
|
pOutput.accept(ModItemRegister.LEASH_ROPE_ARROW.get());
|
||||||
|
})).build());
|
||||||
|
public static String getCreativeMod(@NotNull String tabs) {
|
||||||
|
return LEASHED_PLAYER_TAB_STRING + "." + tabs;
|
||||||
|
}
|
||||||
|
public static void register(IEventBus eventBus) {
|
||||||
|
CREATIVE_MODE_TABS.register(eventBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.r3944realms.leashedplayer.content.items;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.neoforged.bus.api.IEventBus;
|
||||||
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
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 Supplier<Item> register(String name, Supplier<Item> supplier) {
|
||||||
|
return register(name, supplier, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Supplier<Item> register(String name, Supplier<Item> supplier, boolean shouldJoinSupplierLists) {
|
||||||
|
Supplier<Item> supplierItem = ITEMS.register(name, supplier);
|
||||||
|
if(shouldJoinSupplierLists) ITEM_SUPPLIER.add(supplierItem);
|
||||||
|
return supplierItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(IEventBus eventBus) {
|
||||||
|
ITEMS.register(eventBus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
package com.r3944realms.leashedplayer.datagen.LanguageAndOtherData;
|
package com.r3944realms.leashedplayer.datagen.LanguageAndOtherData;
|
||||||
|
|
||||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent;
|
import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers;
|
import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers;
|
||||||
|
import com.r3944realms.leashedplayer.content.items.LeashRopeArrowItem;
|
||||||
|
import com.r3944realms.leashedplayer.content.items.ModCreativeTab;
|
||||||
|
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||||
import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum;
|
import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum;
|
||||||
import com.r3944realms.leashedplayer.utils.Enum.ModPartEnum;
|
import com.r3944realms.leashedplayer.utils.Enum.ModPartEnum;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
|
|
@ -12,24 +17,36 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static com.r3944realms.leashedplayer.content.items.ModCreativeTab.LEASHED_PLAYER_ITEM;
|
||||||
|
|
||||||
public enum ModLangKeyValue {
|
public enum ModLangKeyValue {
|
||||||
|
//ITEM
|
||||||
|
ITEM_LEASH_ROPE_ARROW(ModItemRegister.LEASH_ROPE_ARROW, ModPartEnum.ITEM, "Leash Rope Arrow", "拴绳箭", "拴繩箭", true),
|
||||||
|
//ITEM_DESC
|
||||||
|
DESC_ITEM_LEASH_ROPE_ARROW(LeashRopeArrowItem.descKey, ModPartEnum.DESCRIPTION, "Arrows with ropes attached?","带有拴绳的箭矢?", "帶有拴繩的箭矢?", false),
|
||||||
|
//ENTITY
|
||||||
|
LEASH_ROPE_ARROW(ModEntityRegister.getEntityNameKey("leash_rope_arrow"), ModPartEnum.ENTITY, "Leash Rope Arrow", "拴绳箭", "拴繩箭", false),
|
||||||
|
//CREATIVE_TAB
|
||||||
|
CREATIVE_TAB_NAME(ModCreativeTab.getCreativeMod(LEASHED_PLAYER_ITEM), ModPartEnum.CREATIVE_TAB, "Leashed Player","可拴玩家", "可拴玩家", false),
|
||||||
//COMMAND_MESSAGE
|
//COMMAND_MESSAGE
|
||||||
MESSAGE_LEASH_LENGTH_FAILED(LeashCommand.LEASH_FAILED, ModPartEnum.COMMAND, "Failed (Internal Error, maybe your command is incorrect)", "失败(内部错误,可能是你输的指令有误)", "失敗(内部錯誤,,可能你輸入的指令有誤)", false),
|
MESSAGE_LEASH_LENGTH_FAILED(LeashCommand.LEASH_FAILED, ModPartEnum.COMMAND, "Failed (Internal Error, maybe your command is incorrect)", "失败(内部错误,可能是你输的指令有误)", "失敗(内部錯誤,,可能你輸入的指令有誤)", false),
|
||||||
MESSAGE_LEASH_LENGTH_SHOW(LeashCommand.LEASH_LENGTH_SHOW, ModPartEnum.COMMAND, "The Leash Length of %1$s is %2$s blocks", "%1$s的拴绳长度为%2$s格", "%1$s的栓繩長度為%2$s格" , false),
|
MESSAGE_LEASH_LENGTH_SHOW(LeashCommand.LEASH_LENGTH_SHOW, ModPartEnum.COMMAND, "The Leash Length of %1$s is %2$s blocks", "%1$s的拴绳长度为%2$s格", "%1$s的拴繩長度為%2$s格" , false),
|
||||||
MESSAGE_LEASH_LENGTH_SET(LeashCommand.LEASH_LENGTH_SET, ModPartEnum.COMMAND, "The Leash length of %1$s is set to %2$s blocks", "%1$s的拴绳长度被设置为%2$s格", "%1$s的栓繩長度被設置為%2$s格" , false),
|
MESSAGE_LEASH_LENGTH_SET(LeashCommand.LEASH_LENGTH_SET, ModPartEnum.COMMAND, "The Leash length of %1$s is set to %2$s blocks", "%1$s的拴绳长度被设置为%2$s格", "%1$s的拴繩長度被設置為%2$s格" , false),
|
||||||
MESSAGE_LEASH_GET_LEASH_DATA(LeashCommand.LEASH_DATA_SHOW, ModPartEnum.COMMAND, "%1$s's LeashDataEntity is %2$s", "%1$s的拴绳数据实体为%2$s", "%1$s栓繩數據實體為%2$s",false),
|
MESSAGE_LEASH_GET_LEASH_DATA(LeashCommand.LEASH_DATA_SHOW, ModPartEnum.COMMAND, "%1$s's LeashDataEntity is %2$s", "%1$s的拴绳数据实体为%2$s", "%1$s拴繩數據實體為%2$s",false),
|
||||||
MESSAGE_LEASH_NO_LEASH_DATA(LeashCommand.NO_LEASH_DATA, ModPartEnum.COMMAND, "%1$s has no LeashDataEntity", "%1$s沒有拴绳数据实体", "%1$s沒有栓繩數據實體", false),
|
MESSAGE_LEASH_NO_LEASH_DATA(LeashCommand.NO_LEASH_DATA, ModPartEnum.COMMAND, "%1$s has no LeashDataEntity", "%1$s沒有拴绳数据实体", "%1$s沒有拴繩數據實體", false),
|
||||||
MESSAGE_LEASH_SET_LEASH_DATA(LeashCommand.LEASH_DATA_SET, ModPartEnum.COMMAND, "%1$s LeashDataEntity now is set as %2$s", "%1$s拴绳数据实体被设置为%2$s", "%1$s栓繩數據實體設置為%2$s", false),
|
MESSAGE_LEASH_SET_LEASH_DATA(LeashCommand.LEASH_DATA_SET, ModPartEnum.COMMAND, "%1$s LeashDataEntity now is set as %2$s", "%1$s拴绳数据实体被设置为%2$s", "%1$s拴繩數據實體設置為%2$s", false),
|
||||||
MESSAGE_LEASH_SET_FAILED_DIFF_LEVEL(LeashCommand.LEASH_DATA_SET_FAILED_DIFF_LEVEL, ModPartEnum.COMMAND,"%1$s and %2$s are not at a same level", "%1$s和%2$s不在同一维度上", "%1$s和%2$s不在同一緯度上", false),
|
MESSAGE_LEASH_SET_FAILED_DIFF_LEVEL(LeashCommand.LEASH_DATA_SET_FAILED_DIFF_LEVEL, ModPartEnum.COMMAND,"%1$s and %2$s are not at a same level", "%1$s和%2$s不在同一维度上", "%1$s和%2$s不在同一緯度上", false),
|
||||||
MESSAGE_LEASH_SET_FAILED_TOO_FAR(LeashCommand.LEASH_DATA_SET_FAILED_TOO_FAR, ModPartEnum.COMMAND,"The distance between %1$s and %2$s is larger than the 1.2 times of LeashLength, LeashLength is %3$s blocks", "%1$s到%2$s的距离超过了1.2倍 栓绳长度,原长:%3$s 格", "%1$s到%2$s的距離超過了1.2倍栓繩長度,原長:%3$s 格", false),
|
MESSAGE_LEASH_SET_FAILED_TOO_FAR(LeashCommand.LEASH_DATA_SET_FAILED_TOO_FAR, ModPartEnum.COMMAND,"The distance between %1$s and %2$s is larger than the 1.2 times of LeashLength, LeashLength is %3$s blocks", "%1$s到%2$s的距离超过了1.2倍 拴绳长度,原长:%3$s 格", "%1$s到%2$s的距離超過了1.2倍拴繩長度,原長:%3$s 格", false),
|
||||||
MESSAGE_LEASH_SET_FAILED_NO_KNOT_EXIST_IN_THAT_POS(LeashCommand.LEASH_DATA_SET_FAILED_NO_KNOT_EXISTED_IN_THAT_POS, ModPartEnum.COMMAND, "No knot found at (X:%f,Y:%f,Z:%f)", "未找到栓绳结在(X:%f, Y:%f, Z:%f)处", "未找到栓繩結在(X:%f, Y:%f, Z:%f)処", false),
|
MESSAGE_LEASH_SET_FAILED_NO_KNOT_EXIST_IN_THAT_POS(LeashCommand.LEASH_DATA_SET_FAILED_NO_KNOT_EXISTED_IN_THAT_POS, ModPartEnum.COMMAND, "No knot found at (X:%f,Y:%f,Z:%f)", "未找到拴绳结在(X:%f, Y:%f, Z:%f)处", "未找到拴繩結在(X:%f, Y:%f, Z:%f)処", false),
|
||||||
|
MESSAGE_LEASH_CLEAR(LeashCommand.LEASH_DATA_CLEAR, ModPartEnum.COMMAND, "%1$s's LeashData(LeashHolderEntity: %2$s) now is clear", "%1$s的拴绳数据(拴绳持有者实体:%2$s)现在已清除", "%1$s的拴繩數據(拴繩持有者實體:%2$s)現在已清除", false),
|
||||||
MESSAGE_LEASH_SET_FAILED_FORBID_SAME_ENTITY(LeashCommand.LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY, ModPartEnum.COMMAND, "Prohibit setting the same entity","禁止设置同一实体", "禁止設置同一實體", false),
|
MESSAGE_LEASH_SET_FAILED_FORBID_SAME_ENTITY(LeashCommand.LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY, ModPartEnum.COMMAND, "Prohibit setting the same entity","禁止设置同一实体", "禁止設置同一實體", false),
|
||||||
|
MESSAGE_LEASH_CLEAR_FAILED(LeashCommand.LEASH_DATA_CLEAR_FAILED_NO_DATA, ModPartEnum.COMMAND, "%1$s has no LeashData can be clear", "%1$s沒有拴绳数据可清除", "%1$s沒有拴繩數據實體可被清除", false),
|
||||||
//GAME_RULE_NAME
|
//GAME_RULE_NAME
|
||||||
TELEPORT_WITH_LEASHED_PLAYERS(TeleportWithLeashedPlayers.NAME_KEY, ModPartEnum.NAME, "Teleport leashed player with player holder", "被栓玩家随玩家持有者传送", "被栓玩家随玩家持有者傳送" ,false),
|
TELEPORT_WITH_LEASHED_PLAYERS(TeleportWithLeashedPlayers.NAME_KEY, ModPartEnum.NAME, "Teleport leashed player with player holder", "被拴玩家随玩家持有者传送", "被拴玩家随玩家持有者傳送" ,false),
|
||||||
CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT(CreateLeashFenceKnotEntityIfAbsent.NAME_KEY, ModPartEnum.NAME, "Create Leash Fence Knot Entity if absent", "如果缺失则创建栓绳结", "如果缺失則創建栓繩結", false),
|
CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT(CreateLeashFenceKnotEntityIfAbsent.NAME_KEY, ModPartEnum.NAME, "Create Leash Fence Knot Entity if absent", "如果缺失则创建拴绳结", "如果缺失則創建拴繩結", false),
|
||||||
//GAME_RULE_DESCRIPTION
|
//GAME_RULE_DESCRIPTION
|
||||||
TELEPORT_WITH_LEASHED_DESCRIPTION(TeleportWithLeashedPlayers.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Holder will teleport with their leashed players ", "传送时将被栓玩家与持有者一起传送", "將被栓玩家將隨持有者一起傳送" ,false),
|
TELEPORT_WITH_LEASHED_DESCRIPTION(TeleportWithLeashedPlayers.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Holder will teleport with their leashed players ", "传送时将被拴玩家与持有者一起传送", "將被拴玩家將隨持有者一起傳送" ,false),
|
||||||
CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT_DESCRIPTION(CreateLeashFenceKnotEntityIfAbsent.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Create LeashKnot Entity if it's absent on fence", "如果在栅栏处缺失栓绳结,则创建它", "如果在柵欄処缺失拴繩結,則創建它",false),
|
CREATE_LEASH_FENCE_KNOT_ENTITY_IF_ABSENT_DESCRIPTION(CreateLeashFenceKnotEntityIfAbsent.DESCRIPTION_KEY, ModPartEnum.DESCRIPTION, "Create LeashKnot Entity if it's absent on fence", "如果在栅栏处缺失拴绳结,则创建它", "如果在柵欄処缺失拴繩結,則創建它",false),
|
||||||
|
|
||||||
;
|
;
|
||||||
private final Supplier<?> supplier;
|
private final Supplier<?> supplier;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.r3944realms.leashedplayer.datagen;
|
package com.r3944realms.leashedplayer.datagen;
|
||||||
|
|
||||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
import com.r3944realms.leashedplayer.datagen.provider.ModLanguageProvider;
|
import com.r3944realms.leashedplayer.datagen.provider.*;
|
||||||
import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum;
|
import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.data.DataProvider;
|
import net.minecraft.data.DataProvider;
|
||||||
|
|
@ -24,6 +24,9 @@ public class ModDataGeneratorHandler {
|
||||||
addLanguage(event, LanguageEnum.SimpleChinese, "zh_cn");
|
addLanguage(event, LanguageEnum.SimpleChinese, "zh_cn");
|
||||||
addLanguage(event, LanguageEnum.TraditionalChinese, "zh_tw");
|
addLanguage(event, LanguageEnum.TraditionalChinese, "zh_tw");
|
||||||
addLanguage(event, LanguageEnum.LiteraryChinese, "lzh");
|
addLanguage(event, LanguageEnum.LiteraryChinese, "lzh");
|
||||||
|
ItemModelGenerator(event, existingFileHelper);
|
||||||
|
RecipeGenerator(event, HolderFolder);
|
||||||
|
ModTagsProvider(event, event.getLookupProvider(), existingFileHelper);
|
||||||
}
|
}
|
||||||
private static void addLanguage(GatherDataEvent event, LanguageEnum language, String lan_regex){
|
private static void addLanguage(GatherDataEvent event, LanguageEnum language, String lan_regex){
|
||||||
event.getGenerator().addProvider(
|
event.getGenerator().addProvider(
|
||||||
|
|
@ -31,4 +34,28 @@ public class ModDataGeneratorHandler {
|
||||||
(DataProvider.Factory<ModLanguageProvider>) pOutput -> new ModLanguageProvider(pOutput, LeashedPlayer.MOD_ID, language)
|
(DataProvider.Factory<ModLanguageProvider>) pOutput -> new ModLanguageProvider(pOutput, LeashedPlayer.MOD_ID, language)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
private static void ItemModelGenerator(GatherDataEvent event, ExistingFileHelper helper) {
|
||||||
|
event.getGenerator().addProvider(
|
||||||
|
event.includeClient(),
|
||||||
|
(DataProvider.Factory<ModItemModelProvider>) pOutput -> new ModItemModelProvider(pOutput, LeashedPlayer.MOD_ID, helper)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private static void RecipeGenerator(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> future) {
|
||||||
|
event.getGenerator().addProvider(
|
||||||
|
event.includeServer(),
|
||||||
|
(DataProvider.Factory<ModRecipeProvider>) pOutput -> new ModRecipeProvider(pOutput, future)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private static void ModTagsProvider(GatherDataEvent event, CompletableFuture<HolderLookup.Provider> completableFuture, ExistingFileHelper helper) {
|
||||||
|
ModBlockTagProvider modBlockTagProvider = event.getGenerator().addProvider(
|
||||||
|
event.includeServer(),
|
||||||
|
(DataProvider.Factory<ModBlockTagProvider>) pOutput ->
|
||||||
|
new ModBlockTagProvider(pOutput, completableFuture, LeashedPlayer.MOD_ID, helper)
|
||||||
|
);
|
||||||
|
event.getGenerator().addProvider(
|
||||||
|
event.includeServer(),
|
||||||
|
(DataProvider.Factory<ModItemTagProvider>) pOutput ->
|
||||||
|
new ModItemTagProvider(pOutput, completableFuture, modBlockTagProvider.contentsGetter(), helper)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.r3944realms.leashedplayer.datagen.provider;
|
||||||
|
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.neoforged.neoforge.common.data.BlockTagsProvider;
|
||||||
|
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class ModBlockTagProvider extends BlockTagsProvider {
|
||||||
|
public ModBlockTagProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, String modId, @Nullable ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, lookupProvider, modId, existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addTags(HolderLookup.@NotNull Provider pProvider) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.r3944realms.leashedplayer.datagen.provider;
|
||||||
|
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.datagen.LanguageAndOtherData.ModLangKeyValue;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.neoforged.neoforge.client.model.generators.ItemModelProvider;
|
||||||
|
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ModItemModelProvider extends ItemModelProvider {
|
||||||
|
private static List<Item> objectList;
|
||||||
|
public ModItemModelProvider(PackOutput output, String modId, ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, modId, existingFileHelper);
|
||||||
|
objectList = new ArrayList<>();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
private void init() {
|
||||||
|
for(ModLangKeyValue obj : ModLangKeyValue.values()) {
|
||||||
|
if(!obj.isDefaultItem()) continue;
|
||||||
|
objectList.add(obj.getItem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @implNote 先有纹理才会成功构建
|
||||||
|
*/
|
||||||
|
private void DefaultModItemModelRegister() {
|
||||||
|
objectList.forEach(this::basicItem);
|
||||||
|
}
|
||||||
|
private void AdvancedModItemModelRegister() {
|
||||||
|
/*手动生成更快,其实*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerModels() {
|
||||||
|
// 注册默认材质物品模型
|
||||||
|
DefaultModItemModelRegister();
|
||||||
|
// 注册进阶材质物品模型(非模板大量需要,可以用BlockBench生成的就行了)
|
||||||
|
AdvancedModItemModelRegister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.r3944realms.leashedplayer.datagen.provider;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.data.tags.ItemTagsProvider;
|
||||||
|
import net.minecraft.tags.ItemTags;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class ModItemTagProvider extends ItemTagsProvider {
|
||||||
|
|
||||||
|
public ModItemTagProvider(PackOutput pOutput, CompletableFuture<HolderLookup.Provider> pLookupProvider, CompletableFuture<TagLookup<Block>> pBlockTags, ExistingFileHelper pExistingFileHelper) {
|
||||||
|
super(pOutput, pLookupProvider, pBlockTags, LeashedPlayer.MOD_ID, pExistingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addTags(HolderLookup.@NotNull Provider pProvider) {
|
||||||
|
this.tag(ItemTags.ARROWS)
|
||||||
|
.add(ModItemRegister.LEASH_ROPE_ARROW.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.r3944realms.leashedplayer.datagen.provider;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.data.recipes.*;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class ModRecipeProvider extends RecipeProvider {
|
||||||
|
public ModRecipeProvider(PackOutput pOutput, CompletableFuture<HolderLookup.Provider> future) {
|
||||||
|
super(pOutput, future);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void buildRecipes(@NotNull RecipeOutput pRecipeOutput) {
|
||||||
|
|
||||||
|
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItemRegister.LEASH_ROPE_ARROW.get(),1)
|
||||||
|
.requires(Items.LEAD)
|
||||||
|
.requires(Items.ARROW)
|
||||||
|
.unlockedBy("has_lead",has(Items.LEAD))
|
||||||
|
.save(pRecipeOutput);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,14 @@ import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.Leashable;
|
import net.minecraft.world.entity.Leashable;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public class MixinEntity {
|
public abstract class MixinEntity {
|
||||||
|
@Shadow public abstract void igniteForSeconds(float pSeconds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 这里重定向,当实体类实现了{@link PlayerLeashable}接口时,<br/>
|
* 这里重定向,当实体类实现了{@link PlayerLeashable}接口时,<br/>
|
||||||
* 阻止原版的{@link Leashable}中 的tickLeash方法调用,将其<br/>
|
* 阻止原版的{@link Leashable}中 的tickLeash方法调用,将其<br/>
|
||||||
|
|
@ -25,4 +28,5 @@ public class MixinEntity {
|
||||||
Leashable.tickLeash(entity);
|
Leashable.tickLeash(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
package com.r3944realms.leashedplayer.mixin.both;
|
package com.r3944realms.leashedplayer.mixin.both;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||||
|
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
@ -7,10 +11,12 @@ import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.Leashable;
|
import net.minecraft.world.entity.Leashable;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
|
@ -22,11 +28,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Mixin(Player.class)
|
@Mixin(Player.class)
|
||||||
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable {
|
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable {
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
@Nullable
|
@Nullable
|
||||||
private LeashData Pl$LeashData;//Data
|
private LeashData Pl$LeashData;//Data
|
||||||
|
|
@ -53,41 +59,55 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl
|
||||||
}
|
}
|
||||||
@Unique
|
@Unique
|
||||||
private static void Pl$UpdateLeash(Entity holderEntity, Entity restrainedEntity) {
|
private static void Pl$UpdateLeash(Entity holderEntity, Entity restrainedEntity) {
|
||||||
if(holderEntity == null || holderEntity.level() != restrainedEntity.level())
|
if (holderEntity == null || holderEntity.level() != restrainedEntity.level()) {
|
||||||
return;
|
return;
|
||||||
float leashLength = 6.0f;
|
|
||||||
if(restrainedEntity instanceof ILivingEntityExtension iEntity) {
|
|
||||||
//获取长度
|
|
||||||
float leashLengthFormValue = iEntity.getLeashLength();
|
|
||||||
leashLength = leashLengthFormValue > 6 ? leashLengthFormValue : 6;
|
|
||||||
}
|
|
||||||
//两者距离
|
|
||||||
float distance = holderEntity.distanceTo(restrainedEntity);
|
|
||||||
//大于长度情况
|
|
||||||
if(distance > leashLength) {
|
|
||||||
//作用对象(实体所坐载体还是实体【根据isPassenger来判断】
|
|
||||||
Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity;
|
|
||||||
if(applyMovementEntity != null){
|
|
||||||
double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance;
|
|
||||||
double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance;
|
|
||||||
double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance;
|
|
||||||
//给予作用实体其向holderEntity的一个速度动量
|
|
||||||
applyMovementEntity.setDeltaMovement(
|
|
||||||
applyMovementEntity.getDeltaMovement().add(
|
|
||||||
Math.copySign(dX * dX * 0.4d, dX),
|
|
||||||
Math.copySign(dY * dY * 0.4d, dY),
|
|
||||||
Math.copySign(dZ * dZ * 0.4d, dZ)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
//刹车,避免偏激移动
|
|
||||||
Whimsy$Brake(applyMovementEntity, 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//降低坠落伤害
|
float leashLength = LeashCommand.MIN_VALUE;
|
||||||
|
if (restrainedEntity instanceof ILivingEntityExtension iEntity) {
|
||||||
|
// 获取绳长
|
||||||
|
float leashLengthFormValue = iEntity.getLeashLength();
|
||||||
|
leashLength = leashLengthFormValue > LeashCommand.MIN_VALUE ? leashLengthFormValue : LeashCommand.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 两者距离
|
||||||
|
float distance = holderEntity.distanceTo(restrainedEntity);
|
||||||
|
Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity;
|
||||||
|
|
||||||
|
// 仅当距离大于绳长时施加拉力
|
||||||
|
if (applyMovementEntity != null && distance > leashLength) {
|
||||||
|
// 计算朝向持有者的拉力方向
|
||||||
|
double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance;
|
||||||
|
double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance;
|
||||||
|
double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance;
|
||||||
|
|
||||||
|
// 拉力大小,距离越远拉力越强,但施加一个最大限制
|
||||||
|
double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力
|
||||||
|
applyMovementEntity.setDeltaMovement(
|
||||||
|
applyMovementEntity.getDeltaMovement().add(
|
||||||
|
dX * pullStrength,
|
||||||
|
dY * pullStrength,
|
||||||
|
dZ * pullStrength
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 控制速度不要过快,避免偏激移动
|
||||||
|
Whimsy$Brake(applyMovementEntity, entity -> {
|
||||||
|
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||||
|
entity.setDeltaMovement(
|
||||||
|
Math.min(Math.abs(deltaMovement.x), 1.0) * Math.signum(deltaMovement.x),
|
||||||
|
Math.min(Math.abs(deltaMovement.y), 1.0) * Math.signum(deltaMovement.y),
|
||||||
|
Math.min(Math.abs(deltaMovement.z), 1.0) * Math.signum(deltaMovement.z)
|
||||||
|
);
|
||||||
|
entity.hurtMarked = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 降低坠落伤害
|
||||||
restrainedEntity.checkSlowFallDistance();
|
restrainedEntity.checkSlowFallDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刹车(
|
* 刹车(
|
||||||
* @param pEntity 刹车的实体
|
* @param pEntity 刹车的实体
|
||||||
|
|
@ -98,9 +118,9 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl
|
||||||
@Unique
|
@Unique
|
||||||
private static void Whimsy$Brake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) {
|
private static void Whimsy$Brake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) {
|
||||||
Vec3 deltaMovement = pEntity.getDeltaMovement();
|
Vec3 deltaMovement = pEntity.getDeltaMovement();
|
||||||
double dX = deltaMovement.x > pMaxX ? 0 : deltaMovement.x;
|
double dX = Math.abs(deltaMovement.x) > pMaxX ? 0 : deltaMovement.x;
|
||||||
double dY = deltaMovement.y > pMaxY ? 0 : deltaMovement.y;
|
double dY = Math.abs(deltaMovement.y) > pMaxY ? 0 : deltaMovement.y;
|
||||||
double dZ = deltaMovement.z > pMaxZ ? 0 : deltaMovement.z;
|
double dZ = Math.abs(deltaMovement.z) > pMaxZ ? 0 : deltaMovement.z;
|
||||||
pEntity.setDeltaMovement(dX, dY,dZ);
|
pEntity.setDeltaMovement(dX, dY,dZ);
|
||||||
pEntity.hurtMarked = true;
|
pEntity.hurtMarked = true;
|
||||||
}
|
}
|
||||||
|
|
@ -115,9 +135,9 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl
|
||||||
if(pOpt == null) {
|
if(pOpt == null) {
|
||||||
consumer = entity -> {
|
consumer = entity -> {
|
||||||
Vec3 deltaMovement = entity.getDeltaMovement();
|
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||||
double dX = deltaMovement.x > 1 ? 0 : deltaMovement.x;
|
double dX = Math.abs(deltaMovement.x) > 1 ? 0 : deltaMovement.x;
|
||||||
double dY = deltaMovement.y > 1 ? 0 : deltaMovement.y;
|
double dY = Math.abs(deltaMovement.y) > 1 ? 0 : deltaMovement.y;
|
||||||
double dZ = deltaMovement.z > 1 ? 0 : deltaMovement.z;
|
double dZ = Math.abs(deltaMovement.z) > 1 ? 0 : deltaMovement.z;
|
||||||
entity.setDeltaMovement(dX, dY,dZ);
|
entity.setDeltaMovement(dX, dY,dZ);
|
||||||
entity.hurtMarked = true;
|
entity.hurtMarked = true;
|
||||||
};
|
};
|
||||||
|
|
@ -130,27 +150,34 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl
|
||||||
if(this.Pl$LeashData == null) return;//没有Data直接退出
|
if(this.Pl$LeashData == null) return;//没有Data直接退出
|
||||||
//info -> Holder整理
|
//info -> Holder整理
|
||||||
Pl$RestoreLeashFormSave();
|
Pl$RestoreLeashFormSave();
|
||||||
//默认值设为6.0f距离
|
//默认值设为
|
||||||
float leashLength = 6.0f;
|
float leashLength = LeashCommand.MIN_VALUE;
|
||||||
Entity entity = this.Pl$LeashData.leashHolder;
|
Entity entity = this.Pl$LeashData.leashHolder;
|
||||||
//保存数据
|
//保存数据
|
||||||
saveLeashData(Pl$LeashData);
|
saveLeashData(Pl$LeashData);
|
||||||
if(this instanceof ILivingEntityExtension iEntityExtension) {
|
if(this instanceof ILivingEntityExtension iEntityExtension) {
|
||||||
//获取设定值
|
//获取设定值
|
||||||
float leashLengthSelf = iEntityExtension.getLeashLength();
|
float leashLengthSelf = iEntityExtension.getLeashLength();
|
||||||
leashLength = leashLengthSelf > 6 ? leashLengthSelf : 6;
|
leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE;
|
||||||
}
|
}
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
if(!isAlive() || !entity.isAlive() || distanceTo(entity) > Math.max(leashLength * 2.0f, 10.0f)){
|
float breakDistanceTime = (entity instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||||
|
if(!isAlive() || !entity.isAlive() || distanceTo(entity) > Math.max(leashLength * breakDistanceTime, LeashCommand.MIN_VALUE * breakDistanceTime)){
|
||||||
//玩家死亡 或 持有者不存在 或 距离大于设定值的2倍(长度2倍若低于10格,则选10格) ,
|
//玩家死亡 或 持有者不存在 或 距离大于设定值的2倍(长度2倍若低于10格,则选10格) ,
|
||||||
// 则取消拴绳关系,并掉落拴绳
|
// 则取消拴绳关系,并掉落拴绳
|
||||||
dropLeash(true, true);
|
boolean shouldDrop = !(entity instanceof LeashRopeArrow);
|
||||||
} else if(distanceTo(entity) > leashLength * 1.3f) {
|
dropLeash(true, shouldDrop);
|
||||||
//大于1.3倍绳长则会让其跳跃(在<1.25格阻拦情况下,跳跃阻拦
|
} else if(distanceTo(entity) > leashLength * 0.65f * breakDistanceTime && entity.onGround()) {
|
||||||
jumpFromGround();
|
//大于1.3倍绳长则会让其跳跃(在<1.25格阻拦情况下,跳跃阻拦//TODO:待擴展
|
||||||
|
Entity applyMovementEntity = this.isPassenger() ? this.getVehicle() : this;
|
||||||
|
if(applyMovementEntity instanceof LivingEntity applyMovementLivingEntity) {
|
||||||
|
applyMovementLivingEntity.jumpFromGround();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity getLeashHolder() {
|
public Entity getLeashHolder() {
|
||||||
if (Pl$LeashData == null) return null;
|
if (Pl$LeashData == null) return null;
|
||||||
|
|
@ -176,7 +203,8 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl
|
||||||
if(Pl$LeashData.leashHolder != null) {//且LeashHolder不为null,则直接用它
|
if(Pl$LeashData.leashHolder != null) {//且LeashHolder不为null,则直接用它
|
||||||
setLeashedTo(Pl$LeashData.leashHolder, true);
|
setLeashedTo(Pl$LeashData.leashHolder, true);
|
||||||
return;
|
return;
|
||||||
} return;
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(this.Pl$LeashData.delayedLeashInfo.left().isPresent()) {
|
if(this.Pl$LeashData.delayedLeashInfo.left().isPresent()) {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
package com.r3944realms.leashedplayer.mixin.client;
|
package com.r3944realms.leashedplayer.mixin.client;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.player.AbstractClientPlayer;
|
import net.minecraft.client.player.AbstractClientPlayer;
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(EntityRenderer.class)
|
@Mixin(EntityRenderer.class)
|
||||||
public abstract class MixinEntityRenderer {
|
public abstract class MixinEntityRenderer {
|
||||||
|
|
@ -22,8 +26,9 @@ public abstract class MixinEntityRenderer {
|
||||||
private @NotNull Vec3 ret(Entity instance, float pPartialTick) {
|
private @NotNull Vec3 ret(Entity instance, float pPartialTick) {
|
||||||
if(instance instanceof AbstractClientPlayer) {
|
if(instance instanceof AbstractClientPlayer) {
|
||||||
//为了使拴绳在在第三视角下位于玩家脖子处
|
//为了使拴绳在在第三视角下位于玩家脖子处
|
||||||
return instance.getLeashOffset(pPartialTick).add(0, -0.2, -0.2);
|
return instance.getLeashOffset(pPartialTick).add(0, -0.2, -0.2);//TODO:待擴展Vec3
|
||||||
}
|
}
|
||||||
return instance.getLeashOffset(pPartialTick);//非实现这个接口则不变
|
return instance.getLeashOffset(pPartialTick);//非实现这个接口则不变
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.r3944realms.leashedplayer.mixin.client;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
|
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
|
||||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||||
|
|
@ -61,13 +63,13 @@ public abstract class MixinLevelRenderer {
|
||||||
for(Entity entity : this.level.entitiesForRendering()) {
|
for(Entity entity : this.level.entitiesForRendering()) {
|
||||||
//对于玩家实体拴绳渲染(从第一人称视角)
|
//对于玩家实体拴绳渲染(从第一人称视角)
|
||||||
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
|
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
|
||||||
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) return;
|
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(abstractClientPlayer);
|
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(abstractClientPlayer);
|
||||||
IPlayerRendererExtension playerRendererExtension = (IPlayerRendererExtension) playerRenderer;
|
IPlayerRendererExtension playerRendererExtension = (IPlayerRendererExtension) playerRenderer;
|
||||||
if (mc.options.getCameraType().isFirstPerson()) {
|
if (mc.options.getCameraType().isFirstPerson()) {
|
||||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||||
if(leashDataFromEntityData == null) return;
|
if(leashDataFromEntityData == null) continue;
|
||||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||||
if(delayedLeashInfo != null) {
|
if(delayedLeashInfo != null) {
|
||||||
float partialTickTime = pCamera.getPartialTickTime();
|
float partialTickTime = pCamera.getPartialTickTime();
|
||||||
|
|
@ -92,7 +94,7 @@ public abstract class MixinLevelRenderer {
|
||||||
if (playerByUUID != null) {
|
if (playerByUUID != null) {
|
||||||
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID);
|
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID);
|
||||||
} else {
|
} else {
|
||||||
float MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * 2f;
|
float MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
|
||||||
List<Entity> entities = level.getEntities(
|
List<Entity> entities = level.getEntities(
|
||||||
null,
|
null,
|
||||||
new AABB(
|
new AABB(
|
||||||
|
|
@ -112,9 +114,13 @@ public abstract class MixinLevelRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (holder != null) {
|
if (holder != null) {
|
||||||
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder);
|
if(holder instanceof LeashRopeArrow) {
|
||||||
|
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3
|
||||||
|
}
|
||||||
|
else playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package com.r3944realms.leashedplayer.mixin.client;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
|
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
|
import com.r3944realms.leashedplayer.modInterface.IPlayerRendererExtension;
|
||||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||||
|
|
@ -61,9 +63,10 @@ public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractC
|
||||||
if (playerByUUID != null) {
|
if (playerByUUID != null) {
|
||||||
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, playerByUUID);
|
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, playerByUUID);
|
||||||
} else {
|
} else {
|
||||||
float MaxLeashLength = ((ILivingEntityExtension) pEntity).getLeashLength() * 2f;
|
float breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||||
|
float MaxLeashLength = ((ILivingEntityExtension) pEntity).getLeashLength() * breakDistanceTime;
|
||||||
List<Entity> entities = level.getEntities(
|
List<Entity> entities = level.getEntities(
|
||||||
null,
|
null,
|
||||||
new AABB(
|
new AABB(
|
||||||
pEntity.getX() - MaxLeashLength,
|
pEntity.getX() - MaxLeashLength,
|
||||||
pEntity.getY() - MaxLeashLength,
|
pEntity.getY() - MaxLeashLength,
|
||||||
|
|
@ -81,7 +84,10 @@ public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (holder != null) {
|
if (holder != null) {
|
||||||
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder);
|
if(holder instanceof LeashRopeArrow) {
|
||||||
|
renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder, new Vec3(0,-0.09, 0));//TODO: 待擴展Vec3
|
||||||
|
}
|
||||||
|
else renderLeash(pEntity, pPartialTicks, pPoseStack, pBuffer, holder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,6 +162,7 @@ public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractC
|
||||||
* <h1> 总结 </h1>
|
* <h1> 总结 </h1>
|
||||||
* 这些数学运算主要用于计算实体在三维空间中的位置和方向,以确保在渲染链状结构(如拴住的绳索)时,链条能够跟随实体的移动和旋转并正确显示。在图形编程中,这些计算非常常见,尤其是在处理旋转、插值和光照效果时。
|
* 这些数学运算主要用于计算实体在三维空间中的位置和方向,以确保在渲染链状结构(如拴住的绳索)时,链条能够跟随实体的移动和旋转并正确显示。在图形编程中,这些计算非常常见,尤其是在处理旋转、插值和光照效果时。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||||
@Unique
|
@Unique
|
||||||
public <E extends net.minecraft.world.entity.Entity> void renderLeashForCamera(
|
public <E extends net.minecraft.world.entity.Entity> void renderLeashForCamera(
|
||||||
|
|
@ -163,13 +170,14 @@ public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractC
|
||||||
float partialTick,
|
float partialTick,
|
||||||
com.mojang.blaze3d.vertex.PoseStack poseStack,
|
com.mojang.blaze3d.vertex.PoseStack poseStack,
|
||||||
net.minecraft.client.renderer.MultiBufferSource bufferSource,
|
net.minecraft.client.renderer.MultiBufferSource bufferSource,
|
||||||
E leashHolder
|
E leashHolder,
|
||||||
|
Vec3 holderOffset
|
||||||
) {
|
) {
|
||||||
|
|
||||||
poseStack.pushPose();
|
poseStack.pushPose();
|
||||||
|
|
||||||
// 获得绳索持有者的位置
|
// 获得绳索持有者的位置
|
||||||
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick);
|
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick).add(holderOffset);
|
||||||
|
|
||||||
// 获取当前观察的实体
|
// 获取当前观察的实体
|
||||||
Entity cameraEntity = camera.getEntity();
|
Entity cameraEntity = camera.getEntity();
|
||||||
|
|
@ -224,5 +232,42 @@ public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractC
|
||||||
|
|
||||||
poseStack.popPose();
|
poseStack.popPose();
|
||||||
}
|
}
|
||||||
|
protected <E extends Entity> void renderLeash(AbstractClientPlayer pEntity, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource, E pLeashHolder, Vec3 holderOffset) {
|
||||||
|
pPoseStack.pushPose();
|
||||||
|
Vec3 vec3 = pLeashHolder.getRopeHoldPosition(pPartialTick).add(holderOffset);
|
||||||
|
double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||||
|
Vec3 vec31 = pEntity.getLeashOffset(pPartialTick);
|
||||||
|
double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
|
||||||
|
double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
|
||||||
|
double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
|
||||||
|
double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
|
||||||
|
double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
|
||||||
|
pPoseStack.translate(d1, vec31.y, d2);
|
||||||
|
float f = (float)(vec3.x - d3);
|
||||||
|
float f1 = (float)(vec3.y - d4);
|
||||||
|
float f2 = (float)(vec3.z - d5);
|
||||||
|
float f3 = 0.025F;
|
||||||
|
VertexConsumer vertexconsumer = pBufferSource.getBuffer(RenderType.leash());
|
||||||
|
Matrix4f matrix4f = pPoseStack.last().pose();
|
||||||
|
float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
|
||||||
|
float f5 = f2 * f4;
|
||||||
|
float f6 = f * f4;
|
||||||
|
BlockPos blockpos = BlockPos.containing(pEntity.getEyePosition(pPartialTick));
|
||||||
|
BlockPos blockpos1 = BlockPos.containing(pLeashHolder.getEyePosition(pPartialTick));
|
||||||
|
int i = this.getBlockLightLevel(pEntity, blockpos);
|
||||||
|
int j = 0;
|
||||||
|
int k = pEntity.level().getBrightness(LightLayer.SKY, blockpos);
|
||||||
|
int l = pEntity.level().getBrightness(LightLayer.SKY, blockpos1);
|
||||||
|
|
||||||
|
for (int i1 = 0; i1 <= 24; i1++) {
|
||||||
|
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j1 = 24; j1 >= 0; j1--) {
|
||||||
|
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.0F, f5, f6, j1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
pPoseStack.popPose();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,24 @@
|
||||||
package com.r3944realms.leashedplayer.modInterface;
|
package com.r3944realms.leashedplayer.modInterface;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public interface IPlayerRendererExtension {
|
public interface IPlayerRendererExtension {
|
||||||
<E extends net. minecraft. world. entity. Entity> void renderLeashForCamera(
|
default <E extends net. minecraft. world. entity. Entity> void renderLeashForCamera(
|
||||||
Camera pCamera,
|
Camera pCamera,
|
||||||
float pPartialTick,
|
float pPartialTick,
|
||||||
com.mojang.blaze3d.vertex.PoseStack pPoseStack,
|
com.mojang.blaze3d.vertex.PoseStack pPoseStack,
|
||||||
net.minecraft.client.renderer.MultiBufferSource pBufferSource,
|
net.minecraft.client.renderer.MultiBufferSource pBufferSource,
|
||||||
E pLeashHolder
|
E pLeashHolder
|
||||||
|
) {
|
||||||
|
renderLeashForCamera(pCamera, pPartialTick, pPoseStack, pBufferSource, pLeashHolder, Vec3.ZERO);
|
||||||
|
}
|
||||||
|
<E extends net. minecraft. world. entity. Entity> void renderLeashForCamera(
|
||||||
|
Camera pCamera,
|
||||||
|
float pPartialTick,
|
||||||
|
com.mojang.blaze3d.vertex.PoseStack pPoseStack,
|
||||||
|
net.minecraft.client.renderer.MultiBufferSource pBufferSource,
|
||||||
|
E pLeashHolder,
|
||||||
|
Vec3 holderOffset
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.r3944realms.leashedplayer.modInterface;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.Leashable;
|
import net.minecraft.world.entity.Leashable;
|
||||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||||
|
|
@ -56,6 +57,39 @@ public interface PlayerLeashable extends Leashable {
|
||||||
//这边覆写去掉了乘坐相关的逻辑,即乘坐状态下也可以正常被栓住,不影响其乘坐状态
|
//这边覆写去掉了乘坐相关的逻辑,即乘坐状态下也可以正常被栓住,不影响其乘坐状态
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@Nullable
|
||||||
|
static Entity getLeashDataEntity(@NotNull ServerPlayer serverPlayer , @NotNull ServerLevel serverLevel) {
|
||||||
|
LeashData leashDataFromEntityData = ((PlayerLeashable) serverPlayer).getLeashDataFromEntityData();
|
||||||
|
if (leashDataFromEntityData != null) {
|
||||||
|
return getLeashDataEntity(leashDataFromEntityData, serverLevel);
|
||||||
|
}
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Entity getLeashDataEntityOrThrown(@NotNull ServerPlayer serverPlayer ,@NotNull ServerLevel serverLevel) throws Exception {
|
||||||
|
Entity leashedEntity = getLeashDataEntity(serverPlayer, serverLevel);
|
||||||
|
if(leashedEntity == null) throw new Exception("invalid");
|
||||||
|
else return leashedEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
static Entity getLeashDataEntity(@NotNull Leashable.LeashData leashDataFromEntityData, @NotNull ServerLevel level) {
|
||||||
|
if(leashDataFromEntityData.delayedLeashInfo != null) {
|
||||||
|
Optional<UUID> UUID = leashDataFromEntityData.delayedLeashInfo.left();
|
||||||
|
Optional<BlockPos> BlockPos = leashDataFromEntityData.delayedLeashInfo.right();
|
||||||
|
if (UUID.isPresent()) {
|
||||||
|
return level.getEntity(UUID.get());
|
||||||
|
} else return BlockPos.map(pos -> LeashFenceKnotEntity.getOrCreateKnot(level, pos)).orElse(null);
|
||||||
|
}
|
||||||
|
else if(leashDataFromEntityData.leashHolder != null) {
|
||||||
|
return leashDataFromEntityData.leashHolder;
|
||||||
|
}
|
||||||
|
else if(leashDataFromEntityData.delayedLeashHolderId != 0) {
|
||||||
|
return level.getEntity(leashDataFromEntityData.delayedLeashHolderId);
|
||||||
|
}
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
|
||||||
static Entity getLeashDataEntityOrThrown(@NotNull Leashable.LeashData leashDataFromEntityData, @NotNull ServerLevel level) throws Exception {
|
static Entity getLeashDataEntityOrThrown(@NotNull Leashable.LeashData leashDataFromEntityData, @NotNull ServerLevel level) throws Exception {
|
||||||
if(leashDataFromEntityData.delayedLeashInfo != null) {
|
if(leashDataFromEntityData.delayedLeashInfo != null) {
|
||||||
Optional<UUID> UUID = leashDataFromEntityData.delayedLeashInfo.left();
|
Optional<UUID> UUID = leashDataFromEntityData.delayedLeashInfo.left();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
package com.r3944realms.leashedplayer.utils;
|
package com.r3944realms.leashedplayer.utils;
|
||||||
|
|
||||||
|
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||||
import com.r3944realms.leashedplayer.content.gamerules.Gamerules;
|
import com.r3944realms.leashedplayer.content.gamerules.Gamerules;
|
||||||
|
import net.neoforged.fml.loading.FMLPaths;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static com.r3944realms.leashedplayer.utils.Logger.logger;
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
public static String getGameruleName(Class<?> clazz) {
|
public static String getGameruleName(Class<?> clazz) {
|
||||||
|
|
@ -10,4 +16,25 @@ public class Util {
|
||||||
return Gamerules.GAMERULE_PREFIX + gamerulesName;
|
return Gamerules.GAMERULE_PREFIX + gamerulesName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void configFileCreate(String[] children) {//初始化配置文件目录
|
||||||
|
File configFile = new File(FMLPaths.CONFIGDIR.get().toFile(), LeashedPlayer.MOD_ID);
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
boolean mkdirSuccess = configFile.mkdirs();
|
||||||
|
if (!mkdirSuccess) {
|
||||||
|
logger.error("failed to create config directory for whimsicality");
|
||||||
|
throw new RuntimeException("failed to create config directory for " + LeashedPlayer.MOD_ID);
|
||||||
|
} else {
|
||||||
|
for (String child : children) {
|
||||||
|
File file = new File(configFile, child);
|
||||||
|
if (!file.exists()) {
|
||||||
|
boolean mkdirChildrenSuccess = file.mkdirs();
|
||||||
|
if (!mkdirChildrenSuccess) {
|
||||||
|
logger.error("failed to create " + child + " directory for +" + LeashedPlayer.MOD_ID);
|
||||||
|
throw new RuntimeException("failed to create " + child + " directory for" +LeashedPlayer.MOD_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,6 @@ public net.minecraft.world.level.GameRules$Type <init>(Ljava/util/function/Suppl
|
||||||
#因为'net.minecraft.world.level.GameRules.VisitorCaller' 在 'net.minecraft.world.level.GameRules' 中不为 public。无法从外部软件包访问
|
#因为'net.minecraft.world.level.GameRules.VisitorCaller' 在 'net.minecraft.world.level.GameRules' 中不为 public。无法从外部软件包访问
|
||||||
public net.minecraft.world.level.GameRules$VisitorCaller #Interface
|
public net.minecraft.world.level.GameRules$VisitorCaller #Interface
|
||||||
#private -> public
|
#private -> public
|
||||||
public net.minecraft.world.entity.Leashable$LeashData delayedLeashHolderId # delayedLeashHolderId
|
public net.minecraft.world.entity.Leashable$LeashData delayedLeashHolderId # delayedLeashHolderId
|
||||||
|
#private -> protect
|
||||||
|
protected net.minecraft.world.entity.projectile.AbstractArrow life # life
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 260 B |
Binary file not shown.
|
After Width: | Height: | Size: 268 B |
Loading…
Reference in New Issue
Block a user