版本更新到0.0.0.8

将玩家拴绳应力逻辑放入到客户端
This commit is contained in:
叁玖领域 2025-12-04 19:14:32 +08:00
parent df65a38134
commit 2c7a56de94
124 changed files with 11522 additions and 3556 deletions

View File

@ -162,10 +162,10 @@ configurations {
dependencies { dependencies {
annotationProcessor ('org.spongepowered:mixin:0.8.5:processor') annotationProcessor ('org.spongepowered:mixin:0.8.5:processor')
modRuntimeOnly("curse.maven:debug-utils-forge-783008:5337491") modRuntimeOnly("curse.maven:debug-utils-forge-783008:5337491")
modCompileOnly("blank:curtain-1.20.1:1.3.2") modImplementation("blank:curtain-1.20.1:1.3.2")
modRuntimeOnly("blank:curtain-1.20.1:1.3.2")
modImplementation("dev.kosmx.player-anim:player-animation-lib-forge:${player_anim_version}") modImplementation("dev.kosmx.player-anim:player-animation-lib-forge:${player_anim_version}")
modImplementation("curse.maven:bendy-lib-623373:4550371") modImplementation("curse.maven:bendy-lib-623373:4550371")
// modRuntimeOnly("curse.maven:luckperms-431733:4738950")
modImplementation("software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}") modImplementation("software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}")
implementation("com.eliotlash.mclib:mclib:20") implementation("com.eliotlash.mclib:mclib:20")
modCompileOnly("top.theillusivec4.curios:curios-forge:${curios_version}:api") modCompileOnly("top.theillusivec4.curios:curios-forge:${curios_version}:api")

122
dict.py
View File

@ -22,50 +22,128 @@ used_names = set()
def gen_dict(count: int, length: int, filename: str, charset: str): def gen_dict(count: int, length: int, filename: str, charset: str):
""" """
生成字典文件 生成字典文件
- 首字符必须是字母 - 所有字符都来自charset纯中文汉字包括易经符号
- 剩余字符可以是 charset 中任意字符
- 保证全局唯一 - 保证全局唯一
""" """
if length < 1: if length < 1:
raise ValueError("长度必须至少为 1") raise ValueError("长度必须至少为 1")
# 首字符必须是字母
first_chars = [c for c in charset if c.isalpha()]
if not first_chars:
raise ValueError("字符集必须包含至少一个字母作为首字符")
chars = list(charset) chars = list(charset)
max_combinations = len(first_chars) * (len(chars) ** (length - 1))
# 计算最大可能组合数
max_combinations = len(chars) ** length
if count > max_combinations: if count > max_combinations:
raise ValueError(f"要求数量 {count} 超过最大可能组合数 {max_combinations}") raise ValueError(f"要求数量 {count} 超过最大可能组合数 {max_combinations}")
generated = set() generated = set()
while len(generated) < count: while len(generated) < count:
s = random.choice(first_chars) # 随机生成纯中文字符串
s += ''.join(random.choice(chars) for _ in range(length - 1)) s = ''.join(random.choice(chars) for _ in range(length))
if s in used_names: if s in used_names:
continue # 跳过已使用的名字 continue # 跳过已使用的名字
generated.add(s) generated.add(s)
used_names.add(s) used_names.add(s)
with open(filename, "w") as f: with open(filename, "w", encoding='utf-8') as f:
for s in generated: for s in sorted(generated): # 排序便于查看
f.write(s + "\n") f.write(s + "\n")
print(f"生成完成,共 {len(generated)} 个写入 {filename}") print(f"生成完成,共 {len(generated)} 个写入 {filename}")
def get_chinese_chars():
"""
获取中文汉字字符集包括
1. 易经符号
2. 常用汉字
3. 扩展汉字
"""
# 1. 易经符号字符集 (64卦)
yijing_chars = "䷀䷁䷂䷃䷄䷅䷆䷇䷈䷉䷊䷋䷌䷍䷎䷏䷐䷑䷒䷓䷔䷕䷖䷗䷘䷙䷚䷛䷜䷝䷞䷟䷠䷡䷢䷣䷤䷥䷦䷧䷨䷩䷪䷫䷬䷭䷮䷯䷰䷱䷲䷳䷴䷵䷶䷷䷸䷹䷺䷻䷼䷽䷾䷿"
# 2. 常用汉字 (约3500个常用字)
common_chinese = (
"的一是不了在人有我他个大中来上们到说国和地也子时道出而要于就下得可你年生自会"
"那后能对着事其里所去行过家十用发天如然作方成者多日都三小军二无同么经法当起与"
"好看进学中第样道还法理文心现所政美手知明机高长部见定体此心合表化加动系表实新"
"量将两从问力等电开五心只实社资事制政济用所向好战无性前反合斗图把结第里正新开"
"论之物从当两些还天资事队批如应形想制心样干都向变关点育重其思与间内去因件日利"
"相由压员气业代全组数果期导平各基或月毛然问比展那它最及外没看治提五解系林者米"
"群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指"
"建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观"
"调七山程百报更见必真保热委手改管处己将修支识病象先老光专几什六型具示复安带每"
"东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫轴知研单色坚"
"据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书低术状"
"厂须离再目海交权且儿青才证越际八试规斯近注办布门铁需走议县兵虫固除般引齿千胜"
"细影济白格效置推空配刀叶率今选养德话查差半敌始片施响收华觉备名红续均药标记难"
"存测士身紧液派准斤角降维板许破述技消底床田势端感往神便圆村构照容非搞亚磨族火"
"段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺"
"检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普"
"谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝"
"局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输"
"滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒"
"圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸晚丝女焊攻株亲院冷彻"
"弹错散尼盾商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益"
"洲脱投送奴侧润盖挥距触星松获独官混纪座依未突架宽冬兴章湿偏纹执矿寨责阀熟吃稳"
"夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱"
"待尽俄缩沙退陈讨奋械胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰编"
"印蜂急扩伤飞域露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽"
"磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜"
"笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召"
"旱悟刺脑措贯藏令隙"
)
# 3. 扩展汉字 (Unicode CJK统一表意文字部分)
extended_chinese = []
# 添加一些Unicode范围的汉字为了避免文件过大我们只取一部分
ranges = [
(0x4E00, 0x4EFF), # 基本汉字
(0x4F00, 0x4FFF), # 基本汉字
(0x3400, 0x34FF), # 扩展A区
]
for start, end in ranges:
for code in range(start, end + 1):
try:
char = chr(code)
# 过滤掉一些非常用的字符
if random.random() < 0.3: # 只取30%的字符,避免过多
extended_chinese.append(char)
except:
pass
# 合并所有中文字符
all_chinese = common_chinese + ''.join(extended_chinese)
# 去重并返回
return ''.join(sorted(set(all_chinese)))
if __name__ == "__main__": if __name__ == "__main__":
# 字符集定义 # 获取纯中文汉字字符集
charset_class = "o0OQ" chinese_charset = get_chinese_chars()
charset_member = "i1lI" print(f"字符集大小:{len(chinese_charset)} 个汉字(包含易经符号)")
charset_package = "UvuV" print(f"前50个字符示例{chinese_charset[:50]}")
# 生成类名字典 # 生成类名字典(纯中文)
gen_dict(count=1000, length=10, filename="dict/class_dict.txt", charset=charset_class) gen_dict(
count=3000,
length=128, # 类名长度稍短
filename="dict/class_dict.txt",
charset=chinese_charset
)
# 生成字段/方法字典 # 生成字段/方法字典(纯中文)
gen_dict(count=1000, length=10, filename="dict/member_dict.txt", charset=charset_member) gen_dict(
count=5000,
length=128, # 字段/方法名更短
filename="dict/member_dict.txt",
charset=chinese_charset
)
# 生成包名字典 # 生成包名字典(纯中文)
gen_dict(count=1000, length=10, filename="dict/package_dict.txt", charset=charset_package) gen_dict(
count=2000,
length=128, # 包名可以更长
filename="dict/package_dict.txt",
charset=chinese_charset
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ neoForge.parchment.minecraftVersion=1.20.1
neoForge.parchment.mappingsVersion=2023.09.03 neoForge.parchment.mappingsVersion=2023.09.03
# enable ProGuard # enable ProGuard
enableProguard=false enableProguard=true
# Jei Version # Jei Version
jei_version=15.20.0.112 jei_version=15.20.0.112
#Other Mods Version #Other Mods Version
@ -59,7 +59,7 @@ mod_name=Super Lead Rope
# 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=GPLv3 mod_license=GPLv3
# The mod version. See https://semver.org/ # The mod version. See https://semver.org/
mod_version=0.0.0.7 mod_version=0.0.0.8
# 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

28
proguard.pro vendored
View File

@ -75,6 +75,34 @@
-dontshrink -dontshrink
-dontoptimize -dontoptimize
# -dontpreverify # -dontpreverify
#---------------------------------------
# 忽略缺少的库依赖警告
#---------------------------------------
-dontwarn net.luckperms.**
-dontwarn org.jetbrains.annotations.**
-dontwarn org.slf4j.**
-dontwarn javax.annotation.**
-dontwarn com.google.common.**
-dontwarn com.google.gson.**
# Minecraft 渲染相关
-dontwarn com.mojang.blaze3d.**
-dontwarn org.joml.**
-dontwarn com.mojang.math.**
-dontwarn com.mojang.brigadier.**
# 其他第三方库
-dontwarn mezz.jei.**
-dontwarn top.theillusivec4.curios.**
-dontwarn dev.dubhe.curtain.**
# JDK 内部类
-dontwarn jdk.internal.**
-dontwarn module-info
-dontwarn **
-dontnote **
#--------------------------------------- #---------------------------------------
# 输出映射文件 # 输出映射文件

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-10-24T23:36:36.156494 Languages: zh_tw // 1.20.1 2025-12-04T18:55:51.5054614 Languages: zh_tw
b63c143870a5792603f9967a8044196d59389588 assets/superleadrope/lang/zh_tw.json ff7556f7a8bd62a8c4cc776e45947835ffc19689 assets/superleadrope/lang/zh_tw.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-10-24T23:36:36.1535157 Languages: zh_cn // 1.20.1 2025-12-04T18:55:51.5004568 Languages: zh_cn
25e849cfb08702cdfeb426a3ef90b88d7f621d36 assets/superleadrope/lang/zh_cn.json f5128cf6058db0e79f91aece8de7f5bdd8e04193 assets/superleadrope/lang/zh_cn.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-10-24T23:36:36.1554931 Languages: lzh // 1.20.1 2025-12-04T18:55:51.5034621 Languages: lzh
3c9a7976df8a08b199eb5f9016aff4cbd7632c64 assets/superleadrope/lang/lzh.json 8dde976f77c0ca836ed66627ea2af29b20e5f7c5 assets/superleadrope/lang/lzh.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-10-24T23:36:36.1554931 Languages: en_us // 1.20.1 2025-12-04T18:55:51.5024633 Languages: en_us
cb4fd115c1067f38c218bdc1ddf3cc06b9f2d8d8 assets/superleadrope/lang/en_us.json b1f5523a28ab74acc8bd5b0ec167bf254e0b0dea assets/superleadrope/lang/en_us.json

View File

@ -27,8 +27,8 @@
"sound.superleadrope.subtitle.lead_break": "Lead Break", "sound.superleadrope.subtitle.lead_break": "Lead Break",
"sound.superleadrope.subtitle.lead_tied": "Lead Tied", "sound.superleadrope.subtitle.lead_tied": "Lead Tied",
"sound.superleadrope.subtitle.lead_untied": "Lead Untie", "sound.superleadrope.subtitle.lead_untied": "Lead Untie",
"superleadrope.command..block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.abbreviation": "...", "superleadrope.command.abbreviation": "...",
"superleadrope.command.block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.colon": ":", "superleadrope.command.colon": ":",
"superleadrope.command.end": ".", "superleadrope.command.end": ".",
"superleadrope.command.leash.message.add_block.fail": "Failed to attached %s leash from %s to %s.", "superleadrope.command.leash.message.add_block.fail": "Failed to attached %s leash from %s to %s.",
@ -85,8 +85,25 @@
"superleadrope.command.leash.message.transfer_leash.fail": "Failed to transfer leash from %s to %s.", "superleadrope.command.leash.message.transfer_leash.fail": "Failed to transfer leash from %s to %s.",
"superleadrope.command.leash.message.transfer_leash.suc": "Successfully transferred leash from %s to %s", "superleadrope.command.leash.message.transfer_leash.suc": "Successfully transferred leash from %s to %s",
"superleadrope.command.leash.message.transfer_leash.suc_fail": ", but failed to transfer leash from %s to %s.", "superleadrope.command.leash.message.transfer_leash.suc_fail": ", but failed to transfer leash from %s to %s.",
"superleadrope.command.leash_state.message.apply_offset": "Apply Offset",
"superleadrope.command.leash_state.message.default_offset": "Default Offset",
"superleadrope.command.leash_state.message.get_all_block_pos_states.suc": "Found %d block position states for %s:",
"superleadrope.command.leash_state.message.get_all_states.head": "All states for %s:",
"superleadrope.command.leash_state.message.get_all_uuid_states.suc": "Found %d UUID states for %s:",
"superleadrope.command.leash_state.message.get_apply_entity_offset.none": "%s has no apply entity offset",
"superleadrope.command.leash_state.message.get_apply_entity_offset.suc": "%s apply entity offset: %s",
"superleadrope.command.leash_state.message.get_default_apply_entity_offset.suc": "%s default apply entity offset: %s",
"superleadrope.command.leash_state.message.query.has_state.suc": "%s has state: %s",
"superleadrope.command.leash_state.message.reset_all_holder.suc": "Successfully reset all holders for %s",
"superleadrope.command.leash_state.message.reset_apply_entity_all.suc": "Successfully reset all apply entity offsets for %s",
"superleadrope.command.leash_state.message.reset_holder_for.suc": "Successfully reset holder %s for %s",
"superleadrope.command.leash_state.message.reset_holder_for_block_pos.suc": "Successfully reset block position %s for %s",
"superleadrope.command.leash_state.message.set_apply_entity.suc": "Successfully set apply entity offset %s for %s",
"superleadrope.command.leash_state.message.set_holder_for.suc": "Successfully set holder %s for %s",
"superleadrope.command.leash_state.message.set_holder_for_block_pos.suc": "Successfully set block position %s for %s",
"superleadrope.command.motion.message.adder.successful": "§bAdd Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r", "superleadrope.command.motion.message.adder.successful": "§bAdd Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r",
"superleadrope.command.motion.message.multiply.successful": "§bMultiply Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r", "superleadrope.command.motion.message.multiply.successful": "§bMultiply Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r",
"superleadrope.command.motion.message.setter.successful": "§bSet Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§bSet Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r",
"superleadrope.command.none": "<None>" "superleadrope.command.none": "<None>",
"superleadrope.command.state": "State"
} }

View File

@ -27,8 +27,8 @@
"sound.superleadrope.subtitle.lead_break": "索絕", "sound.superleadrope.subtitle.lead_break": "索絕",
"sound.superleadrope.subtitle.lead_tied": "繫索", "sound.superleadrope.subtitle.lead_tied": "繫索",
"sound.superleadrope.subtitle.lead_untied": "解索", "sound.superleadrope.subtitle.lead_untied": "解索",
"superleadrope.command..block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.abbreviation": "...", "superleadrope.command.abbreviation": "...",
"superleadrope.command.block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.colon": ":", "superleadrope.command.colon": ":",
"superleadrope.command.end": "。", "superleadrope.command.end": "。",
"superleadrope.command.leash.message.add_block.fail": "%s繩自%s繫於%s之舉未遂", "superleadrope.command.leash.message.add_block.fail": "%s繩自%s繫於%s之舉未遂",
@ -85,8 +85,25 @@
"superleadrope.command.leash.message.transfer_leash.fail": "拴繩自%s遷於%s之舉未遂", "superleadrope.command.leash.message.transfer_leash.fail": "拴繩自%s遷於%s之舉未遂",
"superleadrope.command.leash.message.transfer_leash.suc": "拴繩自%s移至%s其事已成", "superleadrope.command.leash.message.transfer_leash.suc": "拴繩自%s移至%s其事已成",
"superleadrope.command.leash.message.transfer_leash.suc_fail": ",然自%s至%s之遷移未竟", "superleadrope.command.leash.message.transfer_leash.suc_fail": ",然自%s至%s之遷移未竟",
"superleadrope.command.leash_state.message.apply_offset": "偏狀",
"superleadrope.command.leash_state.message.default_offset": "常偏狀",
"superleadrope.command.leash_state.message.get_all_block_pos_states.suc": "%s之位狀有%d:",
"superleadrope.command.leash_state.message.get_all_states.head": "%s 之諸狀:",
"superleadrope.command.leash_state.message.get_all_uuid_states.suc": "%s之UUID狀有%d:",
"superleadrope.command.leash_state.message.get_apply_entity_offset.none": "%s 無用體偏移",
"superleadrope.command.leash_state.message.get_apply_entity_offset.suc": "%s 用體偏移: %s",
"superleadrope.command.leash_state.message.get_default_apply_entity_offset.suc": "%s 常用體偏移: %s",
"superleadrope.command.leash_state.message.query.has_state.suc": "%s 有狀否: %s",
"superleadrope.command.leash_state.message.reset_all_holder.suc": "%s之諸持者狀態今已盡復",
"superleadrope.command.leash_state.message.reset_apply_entity_all.suc": "%s之諸用體偏移今已盡復",
"superleadrope.command.leash_state.message.reset_holder_for.suc": "%s之持者%s狀態今已復",
"superleadrope.command.leash_state.message.reset_holder_for_block_pos.suc": "%s之位%s狀態今已復",
"superleadrope.command.leash_state.message.set_apply_entity.suc": "為%s設用體偏移%s其事已成",
"superleadrope.command.leash_state.message.set_holder_for.suc": "為%s設持者%s其事已成",
"superleadrope.command.leash_state.message.set_holder_for_block_pos.suc": "為%s設位%s其事已成",
"superleadrope.command.motion.message.adder.successful": "§b增益既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.adder.successful": "§b增益既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.motion.message.multiply.successful": "§b倍乘既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.multiply.successful": "§b倍乘既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.motion.message.setter.successful": "§b定值既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§b定值既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.none": "無" "superleadrope.command.none": "無",
"superleadrope.command.state": "狀"
} }

View File

@ -27,8 +27,8 @@
"sound.superleadrope.subtitle.lead_break": "拴绳断裂", "sound.superleadrope.subtitle.lead_break": "拴绳断裂",
"sound.superleadrope.subtitle.lead_tied": "拴绳系上", "sound.superleadrope.subtitle.lead_tied": "拴绳系上",
"sound.superleadrope.subtitle.lead_untied": "拴绳解开", "sound.superleadrope.subtitle.lead_untied": "拴绳解开",
"superleadrope.command..block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.abbreviation": "...", "superleadrope.command.abbreviation": "...",
"superleadrope.command.block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.colon": ":", "superleadrope.command.colon": ":",
"superleadrope.command.end": "。", "superleadrope.command.end": "。",
"superleadrope.command.leash.message.add_block.fail": "未能将%s拴绳从%s连接到%s", "superleadrope.command.leash.message.add_block.fail": "未能将%s拴绳从%s连接到%s",
@ -85,8 +85,25 @@
"superleadrope.command.leash.message.transfer_leash.fail": "未能将拴绳从%s转移至%s", "superleadrope.command.leash.message.transfer_leash.fail": "未能将拴绳从%s转移至%s",
"superleadrope.command.leash.message.transfer_leash.suc": "成功将拴绳从%s转移至%s", "superleadrope.command.leash.message.transfer_leash.suc": "成功将拴绳从%s转移至%s",
"superleadrope.command.leash.message.transfer_leash.suc_fail": ",但未能将拴绳从%s转移至%s", "superleadrope.command.leash.message.transfer_leash.suc_fail": ",但未能将拴绳从%s转移至%s",
"superleadrope.command.leash_state.message.apply_offset": "应用偏移状态",
"superleadrope.command.leash_state.message.default_offset": "默认偏移状态",
"superleadrope.command.leash_state.message.get_all_block_pos_states.suc": "找到%s的%d个方块位置状态:",
"superleadrope.command.leash_state.message.get_all_states.head": "%s 的所有状态:",
"superleadrope.command.leash_state.message.get_all_uuid_states.suc": "找到%s的%d个UUID状态:",
"superleadrope.command.leash_state.message.get_apply_entity_offset.none": "%s 没有应用实体偏移",
"superleadrope.command.leash_state.message.get_apply_entity_offset.suc": "%s 应用实体偏移: %s",
"superleadrope.command.leash_state.message.get_default_apply_entity_offset.suc": "%s 默认应用实体偏移: %s",
"superleadrope.command.leash_state.message.query.has_state.suc": "%s 拥有状态: %s",
"superleadrope.command.leash_state.message.reset_all_holder.suc": "已成功重置%s的所有持有者状态",
"superleadrope.command.leash_state.message.reset_apply_entity_all.suc": "已成功重置%s的所有应用实体偏移",
"superleadrope.command.leash_state.message.reset_holder_for.suc": "已成功重置%s的持有者%s状态",
"superleadrope.command.leash_state.message.reset_holder_for_block_pos.suc": "已成功重置%s的方块位置%s状态",
"superleadrope.command.leash_state.message.set_apply_entity.suc": "已成功为%s设置应用实体偏移%s",
"superleadrope.command.leash_state.message.set_holder_for.suc": "已成功为%s设置持有者%s",
"superleadrope.command.leash_state.message.set_holder_for_block_pos.suc": "已成功为%s设置方块位置%s",
"superleadrope.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.motion.message.setter.successful": "§b设置成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§b设置成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.none": "无" "superleadrope.command.none": "无",
"superleadrope.command.state": "状态"
} }

View File

@ -27,8 +27,8 @@
"sound.superleadrope.subtitle.lead_break": "拴繩斷裂", "sound.superleadrope.subtitle.lead_break": "拴繩斷裂",
"sound.superleadrope.subtitle.lead_tied": "拴繩係上", "sound.superleadrope.subtitle.lead_tied": "拴繩係上",
"sound.superleadrope.subtitle.lead_untied": "拴繩解開", "sound.superleadrope.subtitle.lead_untied": "拴繩解開",
"superleadrope.command..block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.abbreviation": "...", "superleadrope.command.abbreviation": "...",
"superleadrope.command.block_pos": "§7[§fX: %d, Y: %d, Z: %d§7]",
"superleadrope.command.colon": ":", "superleadrope.command.colon": ":",
"superleadrope.command.end": "。", "superleadrope.command.end": "。",
"superleadrope.command.leash.message.add_block.fail": "未能將%s拴繩從%s連接到%s", "superleadrope.command.leash.message.add_block.fail": "未能將%s拴繩從%s連接到%s",
@ -85,8 +85,25 @@
"superleadrope.command.leash.message.transfer_leash.fail": "未能將拴繩從%s轉移至%s", "superleadrope.command.leash.message.transfer_leash.fail": "未能將拴繩從%s轉移至%s",
"superleadrope.command.leash.message.transfer_leash.suc": "成功將拴繩從%s轉移至%s", "superleadrope.command.leash.message.transfer_leash.suc": "成功將拴繩從%s轉移至%s",
"superleadrope.command.leash.message.transfer_leash.suc_fail": ",但未能將拴繩從%s轉移至%s", "superleadrope.command.leash.message.transfer_leash.suc_fail": ",但未能將拴繩從%s轉移至%s",
"superleadrope.command.leash_state.message.apply_offset": "應用偏移狀態",
"superleadrope.command.leash_state.message.default_offset": "預設偏移狀態",
"superleadrope.command.leash_state.message.get_all_block_pos_states.suc": "找到%s的%d個方塊位置狀態:",
"superleadrope.command.leash_state.message.get_all_states.head": "%s 的所有狀態:",
"superleadrope.command.leash_state.message.get_all_uuid_states.suc": "找到%s的%d個UUID狀態:",
"superleadrope.command.leash_state.message.get_apply_entity_offset.none": "%s 沒有應用實體偏移",
"superleadrope.command.leash_state.message.get_apply_entity_offset.suc": "%s 應用實體偏移: %s",
"superleadrope.command.leash_state.message.get_default_apply_entity_offset.suc": "%s 默認應用實體偏移: %s",
"superleadrope.command.leash_state.message.query.has_state.suc": "%s 擁有狀態: %s",
"superleadrope.command.leash_state.message.reset_all_holder.suc": "已成功重置%s的所有持有者狀態",
"superleadrope.command.leash_state.message.reset_apply_entity_all.suc": "已成功重置%s的所有應用實體偏移",
"superleadrope.command.leash_state.message.reset_holder_for.suc": "已成功重置%s的持有者%s狀態",
"superleadrope.command.leash_state.message.reset_holder_for_block_pos.suc": "已成功重置%s的方塊位置%s狀態",
"superleadrope.command.leash_state.message.set_apply_entity.suc": "已成功為%s設置應用實體偏移%s",
"superleadrope.command.leash_state.message.set_holder_for.suc": "已成功為%s設置持有者%s",
"superleadrope.command.leash_state.message.set_holder_for_block_pos.suc": "已成功為%s設置方塊位置%s",
"superleadrope.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.adder.successful": "§b添加成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.motion.message.setter.successful": "§b設置成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§b設置成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"superleadrope.command.none": "無" "superleadrope.command.none": "無",
"superleadrope.command.state": "狀態"
} }

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -63,6 +63,7 @@ import top.r3944realms.superleadrope.content.capability.CapabilityRemainder;
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl; import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
import top.r3944realms.superleadrope.content.capability.inter.IEternalPotato; import top.r3944realms.superleadrope.content.capability.inter.IEternalPotato;
import top.r3944realms.superleadrope.content.command.LeashDataCommand; import top.r3944realms.superleadrope.content.command.LeashDataCommand;
import top.r3944realms.superleadrope.content.command.LeashStateCommand;
import top.r3944realms.superleadrope.content.command.MotionCommand; import top.r3944realms.superleadrope.content.command.MotionCommand;
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity; import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities; import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities;
@ -428,6 +429,7 @@ public class CommonEventHandler {
if (tickCounter % 10 == 0) { if (tickCounter % 10 == 0) {
LeashSyncManager.Data.forEach(ILeashData::markForSync); LeashSyncManager.Data.forEach(ILeashData::markForSync);
LeashSyncManager.State.forEach(ILeashState::markForSync); LeashSyncManager.State.forEach(ILeashState::markForSync);
leashConfigManager.broadHashPacket();
} }
// 定期同步检查 // 定期同步检查
@ -479,6 +481,7 @@ public class CommonEventHandler {
CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher(); CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
MotionCommand.register(dispatcher); MotionCommand.register(dispatcher);
LeashDataCommand.register(dispatcher); LeashDataCommand.register(dispatcher);
LeashStateCommand.register(dispatcher);
} }
} }
@ -495,7 +498,7 @@ public class CommonEventHandler {
@SubscribeEvent @SubscribeEvent
public static void onFMLCommonInit(FMLCommonSetupEvent event) { public static void onFMLCommonInit(FMLCommonSetupEvent event) {
event.enqueueWork(Mod::checkAndSet); event.enqueueWork(Mod::checkAndSet);
event.enqueueWork(SLPGameruleRegistry::register);//规则注册 event.enqueueWork(SLPGameruleRegistry::register);
} }
/** /**
@ -526,9 +529,10 @@ public class CommonEventHandler {
* @param event the event * @param event the event
*/ */
@SubscribeEvent @SubscribeEvent
public void onConfigReloading(ModConfigEvent.Reloading event) { public static void onConfigReloading(final ModConfigEvent.Reloading event) {
if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) { if (event.getConfig().getModId().equals(SuperLeadRope.MOD_ID)) {
SuperLeadRope.logger.debug("Config reloading detected..."); SuperLeadRope.logger.debug("Config reloading detected...");
Optional.ofNullable(leashConfigManager).ifPresent(LeashConfigManager::reloadAll);
} }
} }
private static void checkAndSet() { private static void checkAndSet() {
@ -547,7 +551,7 @@ public class CommonEventHandler {
* @param event the event * @param event the event
*/ */
@SubscribeEvent @SubscribeEvent
public void onConfigLoaded(ModConfigEvent.Loading event) { public static void onConfigLoaded(ModConfigEvent.Loading event) {
if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) { if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) {
checkAndSet(); checkAndSet();
LeashConfigManager.loading(leashConfigManager); LeashConfigManager.loading(leashConfigManager);
@ -560,20 +564,20 @@ public class CommonEventHandler {
* @param event the event * @param event the event
*/ */
@SubscribeEvent @SubscribeEvent
public void onConfigReloaded(ModConfigEvent.Reloading event) { public static void onConfigReloaded(ModConfigEvent.Reloading event) {
if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) { if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) {
checkAndSet(); checkAndSet();
LeashConfigManager.reloading(leashConfigManager); LeashConfigManager.reloading(leashConfigManager);
} }
} }
// 忘记订阅事件是静态方法了xwx
/** /**
* On config unloaded. * On config unloaded.
* *
* @param event the event * @param event the event
*/ */
@SubscribeEvent @SubscribeEvent
public void onConfigUnloaded(ModConfigEvent.Unloading event) { public static void onConfigUnloaded(ModConfigEvent.Unloading event) {
if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) { if (event.getConfig().getSpec() == LeashCommonConfig.SPEC) {
LeashConfigManager.unloading(leashConfigManager); LeashConfigManager.unloading(leashConfigManager);
} }

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -477,7 +477,7 @@ public interface ILeashData extends INBTSerializable<CompoundTag> {
* Apply physics * Apply physics
* ---------------------- */ * ---------------------- */
void applyLeashForces(); void applyLeashForces();
void applyLeashForcesClientPlayer();
/** /**
* Transfer leash boolean. * Transfer leash boolean.
* *

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -16,6 +16,8 @@
package top.r3944realms.superleadrope.client; package top.r3944realms.superleadrope.client;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
@ -24,18 +26,22 @@ import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.client.event.RegisterShadersEvent; import net.minecraftforge.client.event.RegisterShadersEvent;
import net.minecraftforge.client.event.RenderLevelStageEvent; import net.minecraftforge.client.event.RenderLevelStageEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import top.r3944realms.superleadrope.SuperLeadRope; import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.client.model.SuperLeashKnotModel; import top.r3944realms.superleadrope.client.model.SuperLeashKnotModel;
import top.r3944realms.superleadrope.client.model.geom.SLPModelLayers; import top.r3944realms.superleadrope.client.model.geom.SLPModelLayers;
import top.r3944realms.superleadrope.client.renderer.LeashRenderHandler; import top.r3944realms.superleadrope.client.renderer.LeashRenderHandler;
import top.r3944realms.superleadrope.client.renderer.SLPShaderRegistry; import top.r3944realms.superleadrope.client.renderer.SLPShaderRegistry;
import top.r3944realms.superleadrope.client.renderer.entity.SuperLeashKnotRenderer; import top.r3944realms.superleadrope.client.renderer.entity.SuperLeashKnotRenderer;
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
import top.r3944realms.superleadrope.core.potato.EternalPotatoFacade; import top.r3944realms.superleadrope.core.potato.EternalPotatoFacade;
import top.r3944realms.superleadrope.core.register.SLPEntityTypes; import top.r3944realms.superleadrope.core.register.SLPEntityTypes;
import top.r3944realms.superleadrope.core.register.SLPItems; import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.core.util.PotatoMode; import top.r3944realms.superleadrope.core.util.PotatoMode;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.io.IOException; import java.io.IOException;
@ -63,6 +69,14 @@ public class ClientEventHandler {
} }
LeashRenderHandler.onRenderLevelStage(event.getPoseStack(), event.getPartialTick()); LeashRenderHandler.onRenderLevelStage(event.getPoseStack(), event.getPartialTick());
} }
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.player instanceof LocalPlayer player && player.equals(Minecraft.getInstance().player)) {
LeashDataInnerAPI
.getLeashData(player)
.ifPresent(ILeashData::applyLeashForcesClientPlayer);
}
}
/** /**
* On player logged out. * On player logged out.
@ -133,5 +147,6 @@ public class ClientEventHandler {
public static void onRegisterShaders(RegisterShadersEvent event) throws IOException { public static void onRegisterShaders(RegisterShadersEvent event) throws IOException {
SLPShaderRegistry.registerShaders(event); SLPShaderRegistry.registerShaders(event);
} }
} }
} }

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -16,6 +16,7 @@
package top.r3944realms.superleadrope.config; package top.r3944realms.superleadrope.config;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.*;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -24,6 +25,8 @@ import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import top.r3944realms.superleadrope.SuperLeadRope; import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.network.toClient.CommonConfigHashInformPacket;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -62,6 +65,9 @@ public class LeashConfigManager {
* The constant ELASTIC_DISTANCE_CHECK. * The constant ELASTIC_DISTANCE_CHECK.
*/ */
public static final Predicate<Double> ELASTIC_DISTANCE_CHECK = distance -> distance == null || (distance >= ELASTIC_DISTANCE_MIN_VALUE && distance <= ELASTIC_DISTANCE_MAX_VALUE); public static final Predicate<Double> ELASTIC_DISTANCE_CHECK = distance -> distance == null || (distance >= ELASTIC_DISTANCE_MIN_VALUE && distance <= ELASTIC_DISTANCE_MAX_VALUE);
// ========= 缓存 ========
public volatile static CompoundTag cacheTag = null;
public volatile static int cacheHash = -1;
// ========== 偏移映射 ========== // ========== 偏移映射 ==========
private final Map<String, double[]> entityHolderMap = new ConcurrentHashMap<>(); private final Map<String, double[]> entityHolderMap = new ConcurrentHashMap<>();
private final Map<String, double[]> tagHolderMap = new ConcurrentHashMap<>(); private final Map<String, double[]> tagHolderMap = new ConcurrentHashMap<>();
@ -385,25 +391,33 @@ public class LeashConfigManager {
*/ */
// ================== 管理 ================== // ================== 管理 ==================
public void reloadAll() { public void reloadAll() {
parseOffsetConfig(); try {
parseOffsetConfig();
teleportWhitelistCache = new ArrayList<>(LeashCommonConfig.COMMON.teleportWhitelist.get()); teleportWhitelistCache = new ArrayList<>(LeashCommonConfig.COMMON.teleportWhitelist.get());
commandPrefixCache = LeashCommonConfig.COMMON.SLPModCommandPrefix.get(); commandPrefixCache = LeashCommonConfig.COMMON.SLPModCommandPrefix.get();
commandPrefixEnabledCache = LeashCommonConfig.COMMON.enableSLPModCommandPrefix.get(); commandPrefixEnabledCache = LeashCommonConfig.COMMON.enableSLPModCommandPrefix.get();
maxLeashLength = LeashCommonConfig.COMMON.maxLeashLength.get(); maxLeashLength = LeashCommonConfig.COMMON.maxLeashLength.get();
elasticDistanceScale = LeashCommonConfig.COMMON.elasticDistanceScale.get(); elasticDistanceScale = LeashCommonConfig.COMMON.elasticDistanceScale.get();
extremeSnapFactor = LeashCommonConfig.COMMON.extremeSnapFactor.get(); extremeSnapFactor = LeashCommonConfig.COMMON.extremeSnapFactor.get();
springDampening = LeashCommonConfig.COMMON.springDampening.get(); springDampening = LeashCommonConfig.COMMON.springDampening.get();
axisElasticity = new ArrayList<>(LeashCommonConfig.COMMON.axisSpecificElasticity.get()); axisElasticity = new ArrayList<>(LeashCommonConfig.COMMON.axisSpecificElasticity.get());
maxLeashesPerEntity = LeashCommonConfig.COMMON.maxLeashesPerEntity.get(); maxLeashesPerEntity = LeashCommonConfig.COMMON.maxLeashesPerEntity.get();
enableTrueDamping = LeashCommonConfig.COMMON.enableTrueDamping.get(); enableTrueDamping = LeashCommonConfig.COMMON.enableTrueDamping.get();
maxForce = LeashCommonConfig.COMMON.maxForce.get(); maxForce = LeashCommonConfig.COMMON.maxForce.get();
playerSpringFactor = LeashCommonConfig.COMMON.playerSpringFactor.get(); playerSpringFactor = LeashCommonConfig.COMMON.playerSpringFactor.get();
mobSpringFactor = LeashCommonConfig.COMMON.mobSpringFactor.get(); mobSpringFactor = LeashCommonConfig.COMMON.mobSpringFactor.get();
cacheHash = calculateConfigHash();
cacheTag = serializeToNBT();
SuperLeadRope.logger.debug("Configs reloaded: {}", getStats());
} catch (Exception e) {
SuperLeadRope.logger.error("Failed to reload configs", e);
cacheHash = -1;
cacheTag = null;
}
SuperLeadRope.logger.debug("Configs reloaded: {}", getStats());
} }
/** /**
@ -441,7 +455,334 @@ public class LeashConfigManager {
public static void unloading(LeashConfigManager manager) { public static void unloading(LeashConfigManager manager) {
if(manager != null) manager.clear(); if(manager != null) manager.clear();
} }
/**
* 将配置管理器状态序列化为NBT
*/
public synchronized CompoundTag serializeToNBT() {
if (cacheHash == calculateConfigHash() && cacheTag != null) return cacheTag;
CompoundTag tag = new CompoundTag();
// 序列化偏移映射
CompoundTag offsets = new CompoundTag();
serializeOffsetMap(offsets, "holder_entity", entityHolderMap);
serializeOffsetMap(offsets, "holder_tag", tagHolderMap);
serializeOffsetMap(offsets, "holder_mod", modHolderMap);
serializeOffsetMap(offsets, "leash_entity", entityLeashMap);
serializeOffsetMap(offsets, "leash_tag", tagLeashMap);
serializeOffsetMap(offsets, "leash_mod", modLeashMap);
tag.put("offsets", offsets);
// 序列化缓存配置
ListTag whitelistTag = new ListTag();
for (String entry : teleportWhitelistCache) {
whitelistTag.add(StringTag.valueOf(entry));
}
tag.put("teleport_whitelist", whitelistTag);
tag.putString("command_prefix", commandPrefixCache);
tag.putBoolean("command_prefix_enabled", commandPrefixEnabledCache);
// 序列化物理参数
tag.putBoolean("enable_true_damping", enableTrueDamping);
tag.putDouble("max_force", maxForce);
tag.putDouble("player_spring_factor", playerSpringFactor);
tag.putDouble("mob_spring_factor", mobSpringFactor);
tag.putDouble("max_leash_length", maxLeashLength);
tag.putDouble("elastic_distance_scale", elasticDistanceScale);
tag.putDouble("extreme_snap_factor", extremeSnapFactor);
tag.putDouble("spring_dampening", springDampening);
ListTag elasticityTag = new ListTag();
for (double value : axisElasticity) {
elasticityTag.add(DoubleTag.valueOf(value));
}
tag.put("axis_elasticity", elasticityTag);
tag.putInt("max_leashes_per_entity", maxLeashesPerEntity);
cacheHash = calculateConfigHash();
cacheTag = tag;
return tag;
}
private void update() {
// ========== 更新偏移配置 ==========
// 将holder偏移写回配置
List<String> holderOffsetConfigs = convertMapsToOffsetList(entityHolderMap, tagHolderMap, modHolderMap);
LeashCommonConfig.COMMON.defaultHolderLocationOffset.set(holderOffsetConfigs);
// 将leash偏移写回配置
List<String> leashOffsetConfigs = convertMapsToOffsetList(entityLeashMap, tagLeashMap, modLeashMap);
LeashCommonConfig.COMMON.defaultApplyEntityLocationOffset.set(leashOffsetConfigs);
// ========== 更新白名单 ==========
LeashCommonConfig.COMMON.teleportWhitelist.set(new ArrayList<>(teleportWhitelistCache));
// ========== 更新命令配置 ==========
LeashCommonConfig.COMMON.SLPModCommandPrefix.set(commandPrefixCache);
LeashCommonConfig.COMMON.enableSLPModCommandPrefix.set(commandPrefixEnabledCache);
// ========== 更新物理参数 ==========
LeashCommonConfig.COMMON.maxLeashLength.set(maxLeashLength);
LeashCommonConfig.COMMON.elasticDistanceScale.set(elasticDistanceScale);
LeashCommonConfig.COMMON.extremeSnapFactor.set(extremeSnapFactor);
LeashCommonConfig.COMMON.springDampening.set(springDampening);
LeashCommonConfig.COMMON.axisSpecificElasticity.set(new ArrayList<>(axisElasticity));
LeashCommonConfig.COMMON.maxLeashesPerEntity.set(maxLeashesPerEntity);
// ========== 更新阻尼参数 ==========
LeashCommonConfig.COMMON.enableTrueDamping.set(enableTrueDamping);
LeashCommonConfig.COMMON.maxForce.set(maxForce);
LeashCommonConfig.COMMON.playerSpringFactor.set(playerSpringFactor);
LeashCommonConfig.COMMON.mobSpringFactor.set(mobSpringFactor);
}
/**
* 将偏移映射转换为配置列表格式
*/
private List<String> convertMapsToOffsetList(
Map<String, double[]> entityMap,
Map<String, double[]> tagMap,
Map<String, double[]> modMap) {
Map<double[], Set<String>> offsetToTargets = new HashMap<>();
// 收集entity映射
for (Map.Entry<String, double[]> entry : entityMap.entrySet()) {
offsetToTargets.computeIfAbsent(entry.getValue(), k -> new LinkedHashSet<>())
.add(entry.getKey());
}
// 收集tag映射
for (Map.Entry<String, double[]> entry : tagMap.entrySet()) {
offsetToTargets.computeIfAbsent(entry.getValue(), k -> new LinkedHashSet<>())
.add("#" + entry.getKey());
}
// 收集mod映射
for (Map.Entry<String, double[]> entry : modMap.entrySet()) {
if (entry.getKey().equals("*")) {
offsetToTargets.computeIfAbsent(entry.getValue(), k -> new LinkedHashSet<>())
.add("*");
} else {
offsetToTargets.computeIfAbsent(entry.getValue(), k -> new LinkedHashSet<>())
.add("#" + entry.getKey());
}
}
// 转换为配置字符串列表
List<String> configs = new ArrayList<>();
for (Map.Entry<double[], Set<String>> entry : offsetToTargets.entrySet()) {
double[] offset = entry.getKey();
Set<String> targets = entry.getValue();
if (targets.isEmpty() || offset.length != 3) continue;
String config = String.format(Locale.ROOT,
"%.2f,%.2f,%.2f=%s",
offset[0], offset[1], offset[2],
String.join(",", targets)
);
configs.add(config);
}
return configs;
}
/**
* 从NBT反序列化配置管理器状态
*/
public void deserializeFromNBT(CompoundTag tag) {
if (tag == null || tag.isEmpty()) return;
// 反序列化偏移映射
if (tag.contains("offsets", Tag.TAG_COMPOUND)) {
CompoundTag offsets = tag.getCompound("offsets");
deserializeOffsetMap(offsets, "holder_entity", entityHolderMap);
deserializeOffsetMap(offsets, "holder_tag", tagHolderMap);
deserializeOffsetMap(offsets, "holder_mod", modHolderMap);
deserializeOffsetMap(offsets, "leash_entity", entityLeashMap);
deserializeOffsetMap(offsets, "leash_tag", tagLeashMap);
deserializeOffsetMap(offsets, "leash_mod", modLeashMap);
}
// 反序列化缓存配置
if (tag.contains("teleport_whitelist", Tag.TAG_LIST)) {
ListTag whitelistTag = tag.getList("teleport_whitelist", Tag.TAG_STRING);
List<String> whitelist = new ArrayList<>();
for (int i = 0; i < whitelistTag.size(); i++) {
whitelist.add(whitelistTag.getString(i));
}
teleportWhitelistCache = Collections.unmodifiableList(whitelist);
}
if (tag.contains("command_prefix", Tag.TAG_STRING)) {
commandPrefixCache = tag.getString("command_prefix");
}
if (tag.contains("command_prefix_enabled", Tag.TAG_BYTE)) {
commandPrefixEnabledCache = tag.getBoolean("command_prefix_enabled");
}
// 反序列化物理参数
if (tag.contains("enable_true_damping", Tag.TAG_BYTE)) {
enableTrueDamping = tag.getBoolean("enable_true_damping");
}
if (tag.contains("max_force", Tag.TAG_DOUBLE)) {
maxForce = tag.getDouble("max_force");
}
if (tag.contains("player_spring_factor", Tag.TAG_DOUBLE)) {
playerSpringFactor = tag.getDouble("player_spring_factor");
}
if (tag.contains("mob_spring_factor", Tag.TAG_DOUBLE)) {
mobSpringFactor = tag.getDouble("mob_spring_factor");
}
if (tag.contains("max_leash_length", Tag.TAG_DOUBLE)) {
maxLeashLength = tag.getDouble("max_leash_length");
}
if (tag.contains("elastic_distance_scale", Tag.TAG_DOUBLE)) {
elasticDistanceScale = tag.getDouble("elastic_distance_scale");
}
if (tag.contains("extreme_snap_factor", Tag.TAG_DOUBLE)) {
extremeSnapFactor = tag.getDouble("extreme_snap_factor");
}
if (tag.contains("spring_dampening", Tag.TAG_DOUBLE)) {
springDampening = tag.getDouble("spring_dampening");
}
if (tag.contains("axis_elasticity", Tag.TAG_LIST)) {
ListTag elasticityTag = tag.getList("axis_elasticity", Tag.TAG_DOUBLE);
List<Double> elasticity = new ArrayList<>();
for (int i = 0; i < elasticityTag.size(); i++) {
elasticity.add(elasticityTag.getDouble(i));
}
axisElasticity = Collections.unmodifiableList(elasticity);
}
if (tag.contains("max_leashes_per_entity", Tag.TAG_INT)) {
maxLeashesPerEntity = tag.getInt("max_leashes_per_entity");
}
update();
}
/**
* 计算配置哈希值用于快速比较配置是否变化
*/
public int calculateConfigHash() {
// 使用FNV-1a哈希算法
int hash = 0x811c9dc5; // FNV偏移基础值
// 哈希偏移映射
hash = fnv1aHashMap(hash, entityHolderMap);
hash = fnv1aHashMap(hash, tagHolderMap);
hash = fnv1aHashMap(hash, modHolderMap);
hash = fnv1aHashMap(hash, entityLeashMap);
hash = fnv1aHashMap(hash, tagLeashMap);
hash = fnv1aHashMap(hash, modLeashMap);
// 哈希白名单
for (String entry : teleportWhitelistCache) {
hash = fnv1aHashString(hash, entry);
}
// 哈希字符串参数
hash = fnv1aHashString(hash, commandPrefixCache);
hash ^= commandPrefixEnabledCache ? 0x55555555 : 0xAAAAAAAA;
// 哈希双精度参数转换为长整型位表示进行哈希
hash = fnv1aHashLong(hash, Double.doubleToLongBits(enableTrueDamping ? 1.0 : 0.0));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(maxForce));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(playerSpringFactor));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(mobSpringFactor));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(maxLeashLength));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(elasticDistanceScale));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(extremeSnapFactor));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(springDampening));
// 哈希轴弹性列表
for (double value : axisElasticity) {
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
}
// 哈希整数参数
hash = fnv1aHashInt(hash, maxLeashesPerEntity);
return hash;
}
// ================== 辅助方法 ==================
private void serializeOffsetMap(CompoundTag parent, String key, @NotNull Map<String, double[]> map) {
CompoundTag mapTag = new CompoundTag();
for (Map.Entry<String, double[]> entry : map.entrySet()) {
String entryKey = entry.getKey().replace(':', '_'); // 避免NBT键中的冒号问题
ListTag offsetList = new ListTag();
for (double value : entry.getValue()) {
offsetList.add(DoubleTag.valueOf(value));
}
mapTag.put(entryKey, offsetList);
}
parent.put(key, mapTag);
}
private void deserializeOffsetMap(@NotNull CompoundTag parent, String key, Map<String, double[]> map) {
if (parent.contains(key, Tag.TAG_COMPOUND)) {
map.clear();
CompoundTag mapTag = parent.getCompound(key);
for (String entryKey : mapTag.getAllKeys()) {
if (mapTag.contains(entryKey, Tag.TAG_LIST)) {
ListTag offsetList = mapTag.getList(entryKey, Tag.TAG_DOUBLE);
double[] offset = new double[offsetList.size()];
for (int i = 0; i < offsetList.size(); i++) {
offset[i] = offsetList.getDouble(i);
}
map.put(entryKey.replace('_', ':'), offset); // 恢复原始键名
}
}
}
}
// FNV-1a哈希辅助方法
private int fnv1aHashInt(int hash, int value) {
hash ^= (value & 0xFF);
hash *= 0x01000193;
hash ^= ((value >> 8) & 0xFF);
hash *= 0x01000193;
hash ^= ((value >> 16) & 0xFF);
hash *= 0x01000193;
hash ^= ((value >> 24) & 0xFF);
hash *= 0x01000193;
return hash;
}
private int fnv1aHashLong(int hash, long value) {
hash = fnv1aHashInt(hash, (int)(value & 0xFFFFFFFFL));
return fnv1aHashInt(hash, (int)(value >> 32));
}
private int fnv1aHashString(int hash, @NotNull String str) {
for (int i = 0; i < str.length(); i++) {
hash ^= str.charAt(i);
hash *= 0x01000193;
}
return hash;
}
private int fnv1aHashMap(int hash, @NotNull Map<String, double[]> map) {
for (Map.Entry<String, double[]> entry : map.entrySet()) {
hash = fnv1aHashString(hash, entry.getKey());
for (double value : entry.getValue()) {
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
}
}
return hash;
}
public void broadHashPacket() {
if (cacheHash != -1){
NetworkHandler.sendToAllPlayer(new CommonConfigHashInformPacket(cacheHash));
}
}
/** /**
* Gets stats. * Gets stats.
* *

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -15,6 +15,7 @@
package top.r3944realms.superleadrope.content.capability.impi; package top.r3944realms.superleadrope.content.capability.impi;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
@ -50,6 +51,7 @@ import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents; import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.network.NetworkHandler; import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.network.toClient.LeashDataSyncPacket; import top.r3944realms.superleadrope.network.toClient.LeashDataSyncPacket;
import top.r3944realms.superleadrope.network.toClient.UpdatePlayerMovementPacket;
import top.r3944realms.superleadrope.util.capability.LeashStateInnerAPI; import top.r3944realms.superleadrope.util.capability.LeashStateInnerAPI;
import top.r3944realms.superleadrope.util.riding.RindingLeash; import top.r3944realms.superleadrope.util.riding.RindingLeash;
@ -772,6 +774,39 @@ public class LeashDataImpl implements ILeashData {
newMaxKeepLeashTicks newMaxKeepLeashTicks
)); ));
} }
@Override
public void applyLeashForcesClientPlayer() {
if (entity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player)) return;
Vec3 combinedForce = Vec3.ZERO;
Vec3 combinedDirection = Vec3.ZERO;
Map<Integer, LeashInfo> result = leashHolders.entrySet().stream()
.collect(Collectors.toMap(
entry -> entry.getValue().holderIdOpt().orElseThrow(),
Map.Entry::getValue,
(existing, replacement) -> existing
));
// 计算所有拴绳的合力和平均方向
for (Map.Entry<Integer, LeashInfo> entry : result.entrySet()) {
Vec3 force = calculateLeashForceForID(entry);
if (force != null) {
combinedForce = combinedForce.add(force);
combinedDirection = combinedDirection.add(force.normalize());
}
}
for (Map.Entry<BlockPos, LeashInfo> entry : leashKnots.entrySet()) {
Vec3 force = calculateLeashForceForBlockPos(entry);
if (force != null) {
combinedForce = combinedForce.add(force);
combinedDirection = combinedDirection.add(force.normalize());
}
}
boolean hasForce = !combinedForce.equals(Vec3.ZERO);
Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce);
if(targetEntity instanceof LocalPlayer && hasForce){
entity.addDeltaMovement(combinedForce);
}
}
/** /**
* 计算拴绳拉力防抖动逻辑 * 计算拴绳拉力防抖动逻辑
@ -811,14 +846,13 @@ public class LeashDataImpl implements ILeashData {
if (MinecraftForge.EVENT_BUS.post(hasFocus)) return; if (MinecraftForge.EVENT_BUS.post(hasFocus)) return;
combinedForce = hasFocus.getCombinedForce(); combinedForce = hasFocus.getCombinedForce();
// 玩家与普通实体统一力应用 // 玩家与普通实体统一力应用
if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player)) { if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player) ) {
RindingLeash.applyForceToPlayer( // 是真实玩家则交给客户端自行处理拴绳逻辑
player, // DO NOTHING
combinedForce, if(targetEntity != entity){
CommonEventHandler.leashConfigManager.getPlayerSpringFactor(), NetworkHandler.sendToPlayer(new UpdatePlayerMovementPacket(UpdatePlayerMovementPacket.Operation.ADD, combinedForce), player);
0.0, // 阻力取消 }
CommonEventHandler.leashConfigManager.getMaxForce() return;
);
} else { } else {
applyForceToNonPlayerEntity(targetEntity, combinedForce, validLeashes, combinedDirection); applyForceToNonPlayerEntity(targetEntity, combinedForce, validLeashes, combinedDirection);
} }
@ -936,7 +970,14 @@ public class LeashDataImpl implements ILeashData {
return baseSpeed * (1.0 + forceFactor); return baseSpeed * (1.0 + forceFactor);
} }
private @Nullable Vec3 calculateLeashForceForID(Map.@NotNull Entry<Integer, LeashInfo> entry) {
Integer id = entry.getKey();
Entity idHolder = entity.level().getEntity(id);
if (idHolder != null) {
return calculateLeashForce(idHolder, entry);
}
return null;
}
/** /**
* 为UUID拴绳计算力 * 为UUID拴绳计算力

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -51,7 +51,7 @@ public class Command {
/** /**
* The constant BLOCK_POS. * The constant BLOCK_POS.
*/ */
public static final String BLOCK_POS = BASE_ + ".block_pos"; public static final String BLOCK_POS = BASE_ + "block_pos";
/** /**
* The constant SUC. * The constant SUC.
*/ */
@ -75,6 +75,20 @@ public class Command {
public static final int MAX_SHOW_NUMBER = 4; public static final int MAX_SHOW_NUMBER = 4;
public static final String END = BASE_ + "end"; public static final String END = BASE_ + "end";
public static final String NONE = BASE_ + "none"; public static final String NONE = BASE_ + "none";
public static final String STATE = BASE_ + "state";
/**
* The constant SLP_LEASH_MESSAGE_.
*/
public static final String SLP_LEASH_MESSAGE_ = Command.BASE_ + "leash.message.";
/**
* The constant ALL_KNOTS.
*/
public static final String ALL_KNOTS = SLP_LEASH_MESSAGE_ + "all_knots";
/**
* The constant ALL_HOLDERS.
*/
public static final String ALL_HOLDERS = SLP_LEASH_MESSAGE_ + "all_holders";
/** /**
* Gets slp name. * Gets slp name.
* *

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -54,19 +54,6 @@ import static top.r3944realms.superleadrope.content.command.Command.*;
* The type Leash data command. * The type Leash data command.
*/ */
public class LeashDataCommand { public class LeashDataCommand {
/**
* The constant SLP_LEASH_MESSAGE_.
*/
public static final String SLP_LEASH_MESSAGE_ = Command.BASE_ + "leash.message.";
/**
* The constant ALL_KNOTS.
*/
public static final String ALL_KNOTS = SLP_LEASH_MESSAGE_ + "all_knots";
/**
* The constant ALL_HOLDERS.
*/
public static final String ALL_HOLDERS = SLP_LEASH_MESSAGE_ + "all_holders";
/** /**
* Register. * Register.
@ -1473,7 +1460,7 @@ public class LeashDataCommand {
* The constant DEFAULT. * The constant DEFAULT.
*/ */
public static final String DEFAULT = SLP_LEASH_MESSAGE_ + "default"; public static final String DEFAULT = SLP_LEASH_MESSAGE_ + "default";
private static Component showLeashInfo(@Nullable Double maxDistance, @Nullable Double elasticDistanceScale, int keepTicks,@Nullable String reserved) { private static @NotNull Component showLeashInfo(@Nullable Double maxDistance, @Nullable Double elasticDistanceScale, int keepTicks, @Nullable String reserved) {
MutableComponent item = Component.literal("[*]"); MutableComponent item = Component.literal("[*]");
MutableComponent hover = Component.empty(); MutableComponent hover = Component.empty();
hover.append(Component.translatable(MAX).withStyle(ChatFormatting.DARK_AQUA)) hover.append(Component.translatable(MAX).withStyle(ChatFormatting.DARK_AQUA))

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -16,31 +16,40 @@
package top.r3944realms.superleadrope.content.command; package top.r3944realms.superleadrope.content.command;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument; import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.commands.arguments.coordinates.Vec3Argument; import net.minecraft.commands.arguments.coordinates.Vec3Argument;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
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.Nullable;
import top.r3944realms.superleadrope.util.capability.LeashStateInnerAPI; import top.r3944realms.superleadrope.util.capability.LeashStateInnerAPI;
import static top.r3944realms.superleadrope.content.command.Command.*; import java.util.ArrayList;
import java.util.List;
import static top.r3944realms.superleadrope.content.command.Command.*;
import static top.r3944realms.superleadrope.content.command.LeashDataCommand.*;
/**
* The type Leash state command.
*/
//TODO: 未来扩展启用
public class LeashStateCommand { public class LeashStateCommand {
/** /**
* The constant SLP_LEASH_STATE_MESSAGE_. * The constant SLP_LEASH_STATE_MESSAGE_.
*/ */
public static final String SLP_LEASH_STATE_MESSAGE_ = Command.BASE_ + "leash_state.message."; public static final String SLP_LEASH_STATE_MESSAGE_ = Command.BASE_ + "leash_state.message.";
public static final String DEFAULT_OFFSET = SLP_LEASH_STATE_MESSAGE_ + "default_offset";
public static final String APPLY_OFFSET = SLP_LEASH_STATE_MESSAGE_ + "apply_offset";
// ==================== 重置操作消息键 ==================== // ==================== 重置操作消息键 ====================
public static final String RESET_ALL_HOLDER_ = SLP_LEASH_STATE_MESSAGE_ + "reset_all_holder."; public static final String RESET_ALL_HOLDER_ = SLP_LEASH_STATE_MESSAGE_ + "reset_all_holder.";
public static final String RESET_ALL_HOLDER_SUC = RESET_ALL_HOLDER_ + SUC; public static final String RESET_ALL_HOLDER_SUC = RESET_ALL_HOLDER_ + SUC;
@ -57,57 +66,12 @@ public class LeashStateCommand {
// ==================== 设置操作消息键 ==================== // ==================== 设置操作消息键 ====================
public static final String SET_HOLDER_FOR_ = SLP_LEASH_STATE_MESSAGE_ + "set_holder_for."; public static final String SET_HOLDER_FOR_ = SLP_LEASH_STATE_MESSAGE_ + "set_holder_for.";
public static final String SET_HOLDER_FOR_SUC = SET_HOLDER_FOR_ + SUC; public static final String SET_HOLDER_FOR_SUC = SET_HOLDER_FOR_ + SUC;
public static final String SET_HOLDER_FOR_SUC_FAIL = SET_HOLDER_FOR_ + SUC_FAIL;
public static final String SET_HOLDER_FOR_FAIL = SET_HOLDER_FOR_ + FAIL;
public static final String SET_HOLDER_FOR_BLOCK_POS_ = SLP_LEASH_STATE_MESSAGE_ + "set_holder_for_block_pos."; public static final String SET_HOLDER_FOR_BLOCK_POS_ = SLP_LEASH_STATE_MESSAGE_ + "set_holder_for_block_pos.";
public static final String SET_HOLDER_FOR_BLOCK_POS_SUC = SET_HOLDER_FOR_BLOCK_POS_ + SUC; public static final String SET_HOLDER_FOR_BLOCK_POS_SUC = SET_HOLDER_FOR_BLOCK_POS_ + SUC;
public static final String SET_HOLDER_FOR_BLOCK_POS_SUC_FAIL = SET_HOLDER_FOR_BLOCK_POS_ + SUC_FAIL;
public static final String SET_HOLDER_FOR_BLOCK_POS_FAIL = SET_HOLDER_FOR_BLOCK_POS_ + FAIL;
public static final String SET_APPLY_ENTITY_ = SLP_LEASH_STATE_MESSAGE_ + "set_apply_entity."; public static final String SET_APPLY_ENTITY_ = SLP_LEASH_STATE_MESSAGE_ + "set_apply_entity.";
public static final String SET_APPLY_ENTITY_SUC = SET_APPLY_ENTITY_ + SUC; public static final String SET_APPLY_ENTITY_SUC = SET_APPLY_ENTITY_ + SUC;
public static final String SET_APPLY_ENTITY_SUC_FAIL = SET_APPLY_ENTITY_ + SUC_FAIL;
public static final String SET_APPLY_ENTITY_FAIL = SET_APPLY_ENTITY_ + FAIL;
// ==================== 添加操作消息键 ====================
public static final String ADD_HOLDER_TO_ = SLP_LEASH_STATE_MESSAGE_ + "add_holder_to.";
public static final String ADD_HOLDER_TO_SUC = ADD_HOLDER_TO_ + SUC;
public static final String ADD_HOLDER_TO_SUC_FAIL = ADD_HOLDER_TO_ + SUC_FAIL;
public static final String ADD_HOLDER_TO_FAIL = ADD_HOLDER_TO_ + FAIL;
public static final String ADD_HOLDER_TO_BLOCK_POS_ = SLP_LEASH_STATE_MESSAGE_ + "add_holder_to_block_pos.";
public static final String ADD_HOLDER_TO_BLOCK_POS_SUC = ADD_HOLDER_TO_BLOCK_POS_ + SUC;
public static final String ADD_HOLDER_TO_BLOCK_POS_SUC_FAIL = ADD_HOLDER_TO_BLOCK_POS_ + SUC_FAIL;
public static final String ADD_HOLDER_TO_BLOCK_POS_FAIL = ADD_HOLDER_TO_BLOCK_POS_ + FAIL;
public static final String ADD_APPLY_ENTITY_ = SLP_LEASH_STATE_MESSAGE_ + "add_apply_entity.";
public static final String ADD_APPLY_ENTITY_SUC = ADD_APPLY_ENTITY_ + SUC;
public static final String ADD_APPLY_ENTITY_SUC_FAIL = ADD_APPLY_ENTITY_ + SUC_FAIL;
public static final String ADD_APPLY_ENTITY_FAIL = ADD_APPLY_ENTITY_ + FAIL;
// ==================== 移除操作消息键 ====================
public static final String REMOVE_HOLDER_FOR_ = SLP_LEASH_STATE_MESSAGE_ + "remove_holder_for.";
public static final String REMOVE_HOLDER_FOR_SUC = REMOVE_HOLDER_FOR_ + SUC;
public static final String REMOVE_HOLDER_FOR_SUC_FAIL = REMOVE_HOLDER_FOR_ + SUC_FAIL;
public static final String REMOVE_HOLDER_FOR_FAIL = REMOVE_HOLDER_FOR_ + FAIL;
public static final String REMOVE_HOLDER_FOR_BLOCK_POS_ = SLP_LEASH_STATE_MESSAGE_ + "remove_holder_for_block_pos.";
public static final String REMOVE_HOLDER_FOR_BLOCK_POS_SUC = REMOVE_HOLDER_FOR_BLOCK_POS_ + SUC;
public static final String REMOVE_HOLDER_FOR_BLOCK_POS_SUC_FAIL = REMOVE_HOLDER_FOR_BLOCK_POS_ + SUC_FAIL;
public static final String REMOVE_HOLDER_FOR_BLOCK_POS_FAIL = REMOVE_HOLDER_FOR_BLOCK_POS_ + FAIL;
public static final String REMOVE_HOLDER_ALL_ = SLP_LEASH_STATE_MESSAGE_ + "remove_holder_all.";
public static final String REMOVE_HOLDER_ALL_SUC = REMOVE_HOLDER_ALL_ + SUC;
public static final String REMOVE_ALL_HOLDER_UUIDS_ = SLP_LEASH_STATE_MESSAGE_ + "remove_all_holder_uuids.";
public static final String REMOVE_ALL_HOLDER_UUIDS_SUC = REMOVE_ALL_HOLDER_UUIDS_ + SUC;
public static final String REMOVE_ALL_HOLDER_BLOCK_POSES_ = SLP_LEASH_STATE_MESSAGE_ + "remove_all_holder_block_poses.";
public static final String REMOVE_ALL_HOLDER_BLOCK_POSES_SUC = REMOVE_ALL_HOLDER_BLOCK_POSES_ + SUC;
public static final String REMOVE_APPLY_ENTITY_ = SLP_LEASH_STATE_MESSAGE_ + "remove_apply_entity.";
public static final String REMOVE_APPLY_ENTITY_SUC = REMOVE_APPLY_ENTITY_ + SUC;
// ==================== 查询操作消息键 ==================== // ==================== 查询操作消息键 ====================
public static final String QUERY_HAS_STATE_ = SLP_LEASH_STATE_MESSAGE_ + "query.has_state."; public static final String QUERY_HAS_STATE_ = SLP_LEASH_STATE_MESSAGE_ + "query.has_state.";
@ -126,216 +90,156 @@ public class LeashStateCommand {
public static final String GET_DEFAULT_APPLY_ENTITY_OFFSET_ = SLP_LEASH_STATE_MESSAGE_ + "get_default_apply_entity_offset."; public static final String GET_DEFAULT_APPLY_ENTITY_OFFSET_ = SLP_LEASH_STATE_MESSAGE_ + "get_default_apply_entity_offset.";
public static final String GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC = GET_DEFAULT_APPLY_ENTITY_OFFSET_ + SUC; public static final String GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC = GET_DEFAULT_APPLY_ENTITY_OFFSET_ + SUC;
/** /**
* Register. * Register.
* *
* @param dispatcher the dispatcher * @param dispatcher the dispatcher
*/ */
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) { public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("leashstate") @Nullable List<LiteralArgumentBuilder<CommandSourceStack>> nodeList = SHOULD_USE_PREFIX ? null : new ArrayList<>();
.requires(source -> source.hasPermission(2)) // 需要权限等级2 LiteralArgumentBuilder<CommandSourceStack> literalArgumentBuilder = Commands.literal(PREFIX);
LiteralArgumentBuilder<CommandSourceStack> $$leashStateRoot = getLiterArgumentBuilderOfCSS("leashstate", !SHOULD_USE_PREFIX, nodeList);
// ==================== 重置操作 ==================== $$leashStateRoot.then(
.then(Commands.literal("resetAllHolder") // ==================== 重置操作 ====================
.then(Commands.argument("entity", EntityArgument.entity()) Commands.literal("resetAllHolder")
.executes(context -> resetAllHolder(context, EntityArgument.getEntity(context, "entity"))) .then(Commands.argument("entity", EntityArgument.entity())
) .executes(context -> resetAllHolder(context, EntityArgument.getEntity(context, "entity")))
) )
.then(Commands.literal("resetHolderFor") )
.then(Commands.argument("entity", EntityArgument.entity()) .then(Commands.literal("resetHolderFor")
.then(Commands.argument("holder", EntityArgument.entity()) .then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> resetHolderFor(context, .then(Commands.argument("holder", EntityArgument.entity())
EntityArgument.getEntity(context, "entity"), .executes(context -> resetHolderFor(context,
EntityArgument.getEntity(context, "holder"))) EntityArgument.getEntity(context, "entity"),
) EntityArgument.getEntity(context, "holder")))
) )
) )
.then(Commands.literal("resetHolderForBlockPos") )
.then(Commands.argument("entity", EntityArgument.entity()) .then(Commands.literal("resetHolderForBlockPos")
.then(Commands.argument("pos", BlockPosArgument.blockPos()) .then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> resetHolderForBlockPos(context, .then(Commands.argument("pos", BlockPosArgument.blockPos())
EntityArgument.getEntity(context, "entity"), .executes(context -> resetHolderForBlockPos(context,
BlockPosArgument.getLoadedBlockPos(context, "pos"))) EntityArgument.getEntity(context, "entity"),
) BlockPosArgument.getLoadedBlockPos(context, "pos")))
) )
) )
.then(Commands.literal("resetApplyEntityAll") )
.then(Commands.argument("entity", EntityArgument.entity()) .then(Commands.literal("resetApplyEntityAll")
.executes(context -> resetApplyEntityAll(context, EntityArgument.getEntity(context, "entity"))) .then(Commands.argument("entity", EntityArgument.entity())
) .executes(context -> resetApplyEntityAll(context, EntityArgument.getEntity(context, "entity")))
) )
)
// ==================== 设置操作 ==================== // ==================== 设置操作 ====================
.then(Commands.literal("setHolderFor") .then(Commands.literal("setHolderFor")
.then(Commands.argument("entity", EntityArgument.entity()) .then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("holder", EntityArgument.entity()) .then(Commands.argument("holder", EntityArgument.entity())
.executes(context -> setHolderFor(context, .executes(context -> setHolderFor(context,
EntityArgument.getEntity(context, "entity"), EntityArgument.getEntity(context, "entity"),
EntityArgument.getEntity(context, "holder"))) EntityArgument.getEntity(context, "holder")))
.then(Commands.argument("offset", Vec3Argument.vec3()) .then(Commands.argument("offset", Vec3Argument.vec3())
.executes(context -> setHolderForWithOffset(context, .executes(context -> setHolderForWithOffset(context,
EntityArgument.getEntity(context, "entity"), EntityArgument.getEntity(context, "entity"),
EntityArgument.getEntity(context, "holder"), EntityArgument.getEntity(context, "holder"),
Vec3Argument.getVec3(context, "offset"))) Vec3Argument.getVec3(context, "offset")))
) )
) )
) )
) )
.then(Commands.literal("setHolderForBlockPos") .then(Commands.literal("setHolderForBlockPos")
.then(Commands.argument("entity", EntityArgument.entity()) .then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("pos", BlockPosArgument.blockPos()) .then(Commands.argument("pos", BlockPosArgument.blockPos())
.executes(context -> setHolderForBlockPos(context, .executes(context -> setHolderForBlockPos(context,
EntityArgument.getEntity(context, "entity"), EntityArgument.getEntity(context, "entity"),
BlockPosArgument.getLoadedBlockPos(context, "pos"))) BlockPosArgument.getLoadedBlockPos(context, "pos")))
.then(Commands.argument("offset", Vec3Argument.vec3()) .then(Commands.argument("offset", Vec3Argument.vec3())
.executes(context -> setHolderForBlockPosWithOffset(context, .executes(context -> setHolderForBlockPosWithOffset(context,
EntityArgument.getEntity(context, "entity"), EntityArgument.getEntity(context, "entity"),
BlockPosArgument.getLoadedBlockPos(context, "pos"), BlockPosArgument.getLoadedBlockPos(context, "pos"),
Vec3Argument.getVec3(context, "offset"))) Vec3Argument.getVec3(context, "offset")))
) )
) )
) )
) )
.then(Commands.literal("setApplyEntity") .then(Commands.literal("setApplyEntity")
.then(Commands.argument("entity", EntityArgument.entity()) .then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("offset", Vec3Argument.vec3()) .then(Commands.argument("offset", Vec3Argument.vec3())
.executes(context -> setApplyEntity(context, .executes(context -> setApplyEntity(context,
EntityArgument.getEntity(context, "entity"), EntityArgument.getEntity(context, "entity"),
Vec3Argument.getVec3(context, "offset"))) Vec3Argument.getVec3(context, "offset")))
) )
) )
) )
// ==================== 查询操作 ====================
.then(Commands.literal("query")
.then(Commands.literal("hasState")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> queryHasState(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getAllUUIDStates")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getAllUUIDStates(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getAllBlockPosStates")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getAllBlockPosStates(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getApplyEntityOffset")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getApplyEntityOffset(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getDefaultApplyEntityOffset")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getDefaultApplyEntityOffset(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getAllStates")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getAllStates(context, EntityArgument.getEntity(context, "entity")))
)
)
// ==================== 添加操作 ==================== ).requires(source -> source.hasPermission(2));
.then(Commands.literal("addHolderTo") if(SHOULD_USE_PREFIX){
.then(Commands.argument("entity", EntityArgument.entity()) literalArgumentBuilder.then($$leashStateRoot);
.then(Commands.argument("holder", EntityArgument.entity()) dispatcher.register(literalArgumentBuilder);
.then(Commands.argument("offset", Vec3Argument.vec3()) } else {
.executes(context -> addHolderTo(context, if (nodeList != null) {
EntityArgument.getEntity(context, "entity"), nodeList.forEach(dispatcher::register);
EntityArgument.getEntity(context, "holder"), }
Vec3Argument.getVec3(context, "offset"))) }
)
)
)
)
.then(Commands.literal("addHolderToBlockPos")
.then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("pos", BlockPosArgument.blockPos())
.then(Commands.argument("offset", Vec3Argument.vec3())
.executes(context -> addHolderToBlockPos(context,
EntityArgument.getEntity(context, "entity"),
BlockPosArgument.getLoadedBlockPos(context, "pos"),
Vec3Argument.getVec3(context, "offset")))
)
)
)
)
.then(Commands.literal("addApplyEntity")
.then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("offset", Vec3Argument.vec3())
.executes(context -> addApplyEntity(context,
EntityArgument.getEntity(context, "entity"),
Vec3Argument.getVec3(context, "offset")))
)
)
)
// ==================== 移除操作 ====================
.then(Commands.literal("removeHolderFor")
.then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("holder", EntityArgument.entity())
.executes(context -> removeHolderFor(context,
EntityArgument.getEntity(context, "entity"),
EntityArgument.getEntity(context, "holder")))
)
)
)
.then(Commands.literal("removeHolderForBlockPos")
.then(Commands.argument("entity", EntityArgument.entity())
.then(Commands.argument("pos", BlockPosArgument.blockPos())
.executes(context -> removeHolderForBlockPos(context,
EntityArgument.getEntity(context, "entity"),
BlockPosArgument.getLoadedBlockPos(context, "pos")))
)
)
)
.then(Commands.literal("removeHolderAll")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> removeHolderAll(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("removeAllHolderUUIDs")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> removeAllHolderUUIDs(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("removeAllHolderBlockPoses")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> removeAllHolderBlockPoses(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("removeApplyEntity")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> removeApplyEntity(context, EntityArgument.getEntity(context, "entity")))
)
)
// ==================== 查询操作 ====================
.then(Commands.literal("query")
.then(Commands.literal("hasState")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> queryHasState(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getAllUUIDStates")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getAllUUIDStates(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getAllBlockPosStates")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getAllBlockPosStates(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getApplyEntityOffset")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getApplyEntityOffset(context, EntityArgument.getEntity(context, "entity")))
)
)
.then(Commands.literal("getDefaultApplyEntityOffset")
.then(Commands.argument("entity", EntityArgument.entity())
.executes(context -> getDefaultApplyEntityOffset(context, EntityArgument.getEntity(context, "entity")))
)
)
)
);
} }
// ==================== 重置操作实现 ==================== // ==================== 重置操作实现 ====================
private static int resetAllHolder(CommandContext<CommandSourceStack> context, Entity entity) { private static int resetAllHolder(@NotNull CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.resetAllHolder(entity); LeashStateInnerAPI.Offset.resetAllHolder(entity);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(RESET_ALL_HOLDER_SUC, getSLPName(entity)), false); Component.translatable(RESET_ALL_HOLDER_SUC, getSLPName(entity)), false);
return 1; return 1;
} }
private static int resetHolderFor(CommandContext<CommandSourceStack> context, Entity entity, Entity holder) { private static int resetHolderFor(@NotNull CommandContext<CommandSourceStack> context, Entity entity, Entity holder) {
LeashStateInnerAPI.Offset.resetHolderFor(entity, holder); LeashStateInnerAPI.Offset.resetHolderFor(entity, holder);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(RESET_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder)), false); Component.translatable(RESET_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder)), false);
return 1; return 1;
} }
private static int resetHolderForBlockPos(CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos) { private static int resetHolderForBlockPos(@NotNull CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos) {
LeashStateInnerAPI.Offset.resetHolderFor(entity, pos); LeashStateInnerAPI.Offset.resetHolderFor(entity, pos);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(RESET_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos)), false); Component.translatable(RESET_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos)), false);
return 1; return 1;
} }
private static int resetApplyEntityAll(CommandContext<CommandSourceStack> context, Entity entity) { private static int resetApplyEntityAll(@NotNull CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.resetApplyEntityAll(entity); LeashStateInnerAPI.Offset.resetApplyEntityAll(entity);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(RESET_APPLY_ENTITY_ALL_SUC, getSLPName(entity)), false); Component.translatable(RESET_APPLY_ENTITY_ALL_SUC, getSLPName(entity)), false);
@ -344,153 +248,253 @@ public class LeashStateCommand {
// ==================== 设置操作实现 ==================== // ==================== 设置操作实现 ====================
private static int setHolderFor(CommandContext<CommandSourceStack> context, Entity entity, Entity holder) { private static int setHolderFor(@NotNull CommandContext<CommandSourceStack> context, Entity entity, Entity holder) {
LeashStateInnerAPI.Offset.setHolderFor(entity, holder); LeashStateInnerAPI.Offset.setHolderFor(entity, holder);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(SET_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder)), false); Component.translatable(SET_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder)), false);
return 1; return 1;
} }
private static int setHolderForWithOffset(CommandContext<CommandSourceStack> context, Entity entity, Entity holder, Vec3 offset) { private static int setHolderForWithOffset(@NotNull CommandContext<CommandSourceStack> context, Entity entity, Entity holder, Vec3 offset) {
LeashStateInnerAPI.Offset.setHolderFor(entity, holder, offset); LeashStateInnerAPI.Offset.setHolderFor(entity, holder, offset);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(SET_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder), offset), false); Component.translatable(SET_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder), offset), false);
return 1; return 1;
} }
private static int setHolderForBlockPos(CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos) { private static int setHolderForBlockPos(@NotNull CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos) {
LeashStateInnerAPI.Offset.setHolderFor(entity, pos); LeashStateInnerAPI.Offset.setHolderFor(entity, pos);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(SET_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos)), false); Component.translatable(SET_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos)), false);
return 1; return 1;
} }
private static int setHolderForBlockPosWithOffset(CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos, Vec3 offset) { private static int setHolderForBlockPosWithOffset(@NotNull CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos, Vec3 offset) {
LeashStateInnerAPI.Offset.setHolderFor(entity, pos, offset); LeashStateInnerAPI.Offset.setHolderFor(entity, pos, offset);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(SET_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos), offset), false); Component.translatable(SET_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos), offset), false);
return 1; return 1;
} }
private static int setApplyEntity(CommandContext<CommandSourceStack> context, Entity entity, Vec3 offset) { private static int setApplyEntity(@NotNull CommandContext<CommandSourceStack> context, Entity entity, Vec3 offset) {
LeashStateInnerAPI.Offset.setApplyEntity(entity, offset); LeashStateInnerAPI.Offset.setApplyEntity(entity, offset);
context.getSource().sendSuccess(() -> context.getSource().sendSuccess(() ->
Component.translatable(SET_APPLY_ENTITY_SUC, getSLPName(entity), offset), false); Component.translatable(SET_APPLY_ENTITY_SUC, getSLPName(entity), offset), false);
return 1; return 1;
} }
// ==================== 添加操作实现 ====================
private static int addHolderTo(CommandContext<CommandSourceStack> context, Entity entity, Entity holder, Vec3 offset) {
LeashStateInnerAPI.Offset.addHolderTo(entity, holder, offset);
context.getSource().sendSuccess(() ->
Component.translatable(ADD_HOLDER_TO_SUC, getSLPName(entity), getSLPName(holder), offset), false);
return 1;
}
private static int addHolderToBlockPos(CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos, Vec3 offset) {
LeashStateInnerAPI.Offset.addHolderTo(entity, pos, offset);
context.getSource().sendSuccess(() ->
Component.translatable(ADD_HOLDER_TO_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos), offset), false);
return 1;
}
private static int addApplyEntity(CommandContext<CommandSourceStack> context, Entity entity, Vec3 offset) {
LeashStateInnerAPI.Offset.addApplyEntity(entity, offset);
context.getSource().sendSuccess(() ->
Component.translatable(ADD_APPLY_ENTITY_SUC, getSLPName(entity), offset), false);
return 1;
}
// ==================== 移除操作实现 ====================
private static int removeHolderFor(CommandContext<CommandSourceStack> context, Entity entity, Entity holder) {
LeashStateInnerAPI.Offset.removeHolderFor(entity, holder);
context.getSource().sendSuccess(() ->
Component.translatable(REMOVE_HOLDER_FOR_SUC, getSLPName(entity), getSLPName(holder)), false);
return 1;
}
private static int removeHolderForBlockPos(CommandContext<CommandSourceStack> context, Entity entity, BlockPos pos) {
LeashStateInnerAPI.Offset.removeHolderFor(entity, pos);
context.getSource().sendSuccess(() ->
Component.translatable(REMOVE_HOLDER_FOR_BLOCK_POS_SUC, getSLPName(entity), getSLPName(pos)), false);
return 1;
}
private static int removeHolderAll(CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.removeHolderAll(entity);
context.getSource().sendSuccess(() ->
Component.translatable(REMOVE_HOLDER_ALL_SUC, getSLPName(entity)), false);
return 1;
}
private static int removeAllHolderUUIDs(CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.removeAllHolderUUIDs(entity);
context.getSource().sendSuccess(() ->
Component.translatable(REMOVE_ALL_HOLDER_UUIDS_SUC, getSLPName(entity)), false);
return 1;
}
private static int removeAllHolderBlockPoses(CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.removeAllHolderBlockPoses(entity);
context.getSource().sendSuccess(() ->
Component.translatable(REMOVE_ALL_HOLDER_BLOCK_POSES_SUC, getSLPName(entity)), false);
return 1;
}
private static int removeApplyEntity(CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.removeApplyEntity(entity);
context.getSource().sendSuccess(() ->
Component.translatable(REMOVE_APPLY_ENTITY_SUC, getSLPName(entity)), false);
return 1;
}
// ==================== 查询操作实现 ==================== // ==================== 查询操作实现 ====================
private static int queryHasState(CommandContext<CommandSourceStack> context, Entity entity) { private static int queryHasState(@NotNull CommandContext<CommandSourceStack> context, Entity entity) {
boolean hasState = LeashStateInnerAPI.Query.hasState(entity); boolean hasState = LeashStateInnerAPI.Query.hasState(entity);
context.getSource().sendSuccess(() -> MutableComponent send = Component.empty();
Component.translatable(QUERY_HAS_STATE_SUC, getSLPName(entity), hasState), false); send.append(Component.translatable(QUERY_HAS_STATE_SUC, getSLPName(entity), hasState));
context.getSource().sendSuccess(() -> send, false);
return 1; return 1;
} }
private static int getAllUUIDStates(CommandContext<CommandSourceStack> context, Entity entity) { private static int getAllUUIDStates(CommandContext<CommandSourceStack> context, Entity entity) {
var states = LeashStateInnerAPI.Query.getAllUUIDStates(entity); var states = LeashStateInnerAPI.Query.getAllUUIDStates(entity);
context.getSource().sendSuccess(() -> MutableComponent head = Component.translatable(GET_ALL_UUID_STATES_SUC, getSLPName(entity), states.size()).append("\n");
Component.translatable(GET_ALL_UUID_STATES_SUC, getSLPName(entity), states.size()), false);
states.forEach((uuid, state) -> { MutableComponent content = Component.empty();
context.getSource().sendSuccess(() -> if (states.isEmpty()) {
Component.literal(" UUID: " + uuid + ", 状态: " + state), false); content.append(Component.translatable(NONE));
}); } else {
int count = 0;
for (var entry : states.entrySet()) {
if (count >= MAX_SHOW_NUMBER) {
content.append(Component.translatable(ABBREVIATION));
break;
}
// UUID: xxx, 状态: xxx
MutableComponent stateInfo = Component.literal(" UUID: " + entry.getKey() + ", 状态: " + entry.getValue());
// 添加悬停信息
MutableComponent hover = Component.empty();
hover.append(Component.translatable(UUID).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getKey().toString())).append("\n");
hover.append(Component.translatable(STATE).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getValue().toString()));
stateInfo.withStyle(s -> s.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover)));
content.append(stateInfo);
if (count < Math.min(states.size(), MAX_SHOW_NUMBER) - 1) {
content.append("\n");
}
count++;
}
}
context.getSource().sendSuccess(() -> head.append(content), false);
return 1; return 1;
} }
private static int getAllBlockPosStates(CommandContext<CommandSourceStack> context, Entity entity) { private static int getAllBlockPosStates(CommandContext<CommandSourceStack> context, Entity entity) {
var states = LeashStateInnerAPI.Query.getAllBlockPosStates(entity); var states = LeashStateInnerAPI.Query.getAllBlockPosStates(entity);
context.getSource().sendSuccess(() -> MutableComponent head = Component.translatable(GET_ALL_BLOCK_POS_STATES_SUC, getSLPName(entity), states.size()).append("\n");
Component.translatable(GET_ALL_BLOCK_POS_STATES_SUC, getSLPName(entity), states.size()), false);
states.forEach((pos, state) -> { MutableComponent content = Component.empty();
context.getSource().sendSuccess(() -> if (states.isEmpty()) {
Component.literal(" 位置: " + pos + ", 状态: " + state), false); content.append(Component.translatable(NONE));
}); } else {
int count = 0;
for (var entry : states.entrySet()) {
if (count >= MAX_SHOW_NUMBER) {
content.append(Component.translatable(ABBREVIATION));
break;
}
BlockPos pos = entry.getKey();
// 位置: (x,y,z), 状态: xxx
MutableComponent stateInfo = Component.literal(Component.translatable(BLOCK_POS, pos.getX(), pos.getY(), pos.getZ()) +"," + Component.translatable(STATE) + Component.translatable(COLON) + entry.getValue());
// 添加悬停信息
MutableComponent hover = Component.empty();
hover.append(Component.translatable(BLOCK).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(pos.toShortString())).append("\n");
hover.append(Component.translatable(STATE).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getValue().toString()));
// 添加点击事件建议传送到该位置
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND,
String.format("/tp @s %d %d %d", pos.getX(), pos.getY(), pos.getZ()));
stateInfo.withStyle(s -> s.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover))
.withClickEvent(clickEvent));
content.append(stateInfo);
if (count < Math.min(states.size(), MAX_SHOW_NUMBER) - 1) {
content.append("\n");
}
count++;
}
}
context.getSource().sendSuccess(() -> head.append(content), false);
return 1; return 1;
} }
private static int getApplyEntityOffset(CommandContext<CommandSourceStack> context, Entity entity) { private static int getApplyEntityOffset(CommandContext<CommandSourceStack> context, Entity entity) {
LeashStateInnerAPI.Offset.getApplyEntityOffset(entity).ifPresentOrElse( LeashStateInnerAPI.Offset.getApplyEntityOffset(entity).ifPresentOrElse(
offset -> context.getSource().sendSuccess(() -> offset -> {
Component.translatable(GET_APPLY_ENTITY_OFFSET_SUC, getSLPName(entity), offset), false), MutableComponent send = Component.empty();
() -> context.getSource().sendSuccess(() -> send.append(Component.translatable(GET_APPLY_ENTITY_OFFSET_SUC, getSLPName(entity), offset));
Component.translatable(GET_APPLY_ENTITY_OFFSET_NONE, getSLPName(entity)), false) context.getSource().sendSuccess(() -> send, false);
},
() -> {
MutableComponent send = Component.empty();
send.append(Component.translatable(GET_APPLY_ENTITY_OFFSET_NONE, getSLPName(entity)));
context.getSource().sendSuccess(() -> send, false);
}
); );
return 1; return 1;
} }
private static int getDefaultApplyEntityOffset(CommandContext<CommandSourceStack> context, Entity entity) { private static int getDefaultApplyEntityOffset(@NotNull CommandContext<CommandSourceStack> context, Entity entity) {
Vec3 offset = LeashStateInnerAPI.Offset.getDefaultApplyEntityOffset(entity); Vec3 offset = LeashStateInnerAPI.Offset.getDefaultApplyEntityOffset(entity);
context.getSource().sendSuccess(() -> MutableComponent send = Component.empty();
Component.translatable(GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC, getSLPName(entity), offset), false); send.append(Component.translatable(GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC, getSLPName(entity), offset));
context.getSource().sendSuccess(() -> send, false);
return 1;
}
public static final String GET_ALL_STATES_HEAD = SLP_LEASH_STATE_MESSAGE_ + "get_all_states.head";
private static int getAllStates(CommandContext<CommandSourceStack> context, @NotNull Entity entity) {
MutableComponent head = Component.translatable(GET_ALL_STATES_HEAD, entity.getDisplayName()).append("\n");
// 获取所有状态信息
var uuidStates = LeashStateInnerAPI.Query.getAllUUIDStates(entity);
var blockPosStates = LeashStateInnerAPI.Query.getAllBlockPosStates(entity);
var applyOffset = LeashStateInnerAPI.Offset.getApplyEntityOffset(entity);
var defaultOffset = LeashStateInnerAPI.Offset.getDefaultApplyEntityOffset(entity);
MutableComponent content = Component.empty();
// UUID 状态
content.append(Component.translatable(UUID).withStyle(ChatFormatting.YELLOW)).append(": ");
if (uuidStates.isEmpty()) {
content.append(Component.translatable(NONE));
} else {
int count = 0;
for (var entry : uuidStates.entrySet()) {
if (count >= 4) { // 限制显示数量
content.append(Component.translatable(ABBREVIATION));
break;
}
MutableComponent stateComp = Component.literal("[U]").withStyle(ChatFormatting.GREEN);
MutableComponent hover = Component.empty();
hover.append(Component.translatable(UUID).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getKey().toString())).append("\n");
hover.append(Component.translatable(STATE).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getValue().toString()));
stateComp.withStyle(s -> s.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover)));
content.append(stateComp);
if (count < Math.min(uuidStates.size(), 4) - 1) {
content.append(", ");
}
count++;
}
}
content.append("\n");
// 方块位置状态
content.append(Component.translatable(BLOCK).withStyle(ChatFormatting.YELLOW)).append(": ");
if (blockPosStates.isEmpty()) {
content.append(Component.translatable(NONE));
} else {
int count = 0;
for (var entry : blockPosStates.entrySet()) {
if (count >= 4) { // 限制显示数量
content.append(Component.translatable(ABBREVIATION));
break;
}
MutableComponent stateComp = Component.literal("[B]").withStyle(ChatFormatting.BLUE);
MutableComponent hover = Component.empty();
hover.append(Component.translatable(BLOCK).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getKey().toShortString())).append("\n");
hover.append(Component.translatable(STATE).withStyle(ChatFormatting.DARK_AQUA))
.append(Component.translatable(COLON).withStyle(ChatFormatting.GRAY))
.append(Component.literal(entry.getValue().toString()));
stateComp.withStyle(s -> s.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover)));
content.append(stateComp);
if (count < Math.min(blockPosStates.size(), 4) - 1) {
content.append(", ");
}
count++;
}
}
content.append("\n");
// 应用偏移量
content.append(Component.translatable(APPLY_OFFSET).withStyle(ChatFormatting.YELLOW)).append(": ");
applyOffset.ifPresentOrElse(
offset -> content.append(Component.literal(String.format("(%.2f, %.2f, %.2f)", offset.x, offset.y, offset.z))),
() -> content.append(Component.translatable(NONE))
);
content.append("\n");
// 默认偏移量
content.append(Component.translatable(DEFAULT_OFFSET).withStyle(ChatFormatting.YELLOW)).append(": ");
content.append(Component.literal(String.format("(%.2f, %.2f, %.2f)", defaultOffset.x, defaultOffset.y, defaultOffset.z)));
context.getSource().sendSuccess(() -> head.append(content), false);
return 1; return 1;
} }
} }

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -36,7 +36,7 @@ public class LeashRenderHook {
* @return the boolean * @return the boolean
*/ */
public static boolean shouldRenderExtra(Mob mob, Frustum camera) { public static boolean shouldRenderExtra(Mob mob, Frustum camera) {
SuperLeadRope.logger.debug("[SuperLeash] Checking entity: {} at position: {}, {}, {}", mob.getName().getString(), mob.getX(), mob.getY(), mob.getZ()); // SuperLeadRope.logger.debug("[SuperLeash] Checking entity: {} at position: {}, {}, {}", mob.getName().getString(), mob.getX(), mob.getY(), mob.getZ());
AtomicBoolean flag = new AtomicBoolean(false); AtomicBoolean flag = new AtomicBoolean(false);
LeashDataInnerAPI.getLeashData(mob).ifPresent(i -> { LeashDataInnerAPI.getLeashData(mob).ifPresent(i -> {
i.getAllLeashes().forEach(j -> { i.getAllLeashes().forEach(j -> {

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -20,6 +20,7 @@ import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.content.command.Command; import top.r3944realms.superleadrope.content.command.Command;
import top.r3944realms.superleadrope.content.command.LeashDataCommand; import top.r3944realms.superleadrope.content.command.LeashDataCommand;
import top.r3944realms.superleadrope.content.command.LeashStateCommand;
import top.r3944realms.superleadrope.content.command.MotionCommand; import top.r3944realms.superleadrope.content.command.MotionCommand;
import top.r3944realms.superleadrope.content.gamerule.server.CreateSuperLeashKnotEntityIfAbsent; import top.r3944realms.superleadrope.content.gamerule.server.CreateSuperLeashKnotEntityIfAbsent;
import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities; import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities;
@ -349,6 +350,120 @@ public enum SLPLangKeyValue {
"§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r",
"§b倍乘既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r" "§b倍乘既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r"
), ),
// ==================== 重置操作消息 ====================
MESSAGE_STATE_RESET_ALL_HOLDER_SUC(
LeashStateCommand.RESET_ALL_HOLDER_SUC, ModPartEnum.COMMAND,
"Successfully reset all holders for %s",
"已成功重置%s的所有持有者状态",
"已成功重置%s的所有持有者狀態",
"%s之諸持者狀態今已盡復"
),
MESSAGE_STATE_RESET_HOLDER_FOR_SUC(
LeashStateCommand.RESET_HOLDER_FOR_SUC, ModPartEnum.COMMAND,
"Successfully reset holder %s for %s",
"已成功重置%s的持有者%s状态",
"已成功重置%s的持有者%s狀態",
"%s之持者%s狀態今已復"
),
MESSAGE_STATE_RESET_HOLDER_FOR_BLOCK_POS_SUC(
LeashStateCommand.RESET_HOLDER_FOR_BLOCK_POS_SUC, ModPartEnum.COMMAND,
"Successfully reset block position %s for %s",
"已成功重置%s的方块位置%s状态",
"已成功重置%s的方塊位置%s狀態",
"%s之位%s狀態今已復"
),
MESSAGE_STATE_RESET_APPLY_ENTITY_ALL_SUC(
LeashStateCommand.RESET_APPLY_ENTITY_ALL_SUC, ModPartEnum.COMMAND,
"Successfully reset all apply entity offsets for %s",
"已成功重置%s的所有应用实体偏移",
"已成功重置%s的所有應用實體偏移",
"%s之諸用體偏移今已盡復"
),
// ==================== 设置操作消息 ====================
MESSAGE_STATE_SET_HOLDER_FOR_SUC(
LeashStateCommand.SET_HOLDER_FOR_SUC, ModPartEnum.COMMAND,
"Successfully set holder %s for %s",
"已成功为%s设置持有者%s",
"已成功為%s設置持有者%s",
"為%s設持者%s其事已成"
),
MESSAGE_STATE_SET_HOLDER_FOR_BLOCK_POS_SUC(
LeashStateCommand.SET_HOLDER_FOR_BLOCK_POS_SUC, ModPartEnum.COMMAND,
"Successfully set block position %s for %s",
"已成功为%s设置方块位置%s",
"已成功為%s設置方塊位置%s",
"為%s設位%s其事已成"
),
MESSAGE_STATE_SET_APPLY_ENTITY_SUC(
LeashStateCommand.SET_APPLY_ENTITY_SUC, ModPartEnum.COMMAND,
"Successfully set apply entity offset %s for %s",
"已成功为%s设置应用实体偏移%s",
"已成功為%s設置應用實體偏移%s",
"為%s設用體偏移%s其事已成"
),
// ==================== 查询操作消息 ====================
MESSAGE_STATE_QUERY_HAS_STATE_SUC(
LeashStateCommand.QUERY_HAS_STATE_SUC, ModPartEnum.COMMAND,
"%s has state: %s",
"%s 拥有状态: %s",
"%s 擁有狀態: %s",
"%s 有狀否: %s"
),
MESSAGE_STATE_GET_ALL_UUID_STATES_SUC(
LeashStateCommand.GET_ALL_UUID_STATES_SUC, ModPartEnum.COMMAND,
"Found %d UUID states for %s:",
"找到%s的%d个UUID状态:",
"找到%s的%d個UUID狀態:",
"%s之UUID狀有%d:"
),
MESSAGE_STATE_GET_ALL_BLOCK_POS_STATES_SUC(
LeashStateCommand.GET_ALL_BLOCK_POS_STATES_SUC, ModPartEnum.COMMAND,
"Found %d block position states for %s:",
"找到%s的%d个方块位置状态:",
"找到%s的%d個方塊位置狀態:",
"%s之位狀有%d:"
),
MESSAGE_STATE_GET_APPLY_ENTITY_OFFSET_SUC(
LeashStateCommand.GET_APPLY_ENTITY_OFFSET_SUC, ModPartEnum.COMMAND,
"%s apply entity offset: %s",
"%s 应用实体偏移: %s",
"%s 應用實體偏移: %s",
"%s 用體偏移: %s"
),
MESSAGE_STATE_GET_APPLY_ENTITY_OFFSET_NONE(
LeashStateCommand.GET_APPLY_ENTITY_OFFSET_NONE, ModPartEnum.COMMAND,
"%s has no apply entity offset",
"%s 没有应用实体偏移",
"%s 沒有應用實體偏移",
"%s 無用體偏移"
),
MESSAGE_STATE_GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC(
LeashStateCommand.GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC, ModPartEnum.COMMAND,
"%s default apply entity offset: %s",
"%s 默认应用实体偏移: %s",
"%s 默認應用實體偏移: %s",
"%s 常用體偏移: %s"
),
MESSAGE_STATE_GET_ALL_STATES_HEAD(
LeashStateCommand.GET_ALL_STATES_HEAD, ModPartEnum.COMMAND,
"All states for %s:",
"%s 的所有状态:",
"%s 的所有狀態:",
"%s 之諸狀:"
),
MESSAGE_ABBREVIATION( MESSAGE_ABBREVIATION(
Command.ABBREVIATION, ModPartEnum.COMMAND, Command.ABBREVIATION, ModPartEnum.COMMAND,
"...", "...",
@ -384,15 +499,36 @@ public enum SLPLangKeyValue {
"", "",
"" ""
), ),
MESSAGE_STATE(
Command.STATE, ModPartEnum.COMMAND,
"State",
"状态",
"狀態",
""
),
MESSAGE_APPLY_OFFSET(
LeashStateCommand.APPLY_OFFSET, ModPartEnum.COMMAND,
"Apply Offset",
"应用偏移状态",
"應用偏移狀態",
"偏狀"
),
MESSAGE_DEFAULT_OFFSET(
LeashStateCommand.DEFAULT_OFFSET, ModPartEnum.COMMAND,
"Default Offset",
"默认偏移状态",
"預設偏移狀態",
"常偏狀"
),
MESSAGE_LEASHDATA_ALL_KNOTS( MESSAGE_LEASHDATA_ALL_KNOTS(
LeashDataCommand.ALL_KNOTS, ModPartEnum.COMMAND, Command.ALL_KNOTS, ModPartEnum.COMMAND,
"All Knots", "All Knots",
"所有绳结", "所有绳结",
"所有繩結", "所有繩結",
"諸結" "諸結"
), ),
MESSAGE_LEASHDATA_ALL_HOLDERS( MESSAGE_LEASHDATA_ALL_HOLDERS(
LeashDataCommand.ALL_HOLDERS, ModPartEnum.COMMAND, Command.ALL_HOLDERS, ModPartEnum.COMMAND,
"All Holders", "All Holders",
"所有持有者", "所有持有者",
"所有持有者", "所有持有者",

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -23,6 +23,7 @@ import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.simple.SimpleChannel;
import top.r3944realms.superleadrope.SuperLeadRope; import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.network.toClient.*; import top.r3944realms.superleadrope.network.toClient.*;
import top.r3944realms.superleadrope.network.toServer.SyncCommonConfigRequestPacket;
/** /**
@ -69,6 +70,21 @@ public class NetworkHandler {
.encoder(LeashStateSyncPacket::encode) .encoder(LeashStateSyncPacket::encode)
.consumerNetworkThread(LeashStateSyncPacket::handle) .consumerNetworkThread(LeashStateSyncPacket::handle)
.add(); .add();
INSTANCE.messageBuilder(SyncCommonConfigPacket.class, cid++, NetworkDirection.PLAY_TO_CLIENT)
.decoder(SyncCommonConfigPacket::decode)
.encoder(SyncCommonConfigPacket::encode)
.consumerNetworkThread(SyncCommonConfigPacket::handle)
.add();
INSTANCE.messageBuilder(SyncCommonConfigRequestPacket.class, cid++, NetworkDirection.PLAY_TO_SERVER)
.decoder(SyncCommonConfigRequestPacket::decode)
.encoder(SyncCommonConfigRequestPacket::encode)
.consumerNetworkThread(SyncCommonConfigRequestPacket::handle)
.add();
INSTANCE.messageBuilder(CommonConfigHashInformPacket.class, cid++, NetworkDirection.PLAY_TO_CLIENT)
.decoder(CommonConfigHashInformPacket::decode)
.encoder(CommonConfigHashInformPacket::encode)
.consumerNetworkThread(CommonConfigHashInformPacket::handle)
.add();
} }
/** /**
@ -82,6 +98,16 @@ public class NetworkHandler {
INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message); INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message);
} }
/**
* Send to all player.
*
* @param <MSG> the type parameter
* @param message the message
*/
public static <MSG> void sendToAllPlayer(MSG message){
INSTANCE.send(PacketDistributor.ALL.noArg(), message);
}
/** /**
* Send to player. * Send to player.
* *

View File

@ -0,0 +1,54 @@
package top.r3944realms.superleadrope.network.toClient;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import top.r3944realms.superleadrope.CommonEventHandler;
import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.network.toServer.SyncCommonConfigRequestPacket;
import java.util.function.Supplier;
/**
* The type Common config hash inform packet.
*/
public record CommonConfigHashInformPacket(int hash) {
/**
* Encode.
*
* @param packet the packet
* @param buffer the buffer
*/
public static void encode(CommonConfigHashInformPacket packet, FriendlyByteBuf buffer) {
buffer.writeInt(packet.hash());
}
/**
* Decode common config hash inform packet.
*
* @param buffer the buffer
* @return the common config hash inform packet
*/
public static CommonConfigHashInformPacket decode(FriendlyByteBuf buffer) {
return new CommonConfigHashInformPacket(buffer.readInt());
}
/**
* Handle.
*
* @param packet the packet
* @param ctx the ctx
*/
public static void handle(CommonConfigHashInformPacket packet, Supplier<NetworkEvent.Context> ctx) {
NetworkEvent.Context context = ctx.get();
context.enqueueWork(() -> {
int hash = CommonEventHandler.leashConfigManager.calculateConfigHash();
if (hash != packet.hash()) {
NetworkHandler.INSTANCE.sendToServer(new SyncCommonConfigRequestPacket(hash));
}
}
);
context.setPacketHandled(true);
}
}

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -36,6 +36,7 @@ public record PacketEternalPotatoRemovePacket(UUID itemUUID) {
buf.writeUUID(msg.itemUUID()); buf.writeUUID(msg.itemUUID());
} }
/** /**
* Decode packet eternal potato remove packet. * Decode packet eternal potato remove packet.
* *

View File

@ -0,0 +1,53 @@
package top.r3944realms.superleadrope.network.toClient;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import top.r3944realms.superleadrope.CommonEventHandler;
import top.r3944realms.superleadrope.SuperLeadRope;
import java.util.function.Supplier;
/**
* The type Sync common config packet.
*/
public record SyncCommonConfigPacket(CompoundTag config, int hash) {
/**
* Encode.
*
* @param msg the msg
* @param buf the buf
*/
public static void encode(SyncCommonConfigPacket msg, FriendlyByteBuf buf) {
buf.writeNbt(msg.config);
buf.writeInt(msg.hash);
}
/**
* Decode packet eternal potato remove packet.
*
* @param buf the buf
* @return the packet eternal potato remove packet
*/
public static SyncCommonConfigPacket decode(FriendlyByteBuf buf) {
return new SyncCommonConfigPacket(buf.readNbt(), buf.readInt());
}
/**
* Handle.
*
* @param msg the msg
* @param ctx the ctx
*/
public static void handle(SyncCommonConfigPacket msg, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
CompoundTag old = CommonEventHandler.leashConfigManager.serializeToNBT();
CommonEventHandler.leashConfigManager.deserializeFromNBT(msg.config);
if (CommonEventHandler.leashConfigManager.calculateConfigHash() != msg.hash) { //BACK
SuperLeadRope.logger.error("Hash mismatch! Except:{}, Actual:{}", msg.hash, CommonEventHandler.leashConfigManager.calculateConfigHash());
CommonEventHandler.leashConfigManager.deserializeFromNBT(old);
}
});
ctx.get().setPacketHandled(true);
}
}

View File

@ -7,7 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,51 @@
package top.r3944realms.superleadrope.network.toServer;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import top.r3944realms.superleadrope.CommonEventHandler;
import top.r3944realms.superleadrope.config.LeashConfigManager;
import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.network.toClient.SyncCommonConfigPacket;
import java.util.function.Supplier;
/**
* The type Sync common config request packet.
*/
public record SyncCommonConfigRequestPacket(int hash) {
/**
* Encode.
*
* @param msg the msg
* @param buf the buf
*/
public static void encode(SyncCommonConfigRequestPacket msg, FriendlyByteBuf buf) {
buf.writeInt(msg.hash);
}
/**
* Decode sync common config request packet.
*
* @param buf the buf
* @return the sync common config request packet
*/
public static SyncCommonConfigRequestPacket decode(FriendlyByteBuf buf) {
return new SyncCommonConfigRequestPacket(buf.readInt());
}
/**
* Handle.
*
* @param msg the msg
* @param ctx the ctx
*/
public static void handle(SyncCommonConfigRequestPacket msg, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
if (msg.hash != LeashConfigManager.cacheHash) {
NetworkHandler.sendToPlayer(new SyncCommonConfigPacket(CommonEventHandler.leashConfigManager.serializeToNBT(), CommonEventHandler.leashConfigManager.calculateConfigHash()), ctx.get().getSender());
}
});
ctx.get().setPacketHandled(true);
}
}

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