Compare commits

...

10 Commits

Author SHA1 Message Date
18d1d06d39 版本更新 1.2.2 -> 1.2.3
修复拴绳配置同步问题
2026-03-30 20:21:59 +08:00
0b6412548f 添加附魔描述 2026-03-29 10:40:56 +08:00
e6465233fb 更新版本 v1.2.1 -> v1.2.2
修复客户端同步bug
2026-03-07 14:51:57 +08:00
0e846b98a0 更新版本 v1.2.0 -> v1.2.1
修复API方法
2026-02-17 13:31:50 +08:00
47ec1af5c1 更新版本 v1.1.0 -> v1.2.0
修复API方法
2026-02-17 13:26:53 +08:00
3a519afad2 更新版本 v1.0.0 -> v1.1.0
添加了拴绳实体
新增新的附魔
调整拴绳数据cap实现
修改配置
删除无用代码
更新代码版权声明
优化import
2026-02-03 11:46:28 +08:00
ebec0d5dee 构建脚本修改(修复publish后没有refmap问题) 2026-01-13 12:24:59 +08:00
ad275c4d37 版本更新到1.0.0
1. 对WayStone做进一步适配(显然WS自己有问题)
2. 添加了禁拴效果及其对应的药水
3. 添加了彩蛋内容(暂无非作弊获取方式)
4. 添加了最大拴绳拉力阈值,在配置中调整
2025-12-11 18:27:07 +08:00
186103e0c5 版本更新到0.0.0.9
对WayStone做适配
2025-12-07 19:42:01 +08:00
8367efcf57 版本更新到0.0.0.8
将玩家拴绳应力逻辑放入到客户端
2025-12-04 19:23:40 +08:00
142 changed files with 3939 additions and 381 deletions

View File

@ -123,6 +123,11 @@ legacyForge {
server {
server()
}
testServer {
server()
//
gameDirectory = file('run/server')
}
data {
data()
programArguments.addAll '--mod', mod_id, '--all',
@ -165,6 +170,9 @@ dependencies {
modImplementation("blank:curtain-1.20.1:1.3.2")
modImplementation("dev.kosmx.player-anim:player-animation-lib-forge:${player_anim_version}")
modImplementation("curse.maven:bendy-lib-623373:4550371")
modImplementation("curse.maven:waystones-245755:6856603")
modImplementation("curse.maven:balm-531761:7087245")
// modImplementation("curse.maven:kaleidoscope-doll-1233277:7201584")
// modRuntimeOnly("curse.maven:luckperms-431733:4738950")
modImplementation("software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}")
implementation("com.eliotlash.mclib:mclib:20")
@ -202,23 +210,7 @@ tasks.named('javadoc', Javadoc).configure {
options.addBooleanOption('Xdoclint:none', true)
options.addStringOption('doctitle', "${mod_id} ${minecraft_version} ${mod_version} Javadoc")
}
// =====================class/ java =====================
tasks.register('deobfJar', Jar) {
from(sourceSets.main.output) // class
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes([
'Specification-Title' : mod_id,
'Specification-Vendor' : mod_authors,
'Specification-Version' : '1',
'Implementation-Title' : project.name,
'Implementation-Version' : archiveVersion,
'Implementation-Vendor' : mod_authors,
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
])
}
dependsOn classes
}
tasks.register('sourceJar', Jar) {
from(sourceSets.main.allSource) // java
archiveFileName = "${mod_id}-${minecraft_version}-${mod_version}-sources.jar"
@ -382,6 +374,9 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources
sourceSets.main.resources.srcDir generateModMetadata
legacyForge.ideSyncTask generateModMetadata
tasks.named('publish') {
dependsOn build
}
afterEvaluate {
tasks.named('reobfJar') {
@ -403,7 +398,7 @@ publishing {
mavenJava(MavenPublication) {
artifactId = mod_id
artifact deobfJar
artifact reobfJar
artifact sourceJar
artifact javadocJar
artifact apiJar

View File

@ -9,7 +9,7 @@ neoForge.parchment.minecraftVersion=1.20.1
neoForge.parchment.mappingsVersion=2023.09.03
# enable ProGuard
enableProguard=true
enableProguard=false
# Jei Version
jei_version=15.20.0.112
#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.
mod_license=GPLv3
# The mod version. See https://semver.org/
mod_version=0.0.0.8
mod_version=1.2.3
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

1
res/doll.bbmodel Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-04T18:55:51.5054614 Languages: zh_tw
ff7556f7a8bd62a8c4cc776e45947835ffc19689 assets/superleadrope/lang/zh_tw.json
// 1.20.1 2026-03-29T10:38:49.6124091 Languages: zh_tw
14bd3a4eb08bbd6e0d88d1d16892ac3a34795631 assets/superleadrope/lang/zh_tw.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-04T18:55:51.5004568 Languages: zh_cn
f5128cf6058db0e79f91aece8de7f5bdd8e04193 assets/superleadrope/lang/zh_cn.json
// 1.20.1 2026-03-29T10:38:49.6074077 Languages: zh_cn
a7e9485ab95b318476762be5513c95d3504d1e8a assets/superleadrope/lang/zh_cn.json

View File

@ -1,4 +1,4 @@
// 1.20.1 2025-09-05T21:41:43.7307014 Item Models: superleadrope
// 1.20.1 2026-02-02T15:05:26.4884922 Item Models: superleadrope
c982e91b60c03a6460d1cc7b516628cf09a28417 assets/superleadrope/models/item/broken_super_lead_rope.json
7b072a8cc70b53d54e37e5fa72d705bd07780943 assets/superleadrope/models/item/eternal_potato.json
4fb737a5f8f15642212aa581a02a81cf649fc36f assets/superleadrope/models/item/super_lead_rope.json

View File

@ -0,0 +1 @@
// 1.20.1 2026-02-02T15:05:26.4884922 Block States: superleadrope

View File

@ -0,0 +1 @@
// 1.20.1 2026-02-02T15:05:26.4750266 Loot Tables

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-04T18:55:51.5034621 Languages: lzh
8dde976f77c0ca836ed66627ea2af29b20e5f7c5 assets/superleadrope/lang/lzh.json
// 1.20.1 2026-03-29T10:38:49.6104091 Languages: lzh
3111e6847a748c793b08ff1c72cf5509cb454335 assets/superleadrope/lang/lzh.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-04T18:55:51.5024633 Languages: en_us
b1f5523a28ab74acc8bd5b0ec167bf254e0b0dea assets/superleadrope/lang/en_us.json
// 1.20.1 2026-03-29T10:38:49.6094088 Languages: en_us
e382e15d14fad2599e91b9fa8a97c8893492c843 assets/superleadrope/lang/en_us.json

View File

@ -1,7 +1,13 @@
{
"death.attack.eternal_potato_not_complete": "§c%1$s was not the rightful owner, struck by lightning!",
"death.attack.eternal_potato_not_owner": "§c%1$s was not the rightful owner, struck by lightning!",
"effect.superleadrope.no_super_leash": "No Super Leash",
"enchantment.superleadrope.prisoner": "Self Prisoner",
"enchantment.superleadrope.prisoner.desc": "Throw the lead to lasso yourself. Requires Ring Toss enchantment to take effect. Higher levels increase throwing distance",
"enchantment.superleadrope.ring_toss": "Ring Toss",
"enchantment.superleadrope.ring_toss.desc": "Throw the lead to lasso creatures. Higher levels increase throwing distance and reduce required charge time",
"entity.superleadrope.super_lead_knot": "Super Lead Knot",
"entity.superleadrope.super_leash_rope": "Super Lead Rope",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence or other supported positions",
"gamerule.SLP.TeleportWithLeashedEntities": "Teleport leashed player with holder",
@ -22,6 +28,9 @@
"item.eternal_potato.tooltip.punish": "§cOverdue punishments: §4%d §7(will be applied), grace exceeded: §4%d",
"item.eternal_potato.tooltip.title": "§6Mythical Item §7- §6Eternal Potato",
"item.eternal_potato.tooltip.unbound": "§cUnbound",
"item.minecraft.lingering_potion.effect.no_super_leash": "Splash No Super Leash Potion",
"item.minecraft.potion.effect.no_super_leash": "No Super Leash Potion",
"item.minecraft.splash_potion.effect.no_super_leash": "Splash No Super Leash Potion",
"item.superleadrope.eternal_potato": "Eternal Potato",
"item.superleadrope.super_lead_rope": "Super Lead Rope",
"sound.superleadrope.subtitle.lead_break": "Lead Break",
@ -105,5 +114,6 @@
"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.none": "<None>",
"superleadrope.command.state": "State"
"superleadrope.command.state": "State",
"tooltip.superleadrope.author": "Author : R3944Realms"
}

View File

@ -1,7 +1,13 @@
{
"death.attack.eternal_potato_not_complete": "§c%1$s 非汝所主,雷霆降身!",
"death.attack.eternal_potato_not_owner": "§c%1$s 非汝所主,雷霆降身!",
"effect.superleadrope.no_super_leash": "禁系之效",
"enchantment.superleadrope.prisoner": "自拴",
"enchantment.superleadrope.prisoner.desc": "擲繩,需套圈附魔方效。階愈高,擲愈遠",
"enchantment.superleadrope.ring_toss": "套圈",
"enchantment.superleadrope.ring_toss.desc": "擲繩套獸,階愈高,擲愈遠,蓄愈短",
"entity.superleadrope.super_lead_knot": "神駒羈縻索結",
"entity.superleadrope.super_leash_rope": "神駒羈縻索",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "若阙则创超级繫绳结",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "若栅等支处阙超级繫绳结,则创之",
"gamerule.SLP.TeleportWithLeashedEntities": "繫畜隨持者傳送",
@ -22,6 +28,9 @@
"item.eternal_potato.tooltip.punish": "§c逾期责务尚未完成: §4%d §7(將受懲罰),超出寬限數: §4%d",
"item.eternal_potato.tooltip.title": "§6永恒土豆 §7- §6传奇之物",
"item.eternal_potato.tooltip.unbound": "§c尚未绑定主人",
"item.minecraft.lingering_potion.effect.no_super_leash": "缠绵禁系汤",
"item.minecraft.potion.effect.no_super_leash": "禁系汤剂",
"item.minecraft.splash_potion.effect.no_super_leash": "飞溅禁系汤",
"item.superleadrope.eternal_potato": "不滅薯",
"item.superleadrope.super_lead_rope": "神駒羈縻索",
"sound.superleadrope.subtitle.lead_break": "索絕",
@ -105,5 +114,6 @@
"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.none": "無",
"superleadrope.command.state": "狀"
"superleadrope.command.state": "狀",
"tooltip.superleadrope.author": "作者 : R3944Realms"
}

View File

@ -1,7 +1,13 @@
{
"death.attack.eternal_potato_not_complete": "§c%1$s 因使用非自己绑定物品,受到闪电惩罚!",
"death.attack.eternal_potato_not_owner": "§c%1$s 因使用非自己绑定物品,受到闪电惩罚!",
"effect.superleadrope.no_super_leash": "禁拴",
"enchantment.superleadrope.prisoner": "自拴",
"enchantment.superleadrope.prisoner.desc": "可以将拴绳丢出去套中自己。需要套圈附魔才能生效。等级越高丢出去的距离越远",
"enchantment.superleadrope.ring_toss": "套圈",
"enchantment.superleadrope.ring_toss.desc": "可以将拴绳丢出去套中生物,等级越高丢出去的距离越远,所需蓄力时间越短",
"entity.superleadrope.super_lead_knot": "超级拴绳结",
"entity.superleadrope.super_leash_rope": "超级拴绳",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "如果缺失则创建超级拴绳结",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "如果在栅栏等支持处缺失超级拴绳结,则创建它",
"gamerule.SLP.TeleportWithLeashedEntities": "被拴实体随持有者传送",
@ -22,6 +28,9 @@
"item.eternal_potato.tooltip.punish": "§c逾期未完成责务: §4%d §7(将会受罚),超出宽限数: §4%d",
"item.eternal_potato.tooltip.title": "§6神话物品 §7- §6永恒土豆",
"item.eternal_potato.tooltip.unbound": "§c未绑定主人",
"item.minecraft.lingering_potion.effect.no_super_leash": "滞留型禁拴药水",
"item.minecraft.potion.effect.no_super_leash": "禁拴药水",
"item.minecraft.splash_potion.effect.no_super_leash": "喷溅型禁拴药水",
"item.superleadrope.eternal_potato": "永恒土豆",
"item.superleadrope.super_lead_rope": "超级拴绳",
"sound.superleadrope.subtitle.lead_break": "拴绳断裂",
@ -105,5 +114,6 @@
"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.none": "无",
"superleadrope.command.state": "状态"
"superleadrope.command.state": "状态",
"tooltip.superleadrope.author": "作者 : R3944Realms"
}

View File

@ -1,7 +1,13 @@
{
"death.attack.eternal_potato_not_complete": "§c%1$s 因使用非自己綁定物品,受到閃電懲罰!",
"death.attack.eternal_potato_not_owner": "§c%1$s 因使用非自己綁定物品,受到閃電懲罰!",
"effect.superleadrope.no_super_leash": "禁拴",
"enchantment.superleadrope.prisoner": "自拴",
"enchantment.superleadrope.prisoner.desc": "可以將拴繩丟出去套中自己。需要套圈附魔才能生效。等級越高丟出去的距離越遠",
"enchantment.superleadrope.ring_toss": "套圈",
"enchantment.superleadrope.ring_toss.desc": "可以將拴繩丟出去套中生物,等級越高丟出去的距離越遠,所需蓄力時間越短",
"entity.superleadrope.super_lead_knot": "超級拴繩結",
"entity.superleadrope.super_leash_rope": "超級拴繩",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "如果缺失則創建超級拴繩結",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "如果在柵欄等支持處缺失超級拴繩結,則創建它",
"gamerule.SLP.TeleportWithLeashedEntities": "被拴实体随持有者傳送",
@ -22,6 +28,9 @@
"item.eternal_potato.tooltip.punish": "§c逾期未完成责務: §4%d §7(將會受罰),超出寬限數: §4%d",
"item.eternal_potato.tooltip.title": "§6神話物品 §7- §6永恒土豆",
"item.eternal_potato.tooltip.unbound": "§c未綁定主人",
"item.minecraft.lingering_potion.effect.no_super_leash": "滯留型禁拴藥水",
"item.minecraft.potion.effect.no_super_leash": "禁拴藥水",
"item.minecraft.splash_potion.effect.no_super_leash": "噴濺型禁拴藥水",
"item.superleadrope.eternal_potato": "永恆馬鈴薯",
"item.superleadrope.super_lead_rope": "超級拴繩",
"sound.superleadrope.subtitle.lead_break": "拴繩斷裂",
@ -105,5 +114,6 @@
"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.none": "無",
"superleadrope.command.state": "狀態"
"superleadrope.command.state": "狀態",
"tooltip.superleadrope.author": "作者 : R3944Realms"
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -20,6 +20,7 @@ import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
@ -28,7 +29,9 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShearsItem;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
@ -66,6 +69,7 @@ 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.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.content.entity.SuperLeashRopeEntity;
import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities;
import top.r3944realms.superleadrope.content.item.EternalPotatoItem;
import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem;
@ -74,6 +78,8 @@ import top.r3944realms.superleadrope.core.leash.LeashSyncManager;
import top.r3944realms.superleadrope.core.potato.EternalPotatoFacade;
import top.r3944realms.superleadrope.core.register.SLPGameruleRegistry;
import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.core.register.SLPPotionRecipeRegistry;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.core.util.PotatoMode;
import top.r3944realms.superleadrope.core.util.PotatoModeHelper;
import top.r3944realms.superleadrope.datagen.data.SLPLangKeyValue;
@ -471,6 +477,27 @@ public class CommonEventHandler {
CapabilityHandler.attachCapability(event);
}
/**
* On use shear item.
*
* @param event the event
*/
@SubscribeEvent
public static void onUseShearItem (PlayerInteractEvent.RightClickItem event) {
ItemStack itemStack = event.getItemStack();
if (itemStack.getItem() instanceof ShearsItem) {
Player player = event.getEntity();
if (LeashDataInnerAPI.QueryOperations.hasLeash(player)) {
LeashDataInnerAPI.LeashOperations.detachAll(player);
if (!player.isCreative()) {
itemStack.hurtAndBreak(5, player, p -> p.broadcastBreakEvent(event.getHand()));
}
event.getLevel().playSound(null, player.getOnPos(), SLPSoundEvents.LEAD_UNTIED.get(), SoundSource.AMBIENT);
event.setCancellationResult(InteractionResult.CONSUME);
}
}
}
/**
* On register command.
*
@ -499,6 +526,8 @@ public class CommonEventHandler {
public static void onFMLCommonInit(FMLCommonSetupEvent event) {
event.enqueueWork(Mod::checkAndSet);
event.enqueueWork(SLPGameruleRegistry::register);
event.enqueueWork(SLPPotionRecipeRegistry::init);
event.enqueueWork(() -> DispenserBlock.registerBehavior(SLPItems.SUPER_LEAD_ROPE.get(), SuperLeashRopeEntity.SuperLeashRopeItemBehavior.INSTANCE));
}
/**
@ -571,6 +600,7 @@ public class CommonEventHandler {
}
}
// 忘记订阅事件是静态方法了xwx
/**
* On config unloaded.
*

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -23,10 +23,10 @@ import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.r3944realms.superleadrope.compat.CurtainCompat;
import top.r3944realms.superleadrope.compat.WayStoneCompat;
import top.r3944realms.superleadrope.config.LeashCommonConfig;
import top.r3944realms.superleadrope.core.register.SLPEntityTypes;
import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.core.register.*;
import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.util.file.ConfigUtil;
@ -52,8 +52,12 @@ public class SuperLeadRope {
public SuperLeadRope() {
IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();
SLPItems.register(eventBus);
SLPBlocks.register(eventBus);
SLPEntityTypes.register(eventBus);
SLPSoundEvents.register(eventBus);
SLPEffects.register(eventBus);
SLPEnchantments.register(eventBus);
SLPPotions.register(eventBus);
NetworkHandler.register();
initialize();
@ -68,6 +72,8 @@ public class SuperLeadRope {
ConfigUtil.createFile(new String[]{c});
ModLoadingContext modLoadingContext = ModLoadingContext.get();
ConfigUtil.registerConfig(modLoadingContext, ModConfig.Type.COMMON, LeashCommonConfig.SPEC, c, "leash");
WayStoneCompat.init();
CurtainCompat.init();
}
/**

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -18,7 +18,6 @@ package top.r3944realms.superleadrope.api.type.capabilty;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.util.INBTSerializable;
import java.util.Collection;
@ -205,9 +204,16 @@ public interface ILeashData extends INBTSerializable<CompoundTag> {
/**
* Add delayed leash.
*
* @param holderPlayer the holder player
* @param holder the holder player
*/
void addDelayedLeash(Player holderPlayer);
void addDelayedLeash(Entity holder);
/**
* Add delayed leash.
*
* @param holderUUID the holder uuid
*/
void addDelayedLeash(UUID holderUUID);
/**
* Remove delayed leash.
@ -477,7 +483,12 @@ public interface ILeashData extends INBTSerializable<CompoundTag> {
* Apply physics
* ---------------------- */
void applyLeashForces();
/**
* Apply leash forces client player.
*/
void applyLeashForcesClientPlayer();
/**
* Transfer leash boolean.
*

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -24,6 +24,7 @@ import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@ -211,7 +212,7 @@ public interface ILeashHelper {
* @return the boolean
*/
default boolean isHoldingLeash(Entity entity) {
return getAllLeash().stream().anyMatch(i -> i.isLeashedBy(entity));
return getAllLeash().stream().anyMatch(i -> Objects.equals(i.self(), entity));
}
/**
@ -221,17 +222,7 @@ public interface ILeashHelper {
* @return the boolean
*/
default boolean isHoldingLeash(UUID uuid) {
return getAllLeash().stream().anyMatch(i -> i.isLeashedBy(uuid));
}
/**
* 检查是否持有特定实体的拴绳
*
* @param blockPos the block pos
* @return the boolean
*/
default boolean isHoldingLeash(BlockPos blockPos) {
return getAllLeash().stream().anyMatch(i -> i.isLeashedBy(blockPos));
return getAllLeash().stream().anyMatch(i -> Objects.equals(i.self().getUUID(), uuid));
}
/**

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -104,4 +104,11 @@ public interface IWorkSpaceHelper {
* @return the leash state
*/
Optional<ILeashState> getLeashState(@NotNull Entity pEntity);
/**
* Register fake player.
*
* @param classes the classes
*/
void registerFakePlayer(@NotNull Class<?>... classes);
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -15,6 +15,7 @@
package top.r3944realms.superleadrope.api.workspace;
import org.jetbrains.annotations.ApiStatus;
import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import java.util.ServiceLoader;
@ -22,6 +23,7 @@ import java.util.ServiceLoader;
/**
* The type Services.
*/
@ApiStatus.Internal
public class Services {
/**
* The constant WORK_SPACE.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -36,7 +36,7 @@ import top.r3944realms.superleadrope.client.model.geom.SLPModelLayers;
import top.r3944realms.superleadrope.client.renderer.LeashRenderHandler;
import top.r3944realms.superleadrope.client.renderer.SLPShaderRegistry;
import top.r3944realms.superleadrope.client.renderer.entity.SuperLeashKnotRenderer;
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
import top.r3944realms.superleadrope.client.renderer.entity.SuperLeashRopeRenderer;
import top.r3944realms.superleadrope.core.potato.EternalPotatoFacade;
import top.r3944realms.superleadrope.core.register.SLPEntityTypes;
import top.r3944realms.superleadrope.core.register.SLPItems;
@ -69,6 +69,12 @@ public class ClientEventHandler {
}
LeashRenderHandler.onRenderLevelStage(event.getPoseStack(), event.getPartialTick());
}
/**
* On player tick.
*
* @param event the event
*/
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.player instanceof LocalPlayer player && player.equals(Minecraft.getInstance().player)) {
@ -135,6 +141,7 @@ public class ClientEventHandler {
@SubscribeEvent
public static void onRegisterRenderer (EntityRenderersEvent.RegisterRenderers event) {
event.registerEntityRenderer(SLPEntityTypes.SUPER_LEAD_KNOT.get(), SuperLeashKnotRenderer::new);
event.registerEntityRenderer(SLPEntityTypes.SUPER_LEASH_ROPE.get(), SuperLeashRopeRenderer::new);
}
/**

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -175,31 +175,36 @@ public class SuperLeashRenderer {
/**
* The Dx.
*/
public final float dx, /**
public final float dx,
/**
* The Dy.
*/
dy, /**
dy,
/**
* The Dz.
*/
dz; // 绳子差向量
/**
* The X offset.
*/
public final float xOffset, /**
public final float xOffset,
/**
* The Z offset.
*/
zOffset; // 横向偏移
/**
* The Y offset pass 1.
*/
public final float yOffsetPass1, /**
public final float yOffsetPass1,
/**
* The Dy offset pass 1.
*/
dyOffsetPass1; // pass1 纵向偏移
/**
* The Y offset pass 2.
*/
public final float yOffsetPass2, /**
public final float yOffsetPass2,
/**
* The Dy offset pass 2.
*/
dyOffsetPass2; // pass2 纵向偏移

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,123 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.client.renderer.entity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.content.entity.SuperLeashRopeEntity;
import top.r3944realms.superleadrope.core.register.SLPItems;
/**
* The type Super leash rope renderer.
*/
public class SuperLeashRopeRenderer extends EntityRenderer<SuperLeashRopeEntity> {
private static final ResourceLocation TEXTURE = new ResourceLocation(
SuperLeadRope.MOD_ID, "textures/entity/super_lead_knot.png"
);
private final Minecraft minecraft = Minecraft.getInstance();
/**
* Instantiates a new Super leash rope renderer.
*
* @param context the context
*/
public SuperLeashRopeRenderer(EntityRendererProvider.Context context) {
super(context);
}
@Override
public void render(@NotNull SuperLeashRopeEntity entity, float entityYaw, float partialTicks,
@NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer, int packedLight) {
poseStack.pushPose();
// 获取拴绳物品
ItemStack ropeItem = entity.getRopeItem();
if (ropeItem.isEmpty()) {
ropeItem = new ItemStack(SLPItems.SUPER_LEAD_ROPE.get());
}
// 获取旋转角度从实体数据
float rotation = entity.getRotation();
float rotationRadians = (float) Math.toRadians(rotation);
// 获取实体的俯仰和偏航
float yRot = Mth.lerp(partialTicks, entity.yRotO, entity.getYRot());
float xRot = Mth.lerp(partialTicks, entity.xRotO, entity.getXRot());
// 计算摆动的物理效果
float swingAmount = 0.0f;
if (!entity.isReturning() && !entity.hasTarget()) {
// 飞行动画的摆动
swingAmount = (float) Math.sin((entity.tickCount + partialTicks) * 0.3f) * 15.0f;
}
// 应用旋转和位置变换
poseStack.translate(0.0D, 0.1D, 0.0D);
// 应用偏航旋转左右
poseStack.mulPose(Axis.YP.rotationDegrees(-yRot));
// 应用俯仰旋转上下
poseStack.mulPose(Axis.XP.rotationDegrees(xRot));
// 应用自旋转
poseStack.mulPose(Axis.YP.rotation(rotationRadians));
// 应用摆动效果
if (swingAmount != 0) {
poseStack.mulPose(Axis.ZP.rotationDegrees(swingAmount));
}
// 调整大小
float scale = 1.2f; // 稍微放大以更清晰可见
poseStack.scale(scale, scale, scale);
// 渲染物品
this.minecraft.getItemRenderer().renderStatic(
ropeItem,
ItemDisplayContext.GROUND,
packedLight,
OverlayTexture.NO_OVERLAY,
poseStack,
buffer,
entity.level(),
entity.getId()
);
poseStack.popPose();
super.render(entity, entityYaw, partialTicks, poseStack, buffer, packedLight);
}
@Override
public @NotNull ResourceLocation getTextureLocation(@NotNull SuperLeashRopeEntity entity) {
return TEXTURE;
}
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -23,18 +23,17 @@ import net.minecraftforge.fml.ModList;
* The type Curtain compat.
*/
public class CurtainCompat{
/**
* The constant isModLoaded.
*/
public final static boolean isModLoaded = ModList.get().isLoaded("curtain");
/**
* Is not fake player boolean.
*
* @param player the player
* @return the boolean
* Init.
*/
public static boolean isNotFakePlayer(Player player) {
public static void init() {
if (isModLoaded) {
return !(player instanceof EntityPlayerMPFake);
FakePlayerJudge.registersFakePlayer(EntityPlayerMPFake.class);
}
return true;
}
}

View File

@ -0,0 +1,60 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.compat;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* The type Fake player judge.
*/
public class FakePlayerJudge {
private final static Set<Class<?>> fakePlayerClasses = new HashSet<>();
private static void check(final @NotNull Class<?> fakePlayerClass) throws IllegalArgumentException {
if(fakePlayerClass.equals(Player.class) || fakePlayerClass.equals(ServerPlayer.class))
throw new IllegalArgumentException("Player or ServerPlayer class cannot be used as FakePlayer");
}
/**
* Registers fake player.
*
* @param fakePlayerClass the fake player class
*/
public static void registersFakePlayer(final Class<?> @NotNull ...fakePlayerClass) {
for (Class<?> playerClass : fakePlayerClass) {
check(playerClass);
}
fakePlayerClasses.addAll(List.of(fakePlayerClass));
}
/**
* Is fake player boolean.
*
* @param entity the entity
* @return the boolean
*/
public static boolean isNotFakePlayer(@NotNull Entity entity) {
if (!(entity instanceof Player)) return true;
return !fakePlayerClasses.contains(entity.getClass());
}
}

View File

@ -1,8 +1,26 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.compat;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.LuckPermsProvider;
import net.luckperms.api.context.*;
import net.luckperms.api.context.ContextCalculator;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.node.Node;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
@ -14,14 +32,42 @@ import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.Objects;
/**
* The type Luck perms compat.
*/
public class LuckPermsCompat {
/**
* The constant isModLoaded.
*/
public final static boolean isModLoaded = ModList.get().isLoaded("luckperms");
/**
* The constant instance.
*/
public static volatile ILPC instance;
/**
* The interface Ilpc.
*/
public interface ILPC {
/**
* Init.
*/
void init();
/**
* Is leashed bypass boolean.
*
* @param player the player
* @return the boolean
*/
default boolean isLeashedBypass(Entity player) { return false; }
}
/**
* Gets or create lpc.
*
* @return the or create lpc
*/
@Contract(" -> new")
public static @NotNull ILPC getOrCreateLPC() {
@ -48,6 +94,10 @@ public class LuckPermsCompat {
private boolean isInitialized;
private LuckPerms luckPerms ;
private final Node LeashBypass = Node.builder(SuperLeadRope.MOD_ID + ".leash.bypass").build();
/**
* Instantiates a new Real lpc.
*/
public RealLPC() {
isInitialized = false;
init();
@ -77,6 +127,9 @@ public class LuckPermsCompat {
.orElse(false);
}
/**
* The type Leash calculator.
*/
public static class LeashCalculator implements ContextCalculator<Player> {
@Override
public void calculate(@NotNull Player target, ContextConsumer contextConsumer) {

View File

@ -0,0 +1,184 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.compat;
import com.ibm.icu.impl.Pair;
import net.blay09.mods.waystones.api.WaystoneTeleportEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.ModList;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
import top.r3944realms.superleadrope.api.type.util.ILeashHelper;
import top.r3944realms.superleadrope.api.workspace.Services;
import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities;
import top.r3944realms.superleadrope.core.leash.LeashSyncManager;
import top.r3944realms.superleadrope.core.register.SLPGameruleRegistry;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import top.r3944realms.superleadrope.util.capability.LeashStateInnerAPI;
import top.r3944realms.superleadrope.util.entity.TeleportUtil;
import top.r3944realms.superleadrope.util.model.RidingRelationship;
import top.r3944realms.superleadrope.util.riding.RidingApplier;
import top.r3944realms.superleadrope.util.riding.RidingDismounts;
import top.r3944realms.superleadrope.util.riding.RidingFinder;
import top.r3944realms.superleadrope.util.riding.RidingSaver;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
/**
* The type Way stone compat.
*/
public class WayStoneCompat {
/**
* The constant isModLoaded.
*/
public final static boolean isModLoaded = ModList.get().isLoaded("waystones");
/**
* The constant tempLeashMap.
*/
public final static Map<UUID, Set<Pair<Entity, OriginalState>>> tempLeashMap = new ConcurrentHashMap<>();
/**
* The constant uuidMap.
*/
public final static Map<UUID, UUID> uuidMap = new ConcurrentHashMap<>();
/**
* The type Original state.
*/
public record OriginalState(Pose pose, boolean isSprinting, float yaw, float pitch, Vec3 deltaMovement, LeashInfo leashInfo, RidingRelationship ridingRelationship) {}
/**
* Init.
*/
public static void init() {
if (isModLoaded) {
MinecraftForge.EVENT_BUS.addListener(WayStoneCompat::onWayStoneTeleport$Pre);
MinecraftForge.EVENT_BUS.addListener(WayStoneCompat::onWayStoneTeleport$Post);
}
}
/**
* On way stone teleport pre.
*
* @param event the event
*/
public static void onWayStoneTeleport$Pre(WaystoneTeleportEvent.@NotNull Pre event) {
Entity telEntity = event.getContext().getEntity();
ILeashHelper.IHolder holderHelper = Services.WORK_SPACE.getLeashHelper().getHolderHelper(telEntity);
Set<Entity> allLeashedEntities = holderHelper.getAllLeashedEntities();
if(!SLPGameruleRegistry.getGameruleBoolValue(telEntity.level(), TeleportWithLeashedEntities.ID)) {
holderHelper.getAllLeashedEntities();
return;
}
ServerLevel level = event.getContext().getDestination().getLevel();
Vec3 destination = event.getContext().getDestination().getLocation();
Set<Pair<Entity, OriginalState>> set = new HashSet<>();
for (Entity beLeashedEntity : allLeashedEntities) {
// --- 保存状态快照 ---
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.teleportWithHolder(beLeashedEntity, telEntity, beLeashedEntity.level(), level, beLeashedEntity.position(), destination)))
continue;
Pose originalPose = beLeashedEntity.getPose();
boolean originalIsSprinting = beLeashedEntity.isSprinting();
float originalYaw = beLeashedEntity.getYRot();
float originalPitch = beLeashedEntity.getXRot();
Vec3 originalDeltaMovement = beLeashedEntity.getDeltaMovement();
AtomicReference<LeashInfo> originalLeashInfo = new AtomicReference<>();
LeashDataInnerAPI.getLeashData(beLeashedEntity).ifPresent(data -> {
originalLeashInfo.set(data.getLeashInfo(telEntity).orElse(null));
data.removeLeash(telEntity);
});
// --- 保存骑乘关系可修改列表 ---
RidingRelationship originalRidingRelationship = RidingSaver.save(beLeashedEntity, true);
// --- 解除骑乘 ---
List<Entity> allPassengers = RidingFinder.getEntityFromRidingShip(originalRidingRelationship, level::getEntity);
RidingDismounts.dismountEntities(allPassengers);
set.add(Pair.of(beLeashedEntity, new OriginalState(
originalPose,
originalIsSprinting,
originalYaw,
originalPitch,
originalDeltaMovement,
originalLeashInfo.get(),
originalRidingRelationship
)
)
);
}
tempLeashMap.put(telEntity.getUUID(), set);
}
/**
* On way stone teleport post.
*
* @param event the event
*/
public static void onWayStoneTeleport$Post(WaystoneTeleportEvent.@NotNull Post event) {
Entity telEntity = event.getContext().getEntity();
ServerLevel serverLevel = event.getContext().getDestination().getLevel();
Vec3 destination = event.getContext().getDestination().getLocation();
Set<Pair<Entity, OriginalState>> set = tempLeashMap.get(telEntity.getUUID());
Set<UUID> shouldBeRemoved = new HashSet<>();
if (set != null) {
HashSet<Pair<Entity, OriginalState>> newSet = new HashSet<>();
// --- 传送实体及乘客 ---
for (Pair<Entity, OriginalState> entityPair : set) {
Entity beLeashedEntity = entityPair.first;
Entity newEntity = TeleportUtil.teleportEntity(beLeashedEntity, serverLevel, destination, beLeashedEntity.getDirection());
if (!beLeashedEntity.getUUID().equals(newEntity.getUUID())){
uuidMap.put(beLeashedEntity.getUUID(), newEntity.getUUID());
}
newSet.add(Pair.of(newEntity, entityPair.second));
}
for (Pair<Entity, OriginalState> entityPair : newSet) {
// --- 恢复状态 ---
Entity beLeashedEntity = entityPair.first;
OriginalState originalState = entityPair.second;
LeashStateInnerAPI.getLeashState(beLeashedEntity).ifPresent(LeashSyncManager.State::track);
LeashDataInnerAPI.getLeashData(beLeashedEntity).ifPresent(LeashSyncManager.Data::track);
beLeashedEntity.setDeltaMovement(originalState.deltaMovement);
beLeashedEntity.setPose(originalState.pose);
beLeashedEntity.setSprinting(originalState.isSprinting);
// --- 将holder替换 ---
LeashInfo leashInfo = Optional.ofNullable(originalState.leashInfo)
.orElse(LeashInfo.EMPTY);
if (leashInfo.holderUUIDOpt().isPresent() && uuidMap.containsKey(leashInfo.holderUUIDOpt().get())) {
leashInfo.transferHolder(beLeashedEntity);
shouldBeRemoved.add(leashInfo.holderUUIDOpt().get());
}
LeashDataInnerAPI.LeashOperations.attachWithInfo(beLeashedEntity, telEntity, leashInfo);
// --- 重新应用骑乘关系仅保留白名单根载具 ---
uuidMap.forEach((oldUUID, newUUID) -> {
int andReplaceAll = originalState.ridingRelationship.findAndReplaceAll(oldUUID, newUUID);
if (andReplaceAll != 0) shouldBeRemoved.add(oldUUID);
});
RidingRelationship filteredRelationship = RidingSaver.filterByWhitelistRoot(originalState.ridingRelationship);
RidingApplier.applyRidingRelationship(filteredRelationship, serverLevel::getEntity);
}
shouldBeRemoved.forEach(uuidMap::remove);
tempLeashMap.remove(telEntity.getUUID());
}
}
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -28,6 +28,11 @@ import top.r3944realms.superleadrope.SuperLeadRope;
public class JEIPlugin implements IModPlugin {
private static final ResourceLocation UID = new ResourceLocation(SuperLeadRope.MOD_ID, "jei_plugin");
/**
* Gets plugin uid.
*
* @return the plugin uid
*/
@Override
public @NotNull ResourceLocation getPluginUid() {
return UID;

View File

@ -1,3 +1,18 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.config;
import net.minecraftforge.common.ForgeConfigSpec;
@ -55,6 +70,10 @@ public class LeashCommonConfig {
*/
// Leash settings
public final ForgeConfigSpec.DoubleValue maxLeashLength;
/**
* The Max movement.
*/
public final ForgeConfigSpec.DoubleValue maxMovement;
/**
* The Elastic distance scale.
*/
@ -155,7 +174,9 @@ public class LeashCommonConfig {
maxLeashLength = builder
.comment("Maximum leash distance (in blocks) for any entity")
.defineInRange("maxLeashLength", 6.0, LeashConfigManager.MAX_DISTANCE_MIN_VALUE, LeashConfigManager.MAX_DISTANCE_MAX_VALUE);
maxMovement = builder
.comment("Defines the maximum acceleration in standard coordinate directions (X/Y/Z axes)")
.defineInRange("maxMovement", 2.0, 0.5, Double.MAX_VALUE);
elasticDistanceScale = builder
.comment("Default elastic distance for the Super Lead rope")
.defineInRange("elasticDistanceScale", 1.0, LeashConfigManager.ELASTIC_DISTANCE_MIN_VALUE, LeashConfigManager.ELASTIC_DISTANCE_MAX_VALUE);
@ -200,6 +221,8 @@ public class LeashCommonConfig {
.defineInRange("mobSpringFactor", 0.5, 0.05, 2.0);
builder.pop();
// ===== Leash State Offsets =====
builder.push("LeashStateSettings");
defaultApplyEntityLocationOffset = builder

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -29,7 +29,6 @@ import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.network.toClient.CommonConfigHashInformPacket;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.regex.Matcher;
@ -65,17 +64,23 @@ public class LeashConfigManager {
* 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);
// ========= 缓存 ========
/**
* The constant cacheTag.
*/
// ========= 缓存 ========
public volatile static CompoundTag cacheTag = null;
/**
* The constant cacheHash.
*/
public volatile static int cacheHash = -1;
// ========== 偏移映射 ==========
private final Map<String, double[]> entityHolderMap = new ConcurrentHashMap<>();
private final Map<String, double[]> tagHolderMap = new ConcurrentHashMap<>();
private final Map<String, double[]> modHolderMap = new ConcurrentHashMap<>();
private final Map<String, double[]> entityHolderMap = new TreeMap<>();
private final Map<String, double[]> tagHolderMap = new TreeMap<>();
private final Map<String, double[]> modHolderMap = new TreeMap<>();
private final Map<String, double[]> entityLeashMap = new ConcurrentHashMap<>();
private final Map<String, double[]> tagLeashMap = new ConcurrentHashMap<>();
private final Map<String, double[]> modLeashMap = new ConcurrentHashMap<>();
private final Map<String, double[]> entityLeashMap = new TreeMap<>();
private final Map<String, double[]> tagLeashMap = new TreeMap<>();
private final Map<String, double[]> modLeashMap = new TreeMap<>();
// ========== 缓存配置 ==========
private volatile List<String> teleportWhitelistCache = Collections.emptyList();
@ -88,6 +93,7 @@ public class LeashConfigManager {
private volatile double mobSpringFactor = 0.5;
private volatile double maxLeashLength = 12.0;
private volatile double maxMovement = 100.0;
private volatile double elasticDistanceScale = 1.0;
private volatile double extremeSnapFactor = 2.0;
private volatile double springDampening = 0.7;
@ -103,9 +109,9 @@ public class LeashConfigManager {
// ================== 偏移解析 ==================
private @NotNull @Unmodifiable Map<String, Map<String, double[]>> parseOffsetList(@NotNull List<? extends String> offsetConfigs) {
Map<String, double[]> entityMap = new HashMap<>();
Map<String, double[]> tagMap = new HashMap<>();
Map<String, double[]> modMap = new HashMap<>();
Map<String, double[]> entityMap = new TreeMap<>();
Map<String, double[]> tagMap = new TreeMap<>();
Map<String, double[]> modMap = new TreeMap<>();
for (String config : offsetConfigs) {
Matcher matcher = OFFSET_PATTERN.matcher(config);
@ -222,7 +228,7 @@ public class LeashConfigManager {
* @return the teleport whitelist
*/
// ================== 白名单 ==================
public List<String> getTeleportWhitelist() { return Collections.unmodifiableList(teleportWhitelistCache); }
public List<String> getTeleportWhitelist() { return new ArrayList<>(teleportWhitelistCache); }
/**
* Is entity teleport allowed boolean.
@ -319,6 +325,13 @@ public class LeashConfigManager {
*/
public double getMaxLeashLength() { return maxLeashLength; }
/**
* Gets max movement.
*
* @return the max movement
*/
public double getMaxMovement() { return maxMovement; }
/**
* Gets elastic distance scale.
*
@ -345,7 +358,7 @@ public class LeashConfigManager {
*
* @return the axis elasticity
*/
public List<Double> getAxisElasticity() { return Collections.unmodifiableList(axisElasticity); }
public List<Double> getAxisElasticity() { return new ArrayList<>(axisElasticity); }
/**
* Gets x elasticity.
@ -399,6 +412,7 @@ public class LeashConfigManager {
commandPrefixEnabledCache = LeashCommonConfig.COMMON.enableSLPModCommandPrefix.get();
maxLeashLength = LeashCommonConfig.COMMON.maxLeashLength.get();
maxMovement = LeashCommonConfig.COMMON.maxMovement.get();
elasticDistanceScale = LeashCommonConfig.COMMON.elasticDistanceScale.get();
extremeSnapFactor = LeashCommonConfig.COMMON.extremeSnapFactor.get();
springDampening = LeashCommonConfig.COMMON.springDampening.get();
@ -409,7 +423,7 @@ public class LeashConfigManager {
maxForce = LeashCommonConfig.COMMON.maxForce.get();
playerSpringFactor = LeashCommonConfig.COMMON.playerSpringFactor.get();
mobSpringFactor = LeashCommonConfig.COMMON.mobSpringFactor.get();
cacheHash = calculateConfigHash();
cacheHash = -1;
cacheTag = serializeToNBT();
SuperLeadRope.logger.debug("Configs reloaded: {}", getStats());
} catch (Exception e) {
@ -455,11 +469,18 @@ public class LeashConfigManager {
public static void unloading(LeashConfigManager manager) {
if(manager != null) manager.clear();
}
/**
* 将配置管理器状态序列化为NBT
*
* @return the compound tag
*/
public synchronized CompoundTag serializeToNBT() {
if (cacheHash == calculateConfigHash() && cacheTag != null) return cacheTag;
int currentHash = calculateConfigHash();
if (cacheTag != null && cacheHash == currentHash) {
return cacheTag;
}
CompoundTag tag = new CompoundTag();
// 序列化偏移映射
@ -489,6 +510,7 @@ public class LeashConfigManager {
tag.putDouble("mob_spring_factor", mobSpringFactor);
tag.putDouble("max_leash_length", maxLeashLength);
tag.putDouble("max_movement", maxMovement);
tag.putDouble("elastic_distance_scale", elasticDistanceScale);
tag.putDouble("extreme_snap_factor", extremeSnapFactor);
tag.putDouble("spring_dampening", springDampening);
@ -500,7 +522,7 @@ public class LeashConfigManager {
tag.put("axis_elasticity", elasticityTag);
tag.putInt("max_leashes_per_entity", maxLeashesPerEntity);
cacheHash = calculateConfigHash();
cacheHash = currentHash;
cacheTag = tag;
return tag;
@ -524,6 +546,7 @@ public class LeashConfigManager {
// ========== 更新物理参数 ==========
LeashCommonConfig.COMMON.maxLeashLength.set(maxLeashLength);
LeashCommonConfig.COMMON.maxMovement.set(maxMovement);
LeashCommonConfig.COMMON.elasticDistanceScale.set(elasticDistanceScale);
LeashCommonConfig.COMMON.extremeSnapFactor.set(extremeSnapFactor);
LeashCommonConfig.COMMON.springDampening.set(springDampening);
@ -535,7 +558,6 @@ public class LeashConfigManager {
LeashCommonConfig.COMMON.maxForce.set(maxForce);
LeashCommonConfig.COMMON.playerSpringFactor.set(playerSpringFactor);
LeashCommonConfig.COMMON.mobSpringFactor.set(mobSpringFactor);
}
/**
@ -546,7 +568,7 @@ public class LeashConfigManager {
Map<String, double[]> tagMap,
Map<String, double[]> modMap) {
Map<double[], Set<String>> offsetToTargets = new HashMap<>();
Map<double[], Set<String>> offsetToTargets = new LinkedHashMap<>();
// 收集entity映射
for (Map.Entry<String, double[]> entry : entityMap.entrySet()) {
@ -592,10 +614,15 @@ public class LeashConfigManager {
/**
* 从NBT反序列化配置管理器状态
*
* @param tag the tag
*/
public void deserializeFromNBT(CompoundTag tag) {
if (tag == null || tag.isEmpty()) return;
cacheHash = -1;
cacheTag = null;
// 反序列化偏移映射
if (tag.contains("offsets", Tag.TAG_COMPOUND)) {
CompoundTag offsets = tag.getCompound("offsets");
@ -614,7 +641,7 @@ public class LeashConfigManager {
for (int i = 0; i < whitelistTag.size(); i++) {
whitelist.add(whitelistTag.getString(i));
}
teleportWhitelistCache = Collections.unmodifiableList(whitelist);
teleportWhitelistCache = new ArrayList<>(whitelist);
}
if (tag.contains("command_prefix", Tag.TAG_STRING)) {
@ -641,6 +668,9 @@ public class LeashConfigManager {
if (tag.contains("max_leash_length", Tag.TAG_DOUBLE)) {
maxLeashLength = tag.getDouble("max_leash_length");
}
if (tag.contains("max_movement", Tag.TAG_DOUBLE)) {
maxMovement = tag.getDouble("max_movement");
}
if (tag.contains("elastic_distance_scale", Tag.TAG_DOUBLE)) {
elasticDistanceScale = tag.getDouble("elastic_distance_scale");
}
@ -657,7 +687,7 @@ public class LeashConfigManager {
for (int i = 0; i < elasticityTag.size(); i++) {
elasticity.add(elasticityTag.getDouble(i));
}
axisElasticity = Collections.unmodifiableList(elasticity);
axisElasticity = new ArrayList<>(elasticity);
}
if (tag.contains("max_leashes_per_entity", Tag.TAG_INT)) {
@ -668,6 +698,8 @@ public class LeashConfigManager {
/**
* 计算配置哈希值用于快速比较配置是否变化
*
* @return the int
*/
public int calculateConfigHash() {
// 使用FNV-1a哈希算法
@ -681,10 +713,6 @@ public class LeashConfigManager {
hash = fnv1aHashMap(hash, tagLeashMap);
hash = fnv1aHashMap(hash, modLeashMap);
// 哈希白名单
for (String entry : teleportWhitelistCache) {
hash = fnv1aHashString(hash, entry);
}
// 哈希字符串参数
hash = fnv1aHashString(hash, commandPrefixCache);
@ -696,12 +724,23 @@ public class LeashConfigManager {
hash = fnv1aHashLong(hash, Double.doubleToLongBits(playerSpringFactor));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(mobSpringFactor));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(maxLeashLength));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(maxMovement));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(elasticDistanceScale));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(extremeSnapFactor));
hash = fnv1aHashLong(hash, Double.doubleToLongBits(springDampening));
// 哈希轴弹性列表
for (double value : axisElasticity) {
// 白名单排序后再哈希
List<String> sortedWhitelist = new ArrayList<>(teleportWhitelistCache);
Collections.sort(sortedWhitelist);
for (String entry : sortedWhitelist) {
hash = fnv1aHashString(hash, entry);
}
// 轴弹性列表排序或者保持原序但确保两端一致
List<Double> sortedElasticity = new ArrayList<>(axisElasticity);
Collections.sort(sortedElasticity);
for (double value : sortedElasticity) {
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
}
@ -716,7 +755,7 @@ public class LeashConfigManager {
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键中的冒号问题
String entryKey = entry.getKey();
ListTag offsetList = new ListTag();
for (double value : entry.getValue()) {
offsetList.add(DoubleTag.valueOf(value));
@ -737,12 +776,13 @@ public class LeashConfigManager {
for (int i = 0; i < offsetList.size(); i++) {
offset[i] = offsetList.getDouble(i);
}
map.put(entryKey.replace('_', ':'), offset); // 恢复原始键名
map.put(entryKey, offset);
}
}
}
}
// FNV-1a哈希辅助方法
private int fnv1aHashInt(int hash, int value) {
hash ^= (value & 0xFF);
@ -770,7 +810,8 @@ public class LeashConfigManager {
}
private int fnv1aHashMap(int hash, @NotNull Map<String, double[]> map) {
for (Map.Entry<String, double[]> entry : map.entrySet()) {
Map<String, double[]> sortedMap = map instanceof TreeMap ? map : new TreeMap<>(map);
for (Map.Entry<String, double[]> entry : sortedMap.entrySet()) {
hash = fnv1aHashString(hash, entry.getKey());
for (double value : entry.getValue()) {
hash = fnv1aHashLong(hash, Double.doubleToLongBits(value));
@ -778,11 +819,16 @@ public class LeashConfigManager {
}
return hash;
}
/**
* Broad hash packet.
*/
public void broadHashPacket() {
if (cacheHash != -1){
NetworkHandler.sendToAllPlayer(new CommonConfigHashInformPacket(cacheHash));
}
}
/**
* Gets stats.
*

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -27,10 +27,10 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
@ -44,10 +44,11 @@ import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
import top.r3944realms.superleadrope.compat.CurtainCompat;
import top.r3944realms.superleadrope.compat.FakePlayerJudge;
import top.r3944realms.superleadrope.compat.LuckPermsCompat;
import top.r3944realms.superleadrope.config.LeashConfigManager;
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.core.register.SLPEffects;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.network.NetworkHandler;
import top.r3944realms.superleadrope.network.toClient.LeashDataSyncPacket;
@ -64,6 +65,7 @@ import java.util.stream.Stream;
/**
* 预期行为
* <pre>
* <table border="1">
* <thead>
* <tr>
@ -90,6 +92,7 @@ import java.util.stream.Stream;
* </tr>
* </tbody>
* </table>
* </pre>
*/
@SuppressWarnings("DuplicatedCode")
public class LeashDataImpl implements ILeashData {
@ -341,10 +344,16 @@ public class LeashDataImpl implements ILeashData {
}
@Override
public void addDelayedLeash(@NotNull Player holderPlayer) {
delayedHolders.add(holderPlayer.getUUID());
public void addDelayedLeash(@NotNull Entity holder) {
delayedHolders.add(holder.getUUID());
}
@Override
public void addDelayedLeash(@NotNull UUID holderUUID) {
delayedHolders.add(holderUUID);
}
@Override
public void removeDelayedLeash(UUID onceHolderUUID) {
delayedHolders.remove(onceHolderUUID);
@ -776,7 +785,7 @@ public class LeashDataImpl implements ILeashData {
}
@Override
public void applyLeashForcesClientPlayer() {
if (entity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player)) return;
if (entity instanceof ServerPlayer player && FakePlayerJudge.isNotFakePlayer(player)) return;
Vec3 combinedForce = Vec3.ZERO;
Vec3 combinedDirection = Vec3.ZERO;
Map<Integer, LeashInfo> result = leashHolders.entrySet().stream()
@ -808,6 +817,29 @@ public class LeashDataImpl implements ILeashData {
}
}
/**
* Limit movement vec 3.
*
* @param movement the movement
* @return the vec 3
*/
public Vec3 limitMovement(@NotNull Vec3 movement) {
double maxMovement = CommonEventHandler.leashConfigManager.getMaxMovement();
return new Vec3(
clamp(movement.x, maxMovement),
clamp(movement.y, maxMovement),
clamp(movement.z, maxMovement)
);
}
private double clamp(double value, double max) {
if (value > 0) {
return Math.min(value, max);
} else {
return Math.max(value, -max);
}
}
/**
* 计算拴绳拉力防抖动逻辑
*/
@ -838,23 +870,26 @@ public class LeashDataImpl implements ILeashData {
vaildLeashKnots.put(entry.getKey(), entry.getValue());
}
}
if (validLeashes > 0 ) { //重置摔落伤害
entity.resetFallDistance();
}
boolean hasForce = !combinedForce.equals(Vec3.ZERO);
Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce);
if (targetEntity != null && hasForce) {
combinedForce = limitMovement(combinedForce);
SuperLeadRopeEvent.hasFocus hasFocus = new SuperLeadRopeEvent.hasFocus(this.entity, targetEntity, combinedForce, vaildLeashHolders, vaildLeashKnots);
if (MinecraftForge.EVENT_BUS.post(hasFocus)) return;
combinedForce = hasFocus.getCombinedForce();
// 玩家与普通实体统一力应用
if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player) ) {
if (targetEntity instanceof ServerPlayer player && FakePlayerJudge.isNotFakePlayer(player)) {
// 是真实玩家则交给客户端自行处理拴绳逻辑
// DO NOTHING
if(targetEntity != entity){
NetworkHandler.sendToPlayer(new UpdatePlayerMovementPacket(UpdatePlayerMovementPacket.Operation.ADD, combinedForce), player);
if(targetEntity == entity) {
NetworkHandler.sendToPlayer(new UpdatePlayerMovementPacket(UpdatePlayerMovementPacket.Operation.ADD, limitMovement(combinedForce)), player);
}
return;
} else {
applyForceToNonPlayerEntity(targetEntity, combinedForce, validLeashes, combinedDirection);
applyForceToNonPlayerEntity(targetEntity, limitMovement(combinedForce), validLeashes, combinedDirection);
}
}
@ -869,7 +904,6 @@ public class LeashDataImpl implements ILeashData {
// 直接施加合力不再加阻力
entity.setDeltaMovement(entity.getDeltaMovement().add(combinedForce));
entity.hurtMarked = true;
// 如果是生物处理导航
if (entity instanceof Mob mob) {
if(mob.tickCount % 5 == 0){
@ -1030,8 +1064,6 @@ public class LeashDataImpl implements ILeashData {
return null;
}
// 2. 正常弹性拉力逻辑
Vec3 pullForce = Vec3.ZERO;
if (distance > elasticLimitDistance) {
@ -1101,8 +1133,7 @@ public class LeashDataImpl implements ILeashData {
// 计算超出临界距离的比例
double criticalExcessRatio = (distance - extremeSnapDistance) / extremeSnapDistance;
// 在临界状态下使用更强的拉力
double pullStrength = 2.0 + criticalExcessRatio * 3.0; // 从2.0开始随超出比例增加
double pullStrength = Math.max(criticalExcessRatio * 0.1, 1.0);
double excessDistance = distance - elasticLimitDistance;
Vec3 pullForce = pullDirection.scale(
@ -1536,7 +1567,15 @@ public class LeashDataImpl implements ILeashData {
CompoundTag infoTag = holdersList.getCompound(i);
if (infoTag.contains("HolderUUID")) {
LeashInfo uuidLeashDataFormListTag = getUUIDLeashDataFormListTag(infoTag);
leashHolders.put(uuidLeashDataFormListTag.holderUUIDOpt().orElseThrow(), uuidLeashDataFormListTag);
Level level = entity.level();
UUID key = uuidLeashDataFormListTag.holderUUIDOpt().orElseThrow();
if (level instanceof ServerLevel serverLevel ) {
Entity holder = serverLevel.getEntity(key);
if (holder == null) {
addDelayedLeash(key);
}
}
leashHolders.put(key, uuidLeashDataFormListTag);
} else {
LeashInfo blockPosLeashDataFormListTag = getBlockPosLeashDataFormListTag(infoTag);
leashKnots.put(blockPosLeashDataFormListTag.blockPosOpt().orElseThrow(), blockPosLeashDataFormListTag);
@ -1621,7 +1660,10 @@ public class LeashDataImpl implements ILeashData {
@Override
public boolean canBeLeashed() {
return (leashHolders.size() + leashKnots.size()) <= CommonEventHandler.leashConfigManager.getMaxLeashesPerEntity();
if ((leashHolders.size() + leashKnots.size()) <= CommonEventHandler.leashConfigManager.getMaxLeashesPerEntity()) {
return !(entity instanceof LivingEntity living) || !living.hasEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get());
}
return false;
}
@Override

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -73,8 +73,17 @@ public class Command {
* The constant MAX_SHOW_NUMBER.
*/
public static final int MAX_SHOW_NUMBER = 4;
/**
* The constant END.
*/
public static final String END = BASE_ + "end";
/**
* The constant NONE.
*/
public static final String NONE = BASE_ + "none";
/**
* The constant STATE.
*/
public static final String STATE = BASE_ + "state";
/**
* The constant SLP_LEASH_MESSAGE_.
@ -89,6 +98,7 @@ public class Command {
* The constant ALL_HOLDERS.
*/
public static final String ALL_HOLDERS = SLP_LEASH_MESSAGE_ + "all_holders";
/**
* Gets slp name.
*

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -45,7 +45,10 @@ import top.r3944realms.superleadrope.content.gamerule.server.CreateSuperLeashKno
import top.r3944realms.superleadrope.core.register.SLPGameruleRegistry;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import static top.r3944realms.superleadrope.content.command.Command.*;
@ -478,7 +481,13 @@ public class LeashDataCommand {
}
}
/**
* The constant RESET_STATIC_MAX_DISTANCE_.
*/
public static final String RESET_STATIC_MAX_DISTANCE_ = SLP_LEASH_MESSAGE_ + "reset.static.max_distance.";
/**
* The constant RESET_STATIC_MAX_DISTANCE_SUC.
*/
public static final String RESET_STATIC_MAX_DISTANCE_SUC = RESET_STATIC_MAX_DISTANCE_ + SUC;
private static int resetStaticMaxDistance(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
Collection<? extends Entity> targets = EntityArgument.getEntities(context, "targets");
@ -501,7 +510,13 @@ public class LeashDataCommand {
return 0;
}
/**
* The constant SET_STATIC_MAX_DISTANCE_.
*/
public static final String SET_STATIC_MAX_DISTANCE_ = SLP_LEASH_MESSAGE_ + "set.static.max_distance.";
/**
* The constant SET_STATIC_MAX_DISTANCE_SUC.
*/
public static final String SET_STATIC_MAX_DISTANCE_SUC = SET_STATIC_MAX_DISTANCE_ + SUC;
private static int setStaticMaxDistance(CommandContext<CommandSourceStack> context, double value) throws CommandSyntaxException {
Collection<? extends Entity> targets = EntityArgument.getEntities(context, "targets");
@ -524,7 +539,13 @@ public class LeashDataCommand {
return 0;
}
/**
* The constant SET_STATIC_ELASTIC_DISTANCE_SCALE_.
*/
public static final String SET_STATIC_ELASTIC_DISTANCE_SCALE_ = SLP_LEASH_MESSAGE_ + "set.static.elastic_distance_scale.";
/**
* The constant SET_STATIC_ELASTIC_DISTANCE_SCALE_SUC.
*/
public static final String SET_STATIC_ELASTIC_DISTANCE_SCALE_SUC = SET_STATIC_ELASTIC_DISTANCE_SCALE_ + SUC;
private static int setStaticElasticDistanceScale(CommandContext<CommandSourceStack> context, double value) throws CommandSyntaxException {
Collection<? extends Entity> targets = EntityArgument.getEntities(context, "targets");
@ -547,7 +568,13 @@ public class LeashDataCommand {
return 0;
}
/**
* The constant RESET_STATIC_ELASTIC_DISTANCE_SCALE_.
*/
public static final String RESET_STATIC_ELASTIC_DISTANCE_SCALE_ = SLP_LEASH_MESSAGE_ + "reset.static.elastic_distance_scale.";
/**
* The constant RESET_STATIC_ELASTIC_DISTANCE_SCALE_SUC.
*/
public static final String RESET_STATIC_ELASTIC_DISTANCE_SCALE_SUC = RESET_STATIC_ELASTIC_DISTANCE_SCALE_ + SUC;
private static int resetStaticElasticDistanceScale(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
Collection<? extends Entity> targets = EntityArgument.getEntities(context, "targets");

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -39,55 +39,140 @@ import java.util.ArrayList;
import java.util.List;
import static top.r3944realms.superleadrope.content.command.Command.*;
import static top.r3944realms.superleadrope.content.command.LeashDataCommand.*;
import static top.r3944realms.superleadrope.content.command.LeashDataCommand.BLOCK;
import static top.r3944realms.superleadrope.content.command.LeashDataCommand.UUID;
/**
* The type Leash state command.
*/
public class LeashStateCommand {
/**
* The constant SLP_LEASH_STATE_MESSAGE_.
*/
public static final String SLP_LEASH_STATE_MESSAGE_ = Command.BASE_ + "leash_state.message.";
/**
* The constant DEFAULT_OFFSET.
*/
public static final String DEFAULT_OFFSET = SLP_LEASH_STATE_MESSAGE_ + "default_offset";
/**
* The constant APPLY_OFFSET.
*/
public static final String APPLY_OFFSET = SLP_LEASH_STATE_MESSAGE_ + "apply_offset";
// ==================== 重置操作消息键 ====================
/**
* The constant RESET_ALL_HOLDER_.
*/
// ==================== 重置操作消息键 ====================
public static final String RESET_ALL_HOLDER_ = SLP_LEASH_STATE_MESSAGE_ + "reset_all_holder.";
/**
* The constant RESET_ALL_HOLDER_SUC.
*/
public static final String RESET_ALL_HOLDER_SUC = RESET_ALL_HOLDER_ + SUC;
/**
* The constant RESET_HOLDER_FOR_.
*/
public static final String RESET_HOLDER_FOR_ = SLP_LEASH_STATE_MESSAGE_ + "reset_holder_for.";
/**
* The constant RESET_HOLDER_FOR_SUC.
*/
public static final String RESET_HOLDER_FOR_SUC = RESET_HOLDER_FOR_ + SUC;
/**
* The constant RESET_HOLDER_FOR_BLOCK_POS_.
*/
public static final String RESET_HOLDER_FOR_BLOCK_POS_ = SLP_LEASH_STATE_MESSAGE_ + "reset_holder_for_block_pos.";
/**
* The constant RESET_HOLDER_FOR_BLOCK_POS_SUC.
*/
public static final String RESET_HOLDER_FOR_BLOCK_POS_SUC = RESET_HOLDER_FOR_BLOCK_POS_ + SUC;
/**
* The constant RESET_APPLY_ENTITY_ALL_.
*/
public static final String RESET_APPLY_ENTITY_ALL_ = SLP_LEASH_STATE_MESSAGE_ + "reset_apply_entity_all.";
/**
* The constant RESET_APPLY_ENTITY_ALL_SUC.
*/
public static final String RESET_APPLY_ENTITY_ALL_SUC = RESET_APPLY_ENTITY_ALL_ + SUC;
// ==================== 设置操作消息键 ====================
/**
* The constant SET_HOLDER_FOR_.
*/
// ==================== 设置操作消息键 ====================
public static final String SET_HOLDER_FOR_ = SLP_LEASH_STATE_MESSAGE_ + "set_holder_for.";
/**
* The constant SET_HOLDER_FOR_SUC.
*/
public static final String SET_HOLDER_FOR_SUC = SET_HOLDER_FOR_ + SUC;
/**
* The constant SET_HOLDER_FOR_BLOCK_POS_.
*/
public static final String SET_HOLDER_FOR_BLOCK_POS_ = SLP_LEASH_STATE_MESSAGE_ + "set_holder_for_block_pos.";
/**
* The constant SET_HOLDER_FOR_BLOCK_POS_SUC.
*/
public static final String SET_HOLDER_FOR_BLOCK_POS_SUC = SET_HOLDER_FOR_BLOCK_POS_ + SUC;
/**
* The constant SET_APPLY_ENTITY_.
*/
public static final String SET_APPLY_ENTITY_ = SLP_LEASH_STATE_MESSAGE_ + "set_apply_entity.";
/**
* The constant SET_APPLY_ENTITY_SUC.
*/
public static final String SET_APPLY_ENTITY_SUC = SET_APPLY_ENTITY_ + SUC;
// ==================== 查询操作消息键 ====================
/**
* The constant QUERY_HAS_STATE_.
*/
// ==================== 查询操作消息键 ====================
public static final String QUERY_HAS_STATE_ = SLP_LEASH_STATE_MESSAGE_ + "query.has_state.";
/**
* The constant QUERY_HAS_STATE_SUC.
*/
public static final String QUERY_HAS_STATE_SUC = QUERY_HAS_STATE_ + SUC;
/**
* The constant GET_ALL_UUID_STATES_.
*/
public static final String GET_ALL_UUID_STATES_ = SLP_LEASH_STATE_MESSAGE_ + "get_all_uuid_states.";
/**
* The constant GET_ALL_UUID_STATES_SUC.
*/
public static final String GET_ALL_UUID_STATES_SUC = GET_ALL_UUID_STATES_ + SUC;
/**
* The constant GET_ALL_BLOCK_POS_STATES_.
*/
public static final String GET_ALL_BLOCK_POS_STATES_ = SLP_LEASH_STATE_MESSAGE_ + "get_all_block_pos_states.";
/**
* The constant GET_ALL_BLOCK_POS_STATES_SUC.
*/
public static final String GET_ALL_BLOCK_POS_STATES_SUC = GET_ALL_BLOCK_POS_STATES_ + SUC;
/**
* The constant GET_APPLY_ENTITY_OFFSET_.
*/
public static final String GET_APPLY_ENTITY_OFFSET_ = SLP_LEASH_STATE_MESSAGE_ + "get_apply_entity_offset.";
/**
* The constant GET_APPLY_ENTITY_OFFSET_SUC.
*/
public static final String GET_APPLY_ENTITY_OFFSET_SUC = GET_APPLY_ENTITY_OFFSET_ + SUC;
/**
* The constant GET_APPLY_ENTITY_OFFSET_NONE.
*/
public static final String GET_APPLY_ENTITY_OFFSET_NONE = GET_APPLY_ENTITY_OFFSET_ + "none";
/**
* The constant GET_DEFAULT_APPLY_ENTITY_OFFSET_.
*/
public static final String GET_DEFAULT_APPLY_ENTITY_OFFSET_ = SLP_LEASH_STATE_MESSAGE_ + "get_default_apply_entity_offset.";
/**
* The constant GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC.
*/
public static final String GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC = GET_DEFAULT_APPLY_ENTITY_OFFSET_ + SUC;
@ -405,6 +490,9 @@ public class LeashStateCommand {
return 1;
}
/**
* The constant GET_ALL_STATES_HEAD.
*/
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) {

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,64 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.content.effect;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.core.register.SLPEffects;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.Optional;
/**
* The type No super leash effect.
*/
public class NoSuperLeashEffect extends MobEffect {
/**
* Instantiates a new No super leash effect.
*
* @param category the category
* @param color the color
*/
public NoSuperLeashEffect(MobEffectCategory category, int color) {
super(category, color);
}
@Override
public void applyEffectTick(@NotNull LivingEntity pLivingEntity, int pAmplifier) {
MobEffectInstance effect = pLivingEntity.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get());
if(effect != null && effect.getDuration() != 0) {
Optional<ILeashData> leashData = LeashDataInnerAPI.getLeashData(pLivingEntity);
if (leashData.isPresent() && leashData.get().hasLeash()) {
LeashDataInnerAPI.LeashOperations.detachAll(pLivingEntity);
pLivingEntity.level().playSound(null,
pLivingEntity.getOnPos(),
SLPSoundEvents.LEAD_UNTIED.get(),
SoundSource.AMBIENT
);
}
}
}
@Override
public boolean isDurationEffectTick(int duration, int amplifier) {
return duration >= 1;
}
}

View File

@ -0,0 +1,56 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.content.enchantment;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
/**
* The type Prisoner curse enchantment.
*/
public class PrisonerCurseEnchantment extends Enchantment {
/**
* Instantiates a new Prisoner curse enchantment.
*
* @param rarity the rarity
* @param category the category
* @param applicableSlots the applicable slots
*/
public PrisonerCurseEnchantment(Rarity rarity, EnchantmentCategory category, EquipmentSlot[] applicableSlots) {
super(rarity, category, applicableSlots);
}
@Override
public boolean isCurse() {
return true;
}
@Override
public boolean isAllowedOnBooks() {
return true;
}
@Override
public boolean isTradeable() {
return true;
}
@Override
public boolean isDiscoverable() {
return true;
}
}

View File

@ -0,0 +1,80 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.content.enchantment;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.content.entity.SuperLeashRopeEntity;
/**
* The type Ring toss enchantment.
*/
public class RingTossEnchantment extends Enchantment {
/**
* Instantiates a new Ring toss enchantment.
*
* @param rarity the rarity
* @param category the category
* @param applicableSlots the applicable slots
*/
public RingTossEnchantment(Rarity rarity, EnchantmentCategory category, EquipmentSlot[] applicableSlots) {
super(rarity, category, applicableSlots);
}
/**
* Work.
*
* @param level the level
* @param entity the entity
* @param stack the stack
* @param chargePower the charge power
* @param enchantmentLevel the enchantment level
*/
public static void work(Level level, @NotNull LivingEntity entity, ItemStack stack, float chargePower, int enchantmentLevel) {
SuperLeashRopeEntity superLeashRopeEntity = new SuperLeashRopeEntity(level, entity, stack);
if (entity instanceof Player player) {
if(!player.isCreative()) {
player.getInventory().removeItem(stack);
} else superLeashRopeEntity.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
superLeashRopeEntity.setLevel(enchantmentLevel);
superLeashRopeEntity.setChargePower(chargePower);
}
superLeashRopeEntity.startThrown();
level.addFreshEntity(superLeashRopeEntity);
}
@Override
public int getMaxLevel() {
return 2;
}
@Override
public boolean isTradeable() {
return true;
}
@Override
public boolean isDiscoverable() {
return true;
}
}

View File

@ -0,0 +1,29 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.content.enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem;
/**
* The type Slp enchantment category.
*/
public class SLPEnchantmentCategory {
/**
* The constant SUPER_LEAD.
*/
public static final EnchantmentCategory SUPER_LEAD = EnchantmentCategory.create("super_lead", item -> item instanceof SuperLeadRopeItem);
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -27,6 +27,7 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
@ -35,9 +36,8 @@ import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem;
import top.r3944realms.superleadrope.core.register.SLPEntityTypes;
import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.Arrays;
@ -267,4 +267,9 @@ public class SuperLeashKnotEntity extends LeashFenceKnotEntity {
}
return InteractionResult.CONSUME;
}
@Override
public ItemStack getPickResult() {
return new ItemStack(SLPItems.SUPER_LEAD_ROPE.get());
}
}

View File

@ -0,0 +1,805 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.content.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockSource;
import net.minecraft.core.Direction;
import net.minecraft.core.dispenser.OptionalDispenseItemBehavior;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.entity.projectile.ProjectileUtil;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem;
import top.r3944realms.superleadrope.core.register.SLPEntityTypes;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import top.r3944realms.superleadrope.util.nbt.NBTReader;
import top.r3944realms.superleadrope.util.nbt.NBTWriter;
import java.util.Objects;
import java.util.UUID;
/**
* The type Super leash rope entity.
*/
public class SuperLeashRopeEntity extends Projectile {
private static final EntityDataAccessor<Integer> DATA_LIFETIME = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> DATA_HAS_TARGET = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Integer> DATA_TARGET_ID = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> DATA_THROWER_ID = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> DATA_RETURNING = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Float> DATA_ROTATION = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.FLOAT);
private static final EntityDataAccessor<Boolean> DATA_IS_SHOOT_BY_DISPENSE = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<BlockPos> DATA_DISPENSE_POS = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.BLOCK_POS);
private static final EntityDataAccessor<Integer> DATA_ENCHANTMENT_LEVEL = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> DATA_HAS_PRISONER_CURSE = SynchedEntityData.defineId(SuperLeashRopeEntity.class, EntityDataSerializers.BOOLEAN);
// 常量
private static final int MAX_LIFETIME = 200; // 10秒寿命
private static final float MAX_RANGE = 24.0F; // 最大射程
private static final float ROPE_SPEED = 0.8F; // 抛掷速度
private static final float RETURN_SPEED = 2.0F; // 返回速度
private static final float ROTATION_SPEED = 20.0F; // 旋转速度
private float chargePower = 0.5F;
// 实体状态
private UUID throwerUUID;
/**
* Gets rope item.
*
* @return the rope item
*/
public ItemStack getRopeItem() {
return ropeItem;
}
/**
* Sets level.
*
* @param level the level
*/
public void setLevel(int level) {
this.entityData.set(DATA_ENCHANTMENT_LEVEL, Math.max(1, level));
}
/**
* Has prisoner curse boolean.
*
* @return the boolean
*/
public boolean hasPrisonerCurse() {
return this.entityData.get(DATA_HAS_PRISONER_CURSE);
}
/**
* Is shoot by dispenser boolean.
*
* @return the boolean
*/
public boolean isShootByDispenser() {
return this.entityData.get(DATA_IS_SHOOT_BY_DISPENSE);
}
/**
* Gets dispenser pos.
*
* @return the dispenser pos
*/
public BlockPos getDispenserPos() {
return this.entityData.get(DATA_DISPENSE_POS);
}
/**
* Gets enchantment level.
*
* @return the enchantment level
*/
public int getEnchantmentLevel() {
return this.entityData.get(DATA_ENCHANTMENT_LEVEL);
}
/**
* Sets charge power.
*
* @param chargePower the charge power
*/
public void setChargePower(float chargePower) {
this.chargePower = chargePower;
}
/**
* Has target boolean.
*
* @return the boolean
*/
public boolean hasTarget() {
return this.entityData.get(DATA_HAS_TARGET);
}
/**
* Is returning boolean.
*
* @return the boolean
*/
public boolean isReturning() {
return this.entityData.get(DATA_RETURNING);
}
/**
* Gets rotation.
*
* @return the rotation
*/
public float getRotation() {
return this.entityData.get(DATA_ROTATION);
}
/**
* The Pickup.
*/
public AbstractArrow.Pickup pickup;
private ItemStack ropeItem = ItemStack.EMPTY;
private Vec3 initialPosition;
private boolean stuckInBlock = false;
private BlockPos stuckBlockPos;
private Direction stuckDirection;
/**
* Instantiates a new Super leash rope entity.
*
* @param entityType the entity type
* @param level the level
*/
public SuperLeashRopeEntity(EntityType<? extends Projectile> entityType, Level level) {
super(entityType, level);
this.pickup = AbstractArrow.Pickup.DISALLOWED;
this.setNoGravity(true);
}
/**
* Instantiates a new Super leash rope entity.
*
* @param level the level
* @param thrower the thrower
* @param itemStack the item stack
*/
public SuperLeashRopeEntity(Level level, LivingEntity thrower, @NotNull ItemStack itemStack) {
this(SLPEntityTypes.SUPER_LEASH_ROPE.get(), level);
this.setNoGravity(true);
this.setThrower(thrower);
this.pickup = AbstractArrow.Pickup.DISALLOWED;
this.throwerUUID = thrower.getUUID();
this.ropeItem = itemStack.copy();
this.initialPosition = thrower.position();
this.entityData.set(DATA_HAS_PRISONER_CURSE, SuperLeadRopeItem.hasPrisonerCurse(itemStack));
}
/**
* Instantiates a new Super leash rope entity.
*
* @param level the level
* @param dispenserPos the dispenser pos
* @param itemStack the item stack
*/
public SuperLeashRopeEntity(Level level, BlockPos dispenserPos, @NotNull ItemStack itemStack) {
this(SLPEntityTypes.SUPER_LEASH_ROPE.get(), level);
this.setNoGravity(true);
this.pickup = AbstractArrow.Pickup.DISALLOWED;
this.throwerUUID = null;
this.ropeItem = itemStack.copy();
this.initialPosition = null;
this.entityData.set(DATA_IS_SHOOT_BY_DISPENSE, true);
this.entityData.set(DATA_DISPENSE_POS, dispenserPos);
this.entityData.set(DATA_HAS_PRISONER_CURSE, SuperLeadRopeItem.hasPrisonerCurse(itemStack));
}
/**
* Start thrown.
*/
public void startThrown() {
if (isShootByDispenser()) {
BlockPos pos = getDispenserPos();
if (pos != null) {
BlockState state = level().getBlockState(pos);
// 检查是否是发射器
if (state.getBlock() instanceof DispenserBlock) {
// 获取发射方向
Direction direction = state.getValue(DispenserBlock.FACING);
// 设置发射器前方的位置
double spawnX = pos.getX() + 0.5 + direction.getStepX() * 0.7;
double spawnY = pos.getY() + 0.5 + direction.getStepY() * 0.7;
double spawnZ = pos.getZ() + 0.5 + direction.getStepZ() * 0.7;
this.setPos(spawnX, spawnY, spawnZ);
// 计算发射方向和速度
Vec3 shootDirection = new Vec3(
direction.getStepX(),
direction.getStepY(),
direction.getStepZ()
).normalize();
// 使用发射器的默认速度
float dispenserSpeed = 1.5F;
this.setDeltaMovement(
shootDirection.x * dispenserSpeed,
shootDirection.y * dispenserSpeed,
shootDirection.z * dispenserSpeed
);
// 设置实体朝向
if (direction.getStepY() == 0) {
// 水平方向
float yaw = -direction.toYRot();
this.setYRot(yaw);
this.setXRot(0.0F);
} else {
// 垂直方向
this.setYRot(0.0F);
this.setXRot(direction == Direction.UP ? -90.0F : 90.0F);
}
// 播放发射器音效
level().playSound(null, pos, SoundEvents.DISPENSER_LAUNCH,
SoundSource.BLOCKS, 1.0F, 1.0F);
}
}
} else {
Entity thrower = getThrower();
if (thrower != null && tickCount == 0) {
// 设置初始位置和旋转
this.setPos(thrower.getX(), thrower.getEyeY() - 0.1, thrower.getZ());
this.setYRot(thrower.getYRot());
this.setXRot(thrower.getXRot());
// 设置初始速度
Vec3 look = thrower.getLookAngle();
this.setDeltaMovement(look.x * ROPE_SPEED * chargePower, look.y * ROPE_SPEED * chargePower, look.z * ROPE_SPEED * chargePower);
if (hasPrisonerCurse()) {
LeashDataInnerAPI.LeashOperations.attach(thrower, this, 10d, 1.0d, 200);
}
}
}
}
/**
* Gets thrower.
*
* @return the thrower
*/
@Nullable
public Entity getThrower() {
if (this.throwerUUID != null && this.level() instanceof ServerLevel) {
return ((ServerLevel) this.level()).getEntity(this.throwerUUID);
}
int throwerId = this.entityData.get(DATA_THROWER_ID);
if (throwerId != -1) {
return this.level().getEntity(throwerId);
}
return null;
}
/**
* Sets thrower.
*
* @param thrower the thrower
*/
public void setThrower(@NotNull Entity thrower) {
this.throwerUUID = thrower.getUUID();
this.entityData.set(DATA_THROWER_ID, thrower.getId());
}
@Override
public void tick() {
super.tick();
// 更新生命周期
int lifetime = this.entityData.get(DATA_LIFETIME);
this.entityData.set(DATA_LIFETIME, lifetime + 1);
// 更新旋转
float rotation = this.entityData.get(DATA_ROTATION);
this.entityData.set(DATA_ROTATION, (rotation + ROTATION_SPEED) % 360.0F);
// 检查是否过期
if (lifetime >= MAX_LIFETIME) {
returnToThrower();
return;
}
// 检查距离限制
if (!hasPrisonerCurse() && this.initialPosition != null && this.position().distanceTo(this.initialPosition) > MAX_RANGE * getEnchantmentLevel() * chargePower) {
this.startReturning();
} else if (isShootByDispenser() && this.position().distanceTo(getDispenserPos().getCenter()) > MAX_RANGE * getEnchantmentLevel() * 0.5) {
this.startReturning();
} else if (hasPrisonerCurse() && lifetime == MAX_LIFETIME / 2) {
this.startReturning();
}
// 处理不同状态
if (this.entityData.get(DATA_RETURNING)) {
this.tickReturning();
} else if (this.stuckInBlock) {
this.tickStuck();
} else {
this.tickFlying();
}
// 移动实体
this.move(MoverType.SELF, this.getDeltaMovement());
// 更新位置到客户端
if (!this.level().isClientSide) {
this.checkCollisions();
}
}
private void tickFlying() {
// 应用空气阻力
Vec3 deltaMovement = this.getDeltaMovement();
this.setDeltaMovement(deltaMovement.multiply(0.99, 0.99, 0.99));
if (hasPrisonerCurse()) {
this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.03D, 0.0D));
}
// 检查是否击中实体
if (!this.level().isClientSide) {
this.checkEntityCollisions();
}
}
private void tickReturning() {
if (isShootByDispenser()) {
BlockPos dispenser = this.getDispenserPos();
// 计算返回方向
Vec3 toDispenser = dispenser.getCenter()
.subtract(this.position());
if (toDispenser.length() < 1.0) {
// 到达发射器者位置回收绳索
this.returnToThrower();
return;
}
// 归一化并设置速度
Vec3 direction = toDispenser.normalize();
this.setDeltaMovement(direction.scale(RETURN_SPEED));
} else {
Entity thrower = this.getThrower();
if (thrower == null) {
this.discard();
return;
}
// 计算返回方向
Vec3 toThrower = thrower.position().add(0, thrower.getEyeHeight() * 0.5, 0)
.subtract(this.position());
if (toThrower.length() < 1.0) {
// 到达投掷者位置回收绳索
this.returnToThrower();
return;
}
// 归一化并设置速度
Vec3 direction = toThrower.normalize();
this.setDeltaMovement(direction.scale(RETURN_SPEED));
}
// 如果有目标一起拉回来
if (!hasTarget()) {
if (!this.level().isClientSide) {
this.checkEntityCollisions();
}
}
}
private void tickStuck() {
// 检查是否仍然卡在方块中
if (this.stuckBlockPos != null && !this.level().isEmptyBlock(this.stuckBlockPos)) {
// 保持位置
BlockPos pos = this.stuckBlockPos;
this.setPos(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
} else {
// 方块被破坏开始返回
this.stuckInBlock = false;
this.startReturning(true);
}
}
private void startReturning(boolean force) {
if (isReturning() || (!force && (hasPrisonerCurse() && this.entityData.get(DATA_LIFETIME) < MAX_LIFETIME / 2))) {
return;
}
this.entityData.set(DATA_RETURNING, true);
this.stuckInBlock = false;
}
private void startReturning() {
this.startReturning(false);
}
private void returnToThrower() {
if (isShootByDispenser()) {
BlockPos pos = getDispenserPos();
if (level().getBlockEntity(pos) instanceof DispenserBlockEntity dispenserBlockEntity) {
dispenserBlockEntity.addItem(this.ropeItem);
if(hasTarget() && getTarget() != null)
LeashDataInnerAPI.LeashOperations.detach(getTarget(), this);
} else {
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), this.ropeItem);
level().addFreshEntity(itemEntity);
}
} else {
Entity thrower = this.getThrower();
if(hasPrisonerCurse() && thrower != null) {
LeashDataInnerAPI.LeashOperations.detach(thrower, this);
}
if (thrower instanceof Player player) {
// 如果是玩家尝试将绳索物品还给他们
if (pickup != AbstractArrow.Pickup.CREATIVE_ONLY) {
if (!player.getInventory().add(this.ropeItem)) {
// 如果背包满了掉落物品
player.drop(this.ropeItem, false);
} else this.level().playSound(null, thrower.getX(), thrower.getY(), thrower.getZ(),
SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.5F, 1.0F);
}
// 如果套住了实体将其拉近
if (hasTarget() && !hasPrisonerCurse()) {
Entity target = this.getTarget();
if (target != null) {
// 将目标传送到玩家附近
Vec3 pullPosition = thrower.position()
.add(thrower.getLookAngle().scale(2.0))
.add(0, 1.0, 0);
target.teleportTo(pullPosition.x, pullPosition.y, pullPosition.z);
LeashDataInnerAPI.TransferOperations.transfer(target, this, thrower);
// 播放拉回声音
this.level().playSound(null, thrower.getX(), thrower.getY(), thrower.getZ(),
SoundEvents.LEASH_KNOT_BREAK, SoundSource.PLAYERS, 1.0F, 1.0F);
}
}
} else {
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), this.ropeItem);
level().addFreshEntity(itemEntity);
}
}
// 销毁实体
this.discard();
}
private void checkEntityCollisions() {
// 获取抛掷者
Entity thrower = this.getThrower();
if (!isShootByDispenser() && thrower == null) return;
// 检查与实体的碰撞
Vec3 start = this.position();
Vec3 end = start.add(this.getDeltaMovement());
EntityHitResult entityHitResult = ProjectileUtil.getEntityHitResult(
this.level(),
this,
start,
end,
this.getBoundingBox().expandTowards(this.getDeltaMovement()).inflate(1.0),
entity -> !entity.isSpectator() && entity.isPickable() && (isShootByDispenser() || entity != thrower)
);
if (entityHitResult != null) {
this.onHitEntity(entityHitResult);
}
}
private void checkCollisions() {
// 使用射线检测检查碰撞
Vec3 start = this.position();
Vec3 end = start.add(this.getDeltaMovement());
HitResult hitResult = this.level().clip(new ClipContext(
start, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this
));
if (hitResult.getType() != HitResult.Type.MISS) {
this.onHit(hitResult);
}
}
/**
* Gets target.
*
* @return the target
*/
@Nullable
public Entity getTarget() {
if (!hasTarget()) {
return null;
}
int targetId = this.entityData.get(DATA_TARGET_ID);
if (targetId != -1) {
return this.level().getEntity(targetId);
}
return null;
}
@Override
protected void defineSynchedData() {
this.entityData.define(DATA_LIFETIME, 0);
this.entityData.define(DATA_HAS_TARGET, false);
this.entityData.define(DATA_TARGET_ID, -1);
this.entityData.define(DATA_THROWER_ID, -1);
this.entityData.define(DATA_RETURNING, false);
this.entityData.define(DATA_ROTATION, 0.0F);
this.entityData.define(DATA_IS_SHOOT_BY_DISPENSE, false);
this.entityData.define(DATA_DISPENSE_POS, BlockPos.ZERO);
this.entityData.define(DATA_ENCHANTMENT_LEVEL, 1);
this.entityData.define(DATA_HAS_PRISONER_CURSE, false);
}
@Override
protected void addAdditionalSaveData(@NotNull CompoundTag compound) {
super.addAdditionalSaveData(compound);
compound.putInt("Lifetime", this.entityData.get(DATA_LIFETIME));
compound.putBoolean("HasTarget", this.entityData.get(DATA_HAS_TARGET));
compound.putBoolean("Returning", this.entityData.get(DATA_RETURNING));
compound.putFloat("Rotation", this.entityData.get(DATA_ROTATION));
if (this.throwerUUID != null) {
compound.putUUID("Thrower", this.throwerUUID);
}
if (!this.ropeItem.isEmpty()) {
compound.put("RopeItem", this.ropeItem.save(new CompoundTag()));
}
if (this.initialPosition != null) {
compound.put("InitialPosition", NBTWriter.writeVec3(initialPosition));
}
compound.putBoolean("StuckInBlock", this.stuckInBlock);
if (this.stuckBlockPos != null) {
compound.put("StuckPos", NbtUtils.writeBlockPos(stuckBlockPos));
}
if (this.stuckDirection != null) {
compound.putInt("StuckDirection", this.stuckDirection.get3DDataValue());
}
compound.putInt("EnchantmentLevel", getEnchantmentLevel());
compound.putFloat("ChargePower", this.chargePower);
compound.putBoolean("IsShootByDispenser", isShootByDispenser());
if (isShootByDispenser()) {
compound.put("DispenserPos", NbtUtils.writeBlockPos(this.entityData.get(DATA_DISPENSE_POS)));
}
compound.putBoolean("HasPrisonerCurse", hasPrisonerCurse());
}
@Override
protected void readAdditionalSaveData(@NotNull CompoundTag compound) {
super.readAdditionalSaveData(compound);
this.entityData.set(DATA_LIFETIME, compound.getInt("Lifetime"));
this.entityData.set(DATA_HAS_TARGET, compound.getBoolean("HasTarget"));
this.entityData.set(DATA_RETURNING, compound.getBoolean("Returning"));
this.entityData.set(DATA_ROTATION, compound.getFloat("Rotation"));
this.entityData.set(DATA_HAS_PRISONER_CURSE, compound.getBoolean("HasPrisonerCurse"));
if (compound.hasUUID("Thrower")) {
this.throwerUUID = compound.getUUID("Thrower");
}
if (compound.contains("RopeItem")) {
this.ropeItem = ItemStack.of(compound.getCompound("RopeItem"));
}
if (compound.contains("InitialPosition")) {
this.initialPosition = NBTReader.readVec3(compound.getCompound("InitialPosition"));
}
this.stuckInBlock = compound.getBoolean("StuckInBlock");
if (compound.contains("StuckPos")) {
this.stuckBlockPos = NbtUtils.readBlockPos(compound.getCompound("StuckPos"));
}
if (compound.contains("StuckDirection")) {
this.stuckDirection = Direction.from3DDataValue(compound.getInt("StuckDirection"));
}
if (compound.contains("EnchantmentLevel")) {
this.entityData.set(DATA_ENCHANTMENT_LEVEL, compound.getInt("EnchantmentLevel"));
}
if (compound.contains("ChargePower")) {
this.chargePower = compound.getFloat("ChargePower");
}
if (compound.contains("IsShootByDispenser")) {
this.entityData.set(DATA_IS_SHOOT_BY_DISPENSE, compound.getBoolean("IsShootByDispenser"));
}
if (compound.contains("DispenserPos")) {
this.entityData.set(DATA_DISPENSE_POS, NbtUtils.readBlockPos(compound.getCompound("DispenserPos")));
}
}
@Override
public boolean hurt(@NotNull DamageSource source, float amount) {
this.startReturning();
return false;
}
@Override
protected void onHit(@NotNull HitResult result) {
super.onHit(result);
if (result.getType() == HitResult.Type.BLOCK) {
BlockHitResult blockHit = (BlockHitResult) result;
BlockPos blockPos = blockHit.getBlockPos();
if (SuperLeashKnotEntity.isSupportBlock(this.level().getBlockState(blockPos))) {
Entity thrower = getThrower();
if (!isShootByDispenser() && hasPrisonerCurse() && thrower != null) {
if (LeashDataInnerAPI.LeashOperations. detach(thrower, this)) {
LeashDataInnerAPI.LeashOperations. attach(thrower, SuperLeashKnotEntity.getOrCreateKnot(level(), blockPos));
}
}
if (hasTarget()) {
Entity target = getTarget();
if (target != null) {
if (LeashDataInnerAPI.LeashOperations. detach(target, this)) {
LeashDataInnerAPI.LeashOperations. attach(target, SuperLeashKnotEntity.getOrCreateKnot(level(), blockPos));
}
entityData.set(DATA_HAS_TARGET, false);
entityData.set(DATA_TARGET_ID, -1);
}
}
this.startReturning(true);
return;
}
// 卡在方块中
this.stuckInBlock = true;
this.stuckBlockPos = blockPos;
this.stuckDirection = blockHit.getDirection();
// 停止移动
this.setDeltaMovement(Vec3.ZERO);
// 播放声音
this.level().playSound(null, this.getX(), this.getY(), this.getZ(),
SoundEvents.LEASH_KNOT_PLACE, SoundSource.PLAYERS, 0.5F, 1.0F);
// 一段时间后开始返回
Objects.requireNonNull(this.level().getServer()).execute(() -> {
if (this.isAlive()) {
this.startReturning(true);
}
});
}
}
@Override
protected void onHitEntity(@NotNull EntityHitResult result) {
super.onHitEntity(result);
Entity resultEntity = result.getEntity();
Entity thrower = getThrower();
if (resultEntity instanceof SuperLeashKnotEntity knot && hasTarget() ) {
Entity target = getTarget();
if(target != null) {
if (LeashDataInnerAPI.LeashOperations. detach(target, this)) {
LeashDataInnerAPI.LeashOperations. attach(target, knot);
}
this.entityData.set(DATA_HAS_TARGET, false);
this.entityData.set(DATA_TARGET_ID, -1);
return;
}
return;
}
if ((!isShootByDispenser() && (resultEntity == thrower || LeashDataInnerAPI.QueryOperations.isLeashedBy(resultEntity, thrower))) || !LeashDataInnerAPI.QueryOperations.canBeLeashed(resultEntity)) {
return;
}
if (!isShootByDispenser() && hasPrisonerCurse() && thrower != null) {
if (LeashDataInnerAPI.LeashOperations. detach(thrower, this)) {
LeashDataInnerAPI.LeashOperations. attach(thrower, resultEntity);
}
}
// 套住实体
this.entityData.set(DATA_HAS_TARGET, true);
this.entityData.set(DATA_TARGET_ID, resultEntity.getId());
if (LeashDataInnerAPI.QueryOperations.canBeLeashed(resultEntity)) {
LeashDataInnerAPI.LeashOperations.attach(resultEntity, this, 10d, 1.0d, 200);
}
// 停止移动
this.setDeltaMovement(Vec3.ZERO);
// 播放套住的声音
this.level().playSound(null, this.getX(), this.getY(), this.getZ(),
SoundEvents.LEASH_KNOT_PLACE, SoundSource.PLAYERS, 1.0F, 1.0F);
// 立即开始返回
this.startReturning();
}
@Override
public boolean isPickable() {
return false;
}
@Override
public boolean shouldRender(double x, double y, double z) {
return true;
}
@Override
public @NotNull Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
/**
* The type Super leash rope item behavior.
*/
public static class SuperLeashRopeItemBehavior extends OptionalDispenseItemBehavior {
/**
* The constant INSTANCE.
*/
public static final SuperLeashRopeItemBehavior INSTANCE = new SuperLeashRopeItemBehavior();
@Override
protected @NotNull ItemStack execute(@NotNull BlockSource source, @NotNull ItemStack stack) {
ServerLevel serverLevel = source.getLevel();
int enchantmentLevel = SuperLeadRopeItem.getRingTossEnchantmentLevel(stack);
if (enchantmentLevel > 0) {
stack.hurtAndBreak(10, FakePlayerFactory.getMinecraft(serverLevel), p -> {});
SuperLeashRopeEntity leashRope = new SuperLeashRopeEntity(serverLevel, source.getPos(), stack);
leashRope.setLevel(enchantmentLevel);
leashRope.startThrown();
serverLevel.addFreshEntity(leashRope);
return ItemStack.EMPTY;
} else return stack;
}
}
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -16,15 +16,21 @@
package top.r3944realms.superleadrope.content.item;
import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TieredItem;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
@ -33,11 +39,15 @@ import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.content.SLPToolTier;
import top.r3944realms.superleadrope.content.enchantment.RingTossEnchantment;
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.core.register.SLPEffects;
import top.r3944realms.superleadrope.core.register.SLPEnchantments;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@ -46,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* The type Super lead rope item.
*/
//TODO:
// 1. 可抛掷使用 ***下个版本实现
// 1. 可抛掷使用
// - 可转移拴绳
// 2. 多绑定一个生物可以被多个加强拴绳绑定产生共同作用效果
// 3. 支持更多支撑方块
@ -57,10 +67,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
// 尝试0 mixin 实现 加强拴绳逻辑
public class SuperLeadRopeItem extends TieredItem implements IForgeItem {
// 配置常量
// 手动调节,可以通过附魔获取更远抛掷和抛掷距离 - x1.3//TODO:将可抛掷实现留到下次编写
// 手动调节,可以通过附魔获取更远抛掷和抛掷距离 - x1.3
// 可以做个大于一定距离时远距离使用时抛出拴绳的实体击中生物才栓中的
private static final double SHORT_RANGE = 5.0D;
private static final float THROW_SPEED = 1.5F;
// 蓄力相关常量
private static final int MAX_CHARGE_TIME = 20; // 最大蓄力时间20 ticks = 1秒
private static final float MIN_CHARGE_POWER = 0.5F; // 最小蓄力功率
private static final float MAX_CHARGE_POWER = 2.0F; // 最大蓄力功率
/**
@ -76,18 +90,163 @@ public class SuperLeadRopeItem extends TieredItem implements IForgeItem {
);
}
//通过按键 可抛掷启用/关闭实现不会影响use逻辑
@Override
public int getUseDuration(@NotNull ItemStack stack) {
return getRingTossEnchantmentLevel(stack) > 0 ? 40 : 0;
}
@Override
public @NotNull UseAnim getUseAnimation(@NotNull ItemStack stack) {
return UseAnim.SPEAR; // 使用矛的动画
}
@Override
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, @NotNull Player pPlayer, @NotNull InteractionHand pUsedHand) {
ItemStack lead = pPlayer.getItemInHand(pUsedHand);
if(!pLevel.isClientSide) {
if (canUse(lead)) return InteractionResultHolder.pass(lead);
int enLp = getRingTossEnchantmentLevel(lead);
if (enLp > 0) {
if (!pLevel.isClientSide) {
if (canUse(lead)) {
// 检查是否有抛掷附魔
pPlayer.startUsingItem(pUsedHand);
return InteractionResultHolder.consume(lead);
}
return InteractionResultHolder.pass(lead);
}
// 客户端也返回consume以开始蓄力
if (canUse(lead)) {
pPlayer.startUsingItem(pUsedHand);
return InteractionResultHolder.consume(lead);
}
return super.use(pLevel, pPlayer, pUsedHand);
}
return InteractionResultHolder.success(lead);
}
/**
* Gets ring toss enchantment level.
*
* @param stack the stack
* @return the ring toss enchantment level
*/
public static int getRingTossEnchantmentLevel(ItemStack stack) {
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
if (enchantments.isEmpty()) return -1;
Integer i = enchantments.get(SLPEnchantments.RING_TOSS.get());
return i != null ? i : -1;
}
/**
* Has prisoner curse boolean.
*
* @param stack the stack
* @return the boolean
*/
public static boolean hasPrisonerCurse(ItemStack stack) {
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
if (enchantments.isEmpty()) return false;
Integer i = enchantments.get(SLPEnchantments.SELF_PRISONER.get());
return i != null && i > 0;
}
@Override
public void onUseTick(@NotNull Level level, @NotNull LivingEntity livingEntity, @NotNull ItemStack stack, int remainingUseDuration) {
if (level.isClientSide && livingEntity instanceof Player player) {
// 客户端播放蓄力音效
int useTime = this.getUseDuration(stack) - remainingUseDuration;
// 2ticks播放一次蓄力音效
if (useTime == 2) {
float pitch = 0.8F ;
level.playLocalSound(
player.getX(), player.getY(), player.getZ(),
net.minecraft.sounds.SoundEvents.CROSSBOW_LOADING_MIDDLE,
SoundSource.PLAYERS, 0.5F, pitch, false
);
}
}
}
@Override
public @NotNull ItemStack finishUsingItem(@NotNull ItemStack stack, @NotNull Level level, @NotNull LivingEntity livingEntity) {
if (livingEntity instanceof Player player) {
int ringTossLevel = getRingTossEnchantmentLevel(stack);
if (ringTossLevel > 0) {
if (!level.isClientSide()) {
// 计算蓄力时间和功率
float chargePower = MAX_CHARGE_POWER;
// 消耗耐久
if (!player.isCreative()) {
stack.hurtAndBreak((int) chargePower * 10, player, (p) -> {
p.broadcastBreakEvent(player.getUsedItemHand());
});
}
RingTossEnchantment.work(level, livingEntity, stack, chargePower, ringTossLevel);
} else {
level.playLocalSound(
livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(),
SoundEvents.CROSSBOW_SHOOT,
SoundSource.PLAYERS, 0.5F, 0.8F, false
);
}
}
}
return stack;
}
@Override
public void releaseUsing(@NotNull ItemStack stack, @NotNull Level level, @NotNull LivingEntity livingEntity, int timeCharged) {
if (livingEntity instanceof Player player) {
// 计算实际蓄力时间
int useTime = this.getUseDuration(stack) - timeCharged;
// 如果蓄力时间超过最小阈值抛出拴绳
if (useTime >= 10) { // 至少0.5秒蓄力
int ringTossLevel = getRingTossEnchantmentLevel(stack);
if (ringTossLevel > 0) {
if(!level.isClientSide()){
float chargePower = Math.max(useTime / (float)MAX_CHARGE_TIME, MIN_CHARGE_POWER);
chargePower = Math.min(chargePower, MAX_CHARGE_POWER);
// 消耗耐久
if (!player.isCreative()) {
stack.hurtAndBreak((int) chargePower * 10, player, (p) -> {
p.broadcastBreakEvent(player.getUsedItemHand());
});
}
RingTossEnchantment.work(level, livingEntity, stack, chargePower, ringTossLevel);
} else {
level.playLocalSound(
livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(),
SoundEvents.CROSSBOW_SHOOT,
SoundSource.PLAYERS, 0.5F, 0.8F, false
);
}
}
}
}
}
/**
* 获取当前蓄力进度用于客户端渲染
*
* @param stack the stack
* @param entity the entity
* @return the charge progress
*/
public static float getChargeProgress(ItemStack stack, LivingEntity entity) {
if (entity instanceof Player player) {
if (player.isUsingItem() && player.getUseItem() == stack) {
int useTime = stack.getUseDuration() - player.getTicksUsingItem();
return Math.min(useTime / (float)MAX_CHARGE_TIME, 1.0F);
}
}
return 0.0F;
}
/**
* Can use boolean.
*
@ -104,14 +263,15 @@ public class SuperLeadRopeItem extends TieredItem implements IForgeItem {
BlockPos pos = context.getClickedPos();
BlockState state = level.getBlockState(pos);
ItemStack itemStack = context.getItemInHand();
if (canUse(itemStack)) return InteractionResult.SUCCESS;
if(SuperLeashKnotEntity.isSupportBlock(state)) {
Player player = context.getPlayer();
if(!level.isClientSide && player != null) {
return bindToBlock(player, level, pos, itemStack, false) ? InteractionResult.CONSUME : InteractionResult.SUCCESS;
if (canUse(itemStack)) {
if(SuperLeashKnotEntity.isSupportBlock(state)) {
Player player = context.getPlayer();
if(!level.isClientSide && player != null) {
return bindToBlock(player, level, pos, itemStack, false) ? InteractionResult.CONSUME : InteractionResult.SUCCESS;
}
}
}
return InteractionResult.SUCCESS;
return InteractionResult.SUCCESS;
} else return InteractionResult.PASS;
}
/**
@ -135,7 +295,7 @@ public class SuperLeadRopeItem extends TieredItem implements IForgeItem {
* @param pos 坐标一般是明确持有玩家的位置
* @return 是否成功 boolean
*/
public static boolean bindToEntity(Entity newHolder, Player player, Level level, BlockPos pos) {
public static boolean bindToEntity(Entity newHolder, Player player, Level level, @NotNull BlockPos pos) {
boolean isSuccess = false;
// 查找当前玩家持有的可拴生物
@ -185,7 +345,7 @@ public class SuperLeadRopeItem extends TieredItem implements IForgeItem {
* @param shouldBindSelf 是否应该触发拴自己逻辑检查
* @return 是否成功 boolean
*/
public static boolean bindToBlock(Player player, Level level, BlockPos pos, ItemStack leashStack, boolean shouldBindSelf) {
public static boolean bindToBlock(@NotNull Player player, Level level, @NotNull BlockPos pos, ItemStack leashStack, boolean shouldBindSelf) {
SuperLeashKnotEntity knot = null;
AtomicBoolean isSuccess = new AtomicBoolean(false);
UUID uuid = player.getUUID();
@ -195,6 +355,10 @@ public class SuperLeadRopeItem extends TieredItem implements IForgeItem {
// 情况一拴自己到新 knot
if (shouldBindSelf && list.isEmpty()) {
MobEffectInstance effect = player.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get());
if (effect != null && effect.getDuration() >= 1) {
return false;
}
if (leashStack.isEmpty() || !canUse(leashStack)) {
return false;
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -18,7 +18,6 @@ package top.r3944realms.superleadrope.core.hook;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.Optional;

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -20,7 +20,9 @@ import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
@ -31,6 +33,7 @@ import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl;
import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem;
import top.r3944realms.superleadrope.core.register.SLPEffects;
import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
@ -53,7 +56,6 @@ public class LeashInteractHandler {
//只有玩家可以互动触发其它的暂不支持考虑到0 Mixin)
public static void onEntityRightInteract(Level level, InteractionHand hand, Entity target , Player player, PlayerInteractEvent.EntityInteract event) {
//WARNING: 主手和副手都会触发一次该事件
// ===== 卫语句 =====
if (level.isClientSide) {
if (hand == InteractionHand.MAIN_HAND &&
@ -63,6 +65,12 @@ public class LeashInteractHandler {
event.setCanceled(true);
event.setCancellationResult(InteractionResult.SUCCESS);
}
if (target instanceof LivingEntity livingEntity) { //禁止拴绳效果存在则取消下面的逻辑
MobEffectInstance effect = livingEntity.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get());
if (effect != null && effect.getDuration() >= 1) {
return;
}
}
if (SuperLeadRopeApi.isLeashHolder(target, player)) {
event.setCanceled(true);
event.setCancellationResult(InteractionResult.SUCCESS);
@ -97,6 +105,12 @@ public class LeashInteractHandler {
event.setCancellationResult(InteractionResult.SUCCESS);
}
} else {
if (target instanceof LivingEntity livingEntity) { //禁止拴绳效果存在则取消下面的逻辑
MobEffectInstance effect = livingEntity.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get());
if (effect != null && effect.getDuration() >= 1) {
return;
}
}
if (SuperLeadRopeApi.isLeashHolder(target, player)) {
LeashCap.ifPresent(
iLeashDataCapability -> iLeashDataCapability.removeLeash(player.getUUID())

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,53 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.core.register;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import top.r3944realms.superleadrope.SuperLeadRope;
import java.util.Collection;
/**
* The type Slp blocks.
*/
public class SLPBlocks {
/**
* The constant BLOCKS.
*/
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, SuperLeadRope.MOD_ID);
/**
* Gets entries.
*
* @return the entries
*/
public static Collection<RegistryObject<Block>> getEntries() {
return BLOCKS.getEntries();
}
/**
* Register.
*
* @param eventBus the event bus
*/
public static void register(IEventBus eventBus) {
BLOCKS.register(eventBus);
}
}

View File

@ -0,0 +1,85 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.core.register;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.content.effect.NoSuperLeashEffect;
import java.util.function.Supplier;
/**
* The type Slp effects.
*/
public class SLPEffects {
/**
* The Mob effect.
*/
public static DeferredRegister<MobEffect> MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, SuperLeadRope.MOD_ID);
/**
* The constant NO_SUPER_LEASH_EFFECT.
*/
public static RegistryObject<MobEffect> NO_SUPER_LEASH_EFFECT = register(
"no_super_leash",
() -> new NoSuperLeashEffect(MobEffectCategory.NEUTRAL, 12063764)
);
/**
* Register registry object.
*
* @param <T> the type parameter
* @param name the name
* @param effect the effect
* @return the registry object
*/
public static <T extends MobEffect> RegistryObject<MobEffect> register(String name, Supplier<T> effect) {
return MOB_EFFECT.register(name, effect);
}
/**
* Gets effect key.
*
* @param effect the effect
* @return the effect key
*/
public static String getEffectKey(MobEffect effect) {
return effect.getDescriptionId();
}
/**
* Gets mod effect key.
*
* @param effect the effect
* @return the mod effect key
*/
public static String getModEffectKey(RegistryObject<MobEffect> effect) {
return getEffectKey(effect.get());
}
/**
* Register.
*
* @param eventBus the event bus
*/
public static void register(IEventBus eventBus) {
MOB_EFFECT.register(eventBus);
}
}

View File

@ -0,0 +1,61 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.core.register;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.content.enchantment.PrisonerCurseEnchantment;
import top.r3944realms.superleadrope.content.enchantment.RingTossEnchantment;
import top.r3944realms.superleadrope.content.enchantment.SLPEnchantmentCategory;
/**
* The type Slp enchantments.
*/
public class SLPEnchantments {
/**
* The constant ENCHANTMENTS.
*/
public static final DeferredRegister<Enchantment> ENCHANTMENTS= DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, SuperLeadRope.MOD_ID);
/**
* The constant RING_TOSS.
*/
public static final RegistryObject<Enchantment> RING_TOSS = ENCHANTMENTS.register(
"ring_toss", () -> new RingTossEnchantment(Enchantment.Rarity.COMMON, SLPEnchantmentCategory.SUPER_LEAD, new EquipmentSlot[]{EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND})
);
/**
* The constant SELF_PRISONER.
*/
public static final RegistryObject<Enchantment> SELF_PRISONER = ENCHANTMENTS.register(
"prisoner", () -> new PrisonerCurseEnchantment(Enchantment.Rarity.RARE, SLPEnchantmentCategory.SUPER_LEAD, new EquipmentSlot[]{EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND})
);
/**
* Register.
*
* @param eventBus the event bus
*/
public static void register(IEventBus eventBus) {
ENCHANTMENTS.register(eventBus);
}
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -23,6 +23,7 @@ import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.content.entity.SuperLeashRopeEntity;
/**
* The type Slp entity types.
@ -45,6 +46,16 @@ public class SLPEntityTypes {
.updateInterval(Integer.MAX_VALUE)
.build("super_lead_knot")
);
/**
* The constant SUPER_LEASH_ROPE.
*/
public static final RegistryObject<EntityType<SuperLeashRopeEntity>> SUPER_LEASH_ROPE =
ENTITY_TYPES.register("super_leash_rope", () ->
EntityType.Builder.<SuperLeashRopeEntity>of(SuperLeashRopeEntity::new, MobCategory.MISC)
.sized(0.5F, 0.5F)
.clientTrackingRange(4)
.updateInterval(20)
.build("super_lead_rope"));
/**
* Gets entity name key.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,104 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.core.register;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.brewing.BrewingRecipe;
import net.minecraftforge.common.brewing.BrewingRecipeRegistry;
import net.minecraftforge.registries.RegistryObject;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
/**
* The type Slp potion recipe registry.
*/
public class SLPPotionRecipeRegistry {
/**
* The type Proper brewing recipe.
*/
public static class ProperBrewingRecipe extends BrewingRecipe {
private final Ingredient input;
/**
* Instantiates a new Proper brewing recipe.
*
* @param input the input
* @param ingredient the ingredient
* @param output the output
*/
public ProperBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) {
super(input, ingredient, output);
this.input = input;
}
@Override
public boolean isInput(@NotNull ItemStack stack) {
ItemStack[] matchingStacks = input.getItems();
if (matchingStacks.length == 0) {
return stack.isEmpty();
} else {
for (ItemStack itemstack : matchingStacks) {
if (ItemStack.isSameItem(stack, itemstack) && ItemStack.isSameItemSameTags(itemstack, stack)) {
return true;
}
}
return false;
}
}
}
/**
* Create potion item stack.
*
* @param potion the potion
* @return the item stack
*/
@Contract("_ -> new")
public static @NotNull ItemStack createPotion(@NotNull RegistryObject<Potion> potion){
return PotionUtils.setPotion(new ItemStack(Items.POTION), potion.get());
}
/**
* Create potion item stack.
*
* @param potion the potion
* @return the item stack
*/
@Contract("_ -> new")
public static @NotNull ItemStack createPotion(Potion potion){
return PotionUtils.setPotion(new ItemStack(Items.POTION), potion);
}
/**
* Init.
*/
public static void init() {
BrewingRecipeRegistry.addRecipe(
new ProperBrewingRecipe(Ingredient.of(createPotion(Potions.INVISIBILITY)), Ingredient.of(Items.SLIME_BALL), createPotion(SLPPotions.NO_SUPER_LEASH)));
BrewingRecipeRegistry.addRecipe(
new ProperBrewingRecipe(Ingredient.of(createPotion(Potions.LONG_INVISIBILITY)), Ingredient.of(Items.SLIME_BALL), createPotion(SLPPotions.LONG_NO_SUPER_LEASH)));
BrewingRecipeRegistry.addRecipe(
new ProperBrewingRecipe(Ingredient.of(createPotion(SLPPotions.NO_SUPER_LEASH)), Ingredient.of(Items.REDSTONE), createPotion(SLPPotions.LONG_NO_SUPER_LEASH)));
}
}

View File

@ -0,0 +1,94 @@
/*
* Super Lead rope mod
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.core.register;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
import top.r3944realms.superleadrope.SuperLeadRope;
import java.util.function.Supplier;
/**
* The type Slp potions.
*/
public class SLPPotions {
/**
* The Potions.
*/
public static DeferredRegister<Potion> POTIONS = DeferredRegister.create(Registries.POTION, SuperLeadRope.MOD_ID);
/**
* The constant NO_SUPER_LEASH.
*/
public static final RegistryObject<Potion> NO_SUPER_LEASH = register("no_super_leash",
() -> new Potion("no_super_leash", new MobEffectInstance(SLPEffects.NO_SUPER_LEASH_EFFECT.get(), 1200, 0))
);
/**
* The constant LONG_NO_SUPER_LEASH.
*/
public static final RegistryObject<Potion> LONG_NO_SUPER_LEASH = register("long_no_super_leash",
() -> new Potion("no_super_leash", new MobEffectInstance(SLPEffects.NO_SUPER_LEASH_EFFECT.get(), 3600, 0))
);
/**
* Register registry object.
*
* @param <T> the type parameter
* @param Name the name
* @param supplier the supplier
* @return the registry object
*/
public static <T extends Potion>RegistryObject<Potion> register(String Name, Supplier<T> supplier) {
return POTIONS.register(Name, supplier);
}
/**
* Gets potion name key.
*
* @param name the Name of Potion
* @param type (char)<br/> [ <br/> 0 & 3 ~ 255 : potion <br/>1 : lingering_potion <br/>2 : splash_potion<br/>]
* @return Language Key
*/
public static String getPotionNameKey(String name, char type) {
return "item.minecraft." +
(type == 1 ? "lingering_potion" :
(type == 2 ? "splash_potion" : "potion")
)
+ ".effect." + name;
}
/**
* Gets tipped arrow name key.
*
* @param Name the name
* @return the tipped arrow name key
*/
public static String getTippedArrowNameKey(String Name) {
return "item.minecraft.tipped_arrow.effect." + Name;
}
/**
* Register.
*
* @param eventBus the event bus
*/
public static void register(IEventBus eventBus) {
POTIONS.register(eventBus);
}
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -54,7 +54,9 @@ public class SLPDataGenEvent {
LanguageGenerator(event, LanguageEnum.LiteraryChinese);
RecipeGenerator(event);
ModelDataGenerate(event);
BlockStateGenerate(event);
TagsProvider(event, lookupProvider);
LootTableGenerate(event);
SoundProvider(event);
}
private static void LanguageGenerator(GatherDataEvent event, LanguageEnum language) {
@ -97,4 +99,16 @@ public class SLPDataGenEvent {
(DataProvider.Factory<SLPItemModelProvider>) pOutput -> new SLPItemModelProvider(pOutput, event.getExistingFileHelper())
);
}
private static void LootTableGenerate(GatherDataEvent event) {
event.getGenerator().addProvider(
event.includeClient(),
(DataProvider.Factory<SLPLootTableProvider>) SLPLootTableProvider::new
);
}
private static void BlockStateGenerate(GatherDataEvent event) {
event.getGenerator().addProvider(
event.includeClient(),
(DataProvider.Factory<SLPBlockStateGenerator>) pOutput -> new SLPBlockStateGenerator(pOutput, event.getExistingFileHelper())
);
}
}

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,13 +1,13 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* Copyright (C) 2026 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
@ -25,9 +25,7 @@ import top.r3944realms.superleadrope.content.command.MotionCommand;
import top.r3944realms.superleadrope.content.gamerule.server.CreateSuperLeashKnotEntityIfAbsent;
import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities;
import top.r3944realms.superleadrope.content.item.EternalPotatoItem;
import top.r3944realms.superleadrope.core.register.SLPEntityTypes;
import top.r3944realms.superleadrope.core.register.SLPItems;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.core.register.*;
import top.r3944realms.superleadrope.util.lang.LanguageEnum;
import top.r3944realms.superleadrope.util.lang.ModPartEnum;
@ -280,6 +278,52 @@ public enum SLPLangKeyValue {
SLPEntityTypes.getEntityNameKey("super_lead_knot"), ModPartEnum.ENTITY,
"Super Lead Knot", "超级拴绳结", "超級拴繩結", "神駒羈縻索結"
),
/**
* The Entity super leash rope.
*/
ENTITY_SUPER_LEASH_ROPE(
SLPEntityTypes.getEntityNameKey("super_leash_rope"), ModPartEnum.ENTITY,
"Super Lead Rope", "超级拴绳", "超級拴繩", "神駒羈縻索"
),
/**
* The Ring ross.
*/
RING_ROSS(
SLPEnchantments.RING_TOSS.get().getDescriptionId(), ModPartEnum.ENCHANTMENT,
"Ring Toss", "套圈", "套圈", "套圈"
),
/**
* The Ring ross desc.
*/
RING_ROSS_DESC(
SLPEnchantments.RING_TOSS.get().getDescriptionId() + ".desc", ModPartEnum.ENCHANTMENT,
"Throw the lead to lasso creatures. Higher levels increase throwing distance and reduce required charge time",
"可以将拴绳丢出去套中生物,等级越高丢出去的距离越远,所需蓄力时间越短",
"可以將拴繩丟出去套中生物,等級越高丟出去的距離越遠,所需蓄力時間越短",
"擲繩套獸,階愈高,擲愈遠,蓄愈短"
),
/**
* The Prisoner.
*/
PRISONER(
SLPEnchantments.SELF_PRISONER.get().getDescriptionId(), ModPartEnum.ENCHANTMENT,
"Self Prisoner", "自拴", "自拴", "自拴"
),
/**
* The Prisoner desc.
*/
PRISONER_DESC(
SLPEnchantments.SELF_PRISONER.get().getDescriptionId() + ".desc", ModPartEnum.ENCHANTMENT,
"Throw the lead to lasso yourself. Requires Ring Toss enchantment to take effect. Higher levels increase throwing distance",
"可以将拴绳丢出去套中自己。需要套圈附魔才能生效。等级越高丢出去的距离越远",
"可以將拴繩丟出去套中自己。需要套圈附魔才能生效。等級越高丟出去的距離越遠",
"擲繩,需套圈附魔方效。階愈高,擲愈遠"
),
/**
* The Teleport with leashed entities name.
*/
@ -350,7 +394,10 @@ 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"
),
// ==================== 重置操作消息 ====================
/**
* The Message state reset all holder suc.
*/
// ==================== 重置操作消息 ====================
MESSAGE_STATE_RESET_ALL_HOLDER_SUC(
LeashStateCommand.RESET_ALL_HOLDER_SUC, ModPartEnum.COMMAND,
"Successfully reset all holders for %s",
@ -359,6 +406,9 @@ public enum SLPLangKeyValue {
"%s之諸持者狀態今已盡復"
),
/**
* The Message state reset holder for suc.
*/
MESSAGE_STATE_RESET_HOLDER_FOR_SUC(
LeashStateCommand.RESET_HOLDER_FOR_SUC, ModPartEnum.COMMAND,
"Successfully reset holder %s for %s",
@ -367,6 +417,9 @@ public enum SLPLangKeyValue {
"%s之持者%s狀態今已復"
),
/**
* The Message state reset holder for block pos suc.
*/
MESSAGE_STATE_RESET_HOLDER_FOR_BLOCK_POS_SUC(
LeashStateCommand.RESET_HOLDER_FOR_BLOCK_POS_SUC, ModPartEnum.COMMAND,
"Successfully reset block position %s for %s",
@ -375,6 +428,9 @@ public enum SLPLangKeyValue {
"%s之位%s狀態今已復"
),
/**
* The Message state reset apply entity all suc.
*/
MESSAGE_STATE_RESET_APPLY_ENTITY_ALL_SUC(
LeashStateCommand.RESET_APPLY_ENTITY_ALL_SUC, ModPartEnum.COMMAND,
"Successfully reset all apply entity offsets for %s",
@ -383,7 +439,10 @@ public enum SLPLangKeyValue {
"%s之諸用體偏移今已盡復"
),
// ==================== 设置操作消息 ====================
/**
* The Message state set holder for suc.
*/
// ==================== 设置操作消息 ====================
MESSAGE_STATE_SET_HOLDER_FOR_SUC(
LeashStateCommand.SET_HOLDER_FOR_SUC, ModPartEnum.COMMAND,
"Successfully set holder %s for %s",
@ -392,6 +451,9 @@ public enum SLPLangKeyValue {
"為%s設持者%s其事已成"
),
/**
* The Message state set holder for block pos suc.
*/
MESSAGE_STATE_SET_HOLDER_FOR_BLOCK_POS_SUC(
LeashStateCommand.SET_HOLDER_FOR_BLOCK_POS_SUC, ModPartEnum.COMMAND,
"Successfully set block position %s for %s",
@ -400,6 +462,9 @@ public enum SLPLangKeyValue {
"為%s設位%s其事已成"
),
/**
* The Message state set apply entity suc.
*/
MESSAGE_STATE_SET_APPLY_ENTITY_SUC(
LeashStateCommand.SET_APPLY_ENTITY_SUC, ModPartEnum.COMMAND,
"Successfully set apply entity offset %s for %s",
@ -408,7 +473,10 @@ public enum SLPLangKeyValue {
"為%s設用體偏移%s其事已成"
),
// ==================== 查询操作消息 ====================
/**
* The Message state query has state suc.
*/
// ==================== 查询操作消息 ====================
MESSAGE_STATE_QUERY_HAS_STATE_SUC(
LeashStateCommand.QUERY_HAS_STATE_SUC, ModPartEnum.COMMAND,
"%s has state: %s",
@ -417,6 +485,9 @@ public enum SLPLangKeyValue {
"%s 有狀否: %s"
),
/**
* The Message state get all uuid states suc.
*/
MESSAGE_STATE_GET_ALL_UUID_STATES_SUC(
LeashStateCommand.GET_ALL_UUID_STATES_SUC, ModPartEnum.COMMAND,
"Found %d UUID states for %s:",
@ -425,6 +496,9 @@ public enum SLPLangKeyValue {
"%s之UUID狀有%d:"
),
/**
* The Message state get all block pos states suc.
*/
MESSAGE_STATE_GET_ALL_BLOCK_POS_STATES_SUC(
LeashStateCommand.GET_ALL_BLOCK_POS_STATES_SUC, ModPartEnum.COMMAND,
"Found %d block position states for %s:",
@ -433,6 +507,9 @@ public enum SLPLangKeyValue {
"%s之位狀有%d:"
),
/**
* The Message state get apply entity offset suc.
*/
MESSAGE_STATE_GET_APPLY_ENTITY_OFFSET_SUC(
LeashStateCommand.GET_APPLY_ENTITY_OFFSET_SUC, ModPartEnum.COMMAND,
"%s apply entity offset: %s",
@ -441,6 +518,9 @@ public enum SLPLangKeyValue {
"%s 用體偏移: %s"
),
/**
* The Message state get apply entity offset none.
*/
MESSAGE_STATE_GET_APPLY_ENTITY_OFFSET_NONE(
LeashStateCommand.GET_APPLY_ENTITY_OFFSET_NONE, ModPartEnum.COMMAND,
"%s has no apply entity offset",
@ -449,6 +529,9 @@ public enum SLPLangKeyValue {
"%s 無用體偏移"
),
/**
* The Message state get default apply entity offset suc.
*/
MESSAGE_STATE_GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC(
LeashStateCommand.GET_DEFAULT_APPLY_ENTITY_OFFSET_SUC, ModPartEnum.COMMAND,
"%s default apply entity offset: %s",
@ -457,6 +540,9 @@ public enum SLPLangKeyValue {
"%s 常用體偏移: %s"
),
/**
* The Message state get all states head.
*/
MESSAGE_STATE_GET_ALL_STATES_HEAD(
LeashStateCommand.GET_ALL_STATES_HEAD, ModPartEnum.COMMAND,
"All states for %s:",
@ -464,6 +550,9 @@ public enum SLPLangKeyValue {
"%s 的所有狀態:",
"%s 之諸狀:"
),
/**
* Message abbreviation slp lang key value.
*/
MESSAGE_ABBREVIATION(
Command.ABBREVIATION, ModPartEnum.COMMAND,
"...",
@ -471,6 +560,9 @@ public enum SLPLangKeyValue {
"...",
"..."
),
/**
* Message end slp lang key value.
*/
MESSAGE_END(
Command.END, ModPartEnum.COMMAND,
".",
@ -478,6 +570,9 @@ public enum SLPLangKeyValue {
"",
""
),
/**
* Message colon slp lang key value.
*/
MESSAGE_COLON(
Command.COLON, ModPartEnum.COMMAND,
":",
@ -485,6 +580,9 @@ public enum SLPLangKeyValue {
":",
":"
),
/**
* Message block pos slp lang key value.
*/
MESSAGE_BLOCK_POS(
Command.BLOCK_POS, ModPartEnum.COMMAND,
"§7[§fX: %d, Y: %d, Z: %d§7]",
@ -492,6 +590,9 @@ public enum SLPLangKeyValue {
"§7[§fX: %d, Y: %d, Z: %d§7]",
"§7[§fX: %d, Y: %d, Z: %d§7]"
),
/**
* Message none slp lang key value.
*/
MESSAGE_NONE(
Command.NONE, ModPartEnum.COMMAND,
"<None>",
@ -499,6 +600,9 @@ public enum SLPLangKeyValue {
"",
""
),
/**
* Message state slp lang key value.
*/
MESSAGE_STATE(
Command.STATE, ModPartEnum.COMMAND,
"State",
@ -506,6 +610,9 @@ public enum SLPLangKeyValue {
"狀態",
""
),
/**
* The Message apply offset.
*/
MESSAGE_APPLY_OFFSET(
LeashStateCommand.APPLY_OFFSET, ModPartEnum.COMMAND,
"Apply Offset",
@ -513,6 +620,9 @@ public enum SLPLangKeyValue {
"應用偏移狀態",
"偏狀"
),
/**
* The Message default offset.
*/
MESSAGE_DEFAULT_OFFSET(
LeashStateCommand.DEFAULT_OFFSET, ModPartEnum.COMMAND,
"Default Offset",
@ -520,6 +630,9 @@ public enum SLPLangKeyValue {
"預設偏移狀態",
"常偏狀"
),
/**
* The Message leashdata all knots.
*/
MESSAGE_LEASHDATA_ALL_KNOTS(
Command.ALL_KNOTS, ModPartEnum.COMMAND,
"All Knots",
@ -527,6 +640,9 @@ public enum SLPLangKeyValue {
"所有繩結",
"諸結"
),
/**
* The Message leashdata all holders.
*/
MESSAGE_LEASHDATA_ALL_HOLDERS(
Command.ALL_HOLDERS, ModPartEnum.COMMAND,
"All Holders",
@ -534,6 +650,9 @@ public enum SLPLangKeyValue {
"所有持有者",
"諸持者"
),
/**
* The constant MESSAGE_LEASHDATA_SET_STATIC_MAX_DISTANCE.
*/
MESSAGE_LEASHDATA_SET_STATIC_MAX_DISTANCE(
LeashDataCommand.SET_STATIC_MAX_DISTANCE_SUC, ModPartEnum.COMMAND,
"Successfully set the static max distance of leash to %.2f from %s",
@ -541,6 +660,9 @@ public enum SLPLangKeyValue {
"已成功設定%.2f為%s的全域最大距離",
"繩距定為%.2f,已立%s之全域極距"
),
/**
* The constant MESSAGE_LEASHDATA_RESET_STATIC_MAX_DISTANCE.
*/
MESSAGE_LEASHDATA_RESET_STATIC_MAX_DISTANCE(
LeashDataCommand.RESET_STATIC_MAX_DISTANCE_SUC, ModPartEnum.COMMAND,
"Successfully reset the static max distance of leash from %s",
@ -548,6 +670,9 @@ public enum SLPLangKeyValue {
"已成功重置%s的全域最大距離",
"%s之全域極距今已復初"
),
/**
* The constant MESSAGE_LEASHDATA_SET_STATIC_ELASTIC_DISTANCE_SCALE.
*/
MESSAGE_LEASHDATA_SET_STATIC_ELASTIC_DISTANCE_SCALE(
LeashDataCommand.SET_STATIC_ELASTIC_DISTANCE_SCALE_SUC, ModPartEnum.COMMAND,
"Successfully set the static elastic distance scale of leash to %.2f from %s",
@ -555,6 +680,9 @@ public enum SLPLangKeyValue {
"已成功設定%.2f為%s的全域彈性距離比例",
"繩距彈性比例定為%.2f,已立%s之全域伸縮度"
),
/**
* The constant MESSAGE_LEASHDATA_RESET_STATIC_ELASTIC_DISTANCE_SCALE.
*/
MESSAGE_LEASHDATA_RESET_STATIC_ELASTIC_DISTANCE_SCALE(
LeashDataCommand.RESET_STATIC_ELASTIC_DISTANCE_SCALE_SUC, ModPartEnum.COMMAND,
"Successfully reset the static elastic distance scale of leash from %s",
@ -562,6 +690,9 @@ public enum SLPLangKeyValue {
"成功重置%s的全域彈性距離比例",
"%s之全域伸縮比例今已復初"
),
/**
* The Message leashdata set max distance suc.
*/
MESSAGE_LEASHDATA_SET_MAX_DISTANCE_SUC(
LeashDataCommand.SET_MAX_DISTANCE_SUC, ModPartEnum.COMMAND,
"Successfully adjusted the max distance of leash from %s to %s",
@ -569,6 +700,9 @@ public enum SLPLangKeyValue {
"成功調整%s到%s的拴繩最大距離",
"%s至%s之拴繩極距今已定"
),
/**
* The Message leashdata set max distance suc fail.
*/
MESSAGE_LEASHDATA_SET_MAX_DISTANCE_SUC_FAIL(
LeashDataCommand.SET_MAX_DISTANCE_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to adjust it from %s to %s",
@ -576,6 +710,9 @@ public enum SLPLangKeyValue {
",但未能調整%s到%s的拴繩最大距離",
",然%s至%s之拴繩極距未定"
),
/**
* The Message leashdata set max distance fail.
*/
MESSAGE_LEASHDATA_SET_MAX_DISTANCE_FAIL(
LeashDataCommand.SET_MAX_DISTANCE_FAIL, ModPartEnum.COMMAND,
"Failed to adjust the max distance of leash from %s to %s",
@ -583,6 +720,9 @@ public enum SLPLangKeyValue {
"未能調整%s到%s的拴繩最大距離",
"%s至%s之拴繩極距未成"
),
/**
* The Message leashdata remove all block leashes.
*/
MESSAGE_LEASHDATA_REMOVE_ALL_BLOCK_LEASHES(
LeashDataCommand.REMOVE_ALL_BLOCK_LEASHES, ModPartEnum.COMMAND,
"Successfully removed all holders' leash to %s",
@ -590,6 +730,9 @@ public enum SLPLangKeyValue {
"已成功移除所有持有者對%s的牽引",
"%s之所有羈絆今已盡釋"
),
/**
* The Message leashdata remove remove all holder leashes.
*/
MESSAGE_LEASHDATA_REMOVE_REMOVE_ALL_HOLDER_LEASHES(
LeashDataCommand.REMOVE_ALL_HOLDER_LEASHES, ModPartEnum.COMMAND,
"Successfully removed all holders' leash to %s",
@ -597,6 +740,9 @@ public enum SLPLangKeyValue {
"已成功移除所有持有者對%s的牽引",
"%s之所有繫繩今已盡除"
),
/**
* The Message leashdata transfer from block suc.
*/
MESSAGE_LEASHDATA_TRANSFER_FROM_BLOCK_SUC(
LeashDataCommand.TRANSFER_FROM_BLOCK_SUC, ModPartEnum.COMMAND,
"Successfully transferred leash from %s to %s",
@ -604,6 +750,9 @@ public enum SLPLangKeyValue {
"已成功將牽引從%s轉移至%s",
"繫繩自%s移至%s其事已成"
),
/**
* The Message leashdata transfer from block suc fail.
*/
MESSAGE_LEASHDATA_TRANSFER_FROM_BLOCK_SUC_FAIL(
LeashDataCommand.TRANSFER_FROM_BLOCK_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to transfer leash from %s to %s.",
@ -611,6 +760,9 @@ public enum SLPLangKeyValue {
",但未能將牽引從%s轉移至%s",
",然自%s至%s之遷移未竟"
),
/**
* The Message leashdata transfer from block fail.
*/
MESSAGE_LEASHDATA_TRANSFER_FROM_BLOCK_FAIL(
LeashDataCommand.TRANSFER_FROM_BLOCK_FAIL, ModPartEnum.COMMAND,
"Failed to transfer leash from %s to %s.",
@ -618,6 +770,9 @@ public enum SLPLangKeyValue {
"未能將牽引從%s轉移至%s",
"繫繩自%s遷於%s之舉未遂"
),
/**
* The Message leashdata set elastic distance scale suc.
*/
MESSAGE_LEASHDATA_SET_ELASTIC_DISTANCE_SCALE_SUC(
LeashDataCommand.SET_ELASTIC_DISTANCE_SCALE_SUC, ModPartEnum.COMMAND,
"Successfully adjusted the elastic distance scale of leash from %s to %s",
@ -625,6 +780,9 @@ public enum SLPLangKeyValue {
"成功調整%s到%s的拴繩彈性距離比例",
"%s至%s之拴繩伸縮比例今已定"
),
/**
* The Message leashdata set elastic distance scale suc fail.
*/
MESSAGE_LEASHDATA_SET_ELASTIC_DISTANCE_SCALE_SUC_FAIL(
LeashDataCommand.SET_ELASTIC_DISTANCE_SCALE_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to adjust it from %s to %s",
@ -632,6 +790,9 @@ public enum SLPLangKeyValue {
",但未能調整%s到%s的拴繩彈性距離比例",
",然%s至%s之拴繩伸縮比例未定"
),
/**
* The Message leashdata set elastic distance scale fail.
*/
MESSAGE_LEASHDATA_SET_ELASTIC_DISTANCE_SCALE_FAIL(
LeashDataCommand.SET_ELASTIC_DISTANCE_SCALE_FAIL, ModPartEnum.COMMAND,
"Failed to adjust the elastic distance scale of leash from %s to %s",
@ -639,6 +800,9 @@ public enum SLPLangKeyValue {
"未能調整%s到%s的拴繩彈性距離比例",
"%s至%s之拴繩伸縮比例未成"
),
/**
* The Message leashdata set block max distance suc.
*/
MESSAGE_LEASHDATA_SET_BLOCK_MAX_DISTANCE_SUC(
LeashDataCommand.SET_BLOCK_MAX_DISTANCE_SUC, ModPartEnum.COMMAND,
"Successfully adjusted the max distance of leash from %s to %s",
@ -646,6 +810,9 @@ public enum SLPLangKeyValue {
"成功調整%s到%s的拴繩最大距離",
"%s至%s之拴繩極距今已定"
),
/**
* The Message leashdata set block max distance suc fail.
*/
MESSAGE_LEASHDATA_SET_BLOCK_MAX_DISTANCE_SUC_FAIL(
LeashDataCommand.SET_BLOCK_MAX_DISTANCE_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to adjust it from %s to %s",
@ -653,6 +820,9 @@ public enum SLPLangKeyValue {
",但未能調整%s到%s的拴繩最大距離",
",然%s至%s之拴繩極距未定"
),
/**
* The Message leashdata set block max distance fail.
*/
MESSAGE_LEASHDATA_SET_BLOCK_MAX_DISTANCE_FAIL(
LeashDataCommand.SET_BLOCK_MAX_DISTANCE_FAIL, ModPartEnum.COMMAND,
"Failed to adjust the max distance of leash from %s to %s",
@ -660,6 +830,9 @@ public enum SLPLangKeyValue {
"未能調整%s到%s的拴繩最大距離",
"%s至%s之拴繩極距未成"
),
/**
* The Message leashdata set block elastic distance scale suc.
*/
MESSAGE_LEASHDATA_SET_BLOCK_ELASTIC_DISTANCE_SCALE_SUC(
LeashDataCommand.SET_BLOCK_ELASTIC_DISTANCE_SCALE_SUC, ModPartEnum.COMMAND,
"Successfully adjusted the elastic distance scale of leash from %s to %s",
@ -667,6 +840,9 @@ public enum SLPLangKeyValue {
"成功調整%s到%s的拴繩彈性距離比例",
"%s至%s之拴繩伸縮比例今已定"
),
/**
* The Message leashdata set block elastic distance scale suc fail.
*/
MESSAGE_LEASHDATA_SET_BLOCK_ELASTIC_DISTANCE_SCALE_SUC_FAIL(
LeashDataCommand.SET_BLOCK_ELASTIC_DISTANCE_SCALE_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to adjust it from %s to %s",
@ -674,6 +850,9 @@ public enum SLPLangKeyValue {
",但未能調整%s到%s的拴繩彈性距離比例",
",然%s至%s之拴繩伸縮比例未定"
),
/**
* The Message leashdata set block elastic distance scale fail.
*/
MESSAGE_LEASHDATA_SET_BLOCK_ELASTIC_DISTANCE_SCALE_FAIL(
LeashDataCommand.SET_BLOCK_ELASTIC_DISTANCE_SCALE_FAIL, ModPartEnum.COMMAND,
"Failed to adjust the elastic distance scale of leash from %s to %s",
@ -681,6 +860,9 @@ public enum SLPLangKeyValue {
"未能%s調整為拴繩彈性距離比例從%s",
"繩距伸縮比例自%s易為%s之舉未遂"
),
/**
* Message leashdata leash data head slp lang key value.
*/
MESSAGE_LEASHDATA_LEASH_DATA_HEAD(
LeashDataCommand.LEASH_DATA_HEAD, ModPartEnum.COMMAND,
"LeashData:",
@ -688,6 +870,9 @@ public enum SLPLangKeyValue {
"拴繩數據:",
"繫繩錄:"
),
/**
* Message leashdata leash data item slp lang key value.
*/
MESSAGE_LEASHDATA_LEASH_DATA_ITEM(
LeashDataCommand.LEASH_DATA_ITEM, ModPartEnum.COMMAND,
"%s { Holder:%s, BlockPos:%s }",
@ -755,6 +940,9 @@ public enum SLPLangKeyValue {
"保留字段",
"備註"
),
/**
* Message leashdata entity slp lang key value.
*/
MESSAGE_LEASHDATA_ENTITY(
LeashDataCommand.ENTITY, ModPartEnum.COMMAND,
"§7[ §l§fEntity §r§7]",
@ -763,6 +951,9 @@ public enum SLPLangKeyValue {
"§7[ §l§f實者 §r§7]"
),
/**
* Message leashdata knot slp lang key value.
*/
MESSAGE_LEASHDATA_KNOT(
LeashDataCommand.KNOT, ModPartEnum.COMMAND,
"Knot",
@ -770,6 +961,9 @@ public enum SLPLangKeyValue {
"§7[ §l§f繩結 §r§7]",
"§7[ §l§f結 §r§7]"
),
/**
* Message leashdata leash info head slp lang key value.
*/
MESSAGE_LEASHDATA_LEASH_INFO_HEAD(
LeashDataCommand.LEASH_INFO_HEAD, ModPartEnum.COMMAND,
"LeashInfo:",
@ -777,6 +971,9 @@ public enum SLPLangKeyValue {
"拴繩資訊:",
"繫繩訊:"
),
/**
* Message leashdata leash info item slp lang key value.
*/
MESSAGE_LEASHDATA_LEASH_INFO_ITEM(
LeashDataCommand.LEASH_INFO_ITEM, ModPartEnum.COMMAND,
"%s { Info: %s }",
@ -784,6 +981,9 @@ public enum SLPLangKeyValue {
"%s { 資訊: %s }",
"%s { 訊: %s }"
),
/**
* The Message leashdata add holder leashes suc.
*/
MESSAGE_LEASHDATA_ADD_HOLDER_LEASHES_SUC(
LeashDataCommand.ADD_HOLDER_LEASHES_SUC, ModPartEnum.COMMAND,
"Successfully attached %s leash from %s to %s",
@ -791,6 +991,9 @@ public enum SLPLangKeyValue {
"成功將%s拴繩從%s連接到%s",
"%s繩自%s繫於%s其事已成"
),
/**
* The Message leashdata add holder leashes suc fail.
*/
MESSAGE_LEASHDATA_ADD_HOLDER_LEASHES_SUC_FAIL(
LeashDataCommand.ADD_HOLDER_LEASHES_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to attached %s leash from %s to %s.",
@ -798,6 +1001,9 @@ public enum SLPLangKeyValue {
",但未能將%s拴繩從%s連接到%s",
",然%s繩自%s繫於%s未竟"
),
/**
* The Message leashdata add holder leashes fail.
*/
MESSAGE_LEASHDATA_ADD_HOLDER_LEASHES_FAIL(
LeashDataCommand.ADD_HOLDER_LEASHES_FAIL, ModPartEnum.COMMAND,
"Failed to attached %s leash from %s to %s.",
@ -805,6 +1011,9 @@ public enum SLPLangKeyValue {
"未能將%s拴繩從%s連接到%s",
"%s繩自%s繫於%s之舉未遂"
),
/**
* The Message leashdata add block leashes suc.
*/
MESSAGE_LEASHDATA_ADD_BLOCK_LEASHES_SUC(
LeashDataCommand.ADD_BLOCK_LEASHES_SUC, ModPartEnum.COMMAND,
"Successfully attached %s leash from %s to %s",
@ -812,6 +1021,9 @@ public enum SLPLangKeyValue {
"成功將%s拴繩從%s連接到%s",
"%s繩自%s繫於%s其事已成"
),
/**
* The Message leashdata add block leashes suc fail.
*/
MESSAGE_LEASHDATA_ADD_BLOCK_LEASHES_SUC_FAIL(
LeashDataCommand.ADD_BLOCK_LEASHES_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to attached %s leash from %s to %s.",
@ -819,6 +1031,9 @@ public enum SLPLangKeyValue {
",但未能將%s拴繩從%s連接到%s",
",然%s繩自%s繫於%s未竟"
),
/**
* The Message leashdata add block leashes fail.
*/
MESSAGE_LEASHDATA_ADD_BLOCK_LEASHES_FAIL(
LeashDataCommand.ADD_BLOCK_LEASHES_FAIL, ModPartEnum.COMMAND,
"Failed to attached %s leash from %s to %s.",
@ -826,6 +1041,9 @@ public enum SLPLangKeyValue {
"未能將%s拴繩從%s連接到%s",
"%s繩自%s繫於%s之舉未遂"
),
/**
* The Message leashdata add block leashes fail no knot found.
*/
MESSAGE_LEASHDATA_ADD_BLOCK_LEASHES_FAIL_NO_KNOT_FOUND(
LeashDataCommand.ADD_BLOCK_LEASHES_FAIL_NO_KNOT_FOUND, ModPartEnum.COMMAND,
"Unable to tie the towing rope to %s as there is no knot in the position.",
@ -833,6 +1051,9 @@ public enum SLPLangKeyValue {
"無法將拴繩繫到%s因為該位置沒有繩結",
"%s處無結拴繩難繫"
),
/**
* Message leashdata default slp lang key value.
*/
MESSAGE_LEASHDATA_DEFAULT(
LeashDataCommand.DEFAULT, ModPartEnum.COMMAND,
"Default",
@ -840,6 +1061,9 @@ public enum SLPLangKeyValue {
"默認值",
"原值"
),
/**
* The Message leashdata remove holder leashes suc.
*/
MESSAGE_LEASHDATA_REMOVE_HOLDER_LEASHES_SUC(
LeashDataCommand.REMOVE_HOLDER_LEASHES_SUC, ModPartEnum.COMMAND,
"Successfully detached leash from %s to %s",
@ -847,6 +1071,9 @@ public enum SLPLangKeyValue {
"成功解除%s到%s的拴繩連接",
"%s至%s之拴繩今已解"
),
/**
* The Message leashdata remove holder leashes suc fail.
*/
MESSAGE_LEASHDATA_REMOVE_HOLDER_LEASHES_SUC_FAIL(
LeashDataCommand.REMOVE_HOLDER_LEASHES_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to detach leash from %s to %s",
@ -854,6 +1081,9 @@ public enum SLPLangKeyValue {
"未能解除%s到%s的拴繩連接",
"%s至%s之拴繩未除"
),
/**
* The Message leashdata remove holder leashes fail.
*/
MESSAGE_LEASHDATA_REMOVE_HOLDER_LEASHES_FAIL(
LeashDataCommand.REMOVE_HOLDER_LEASHES_FAIL, ModPartEnum.COMMAND,
"Failed to detach leash from %s to %s.",
@ -861,6 +1091,9 @@ public enum SLPLangKeyValue {
"成功解除%s到%s的拴繩連接",
"%s至%s之拴繩今已解"
),
/**
* The Message leashdata remove block leashes suc.
*/
MESSAGE_LEASHDATA_REMOVE_BLOCK_LEASHES_SUC(
LeashDataCommand.REMOVE_BLOCK_LEASHES_SUC, ModPartEnum.COMMAND,
"Successfully detached leash from %s to %s",
@ -868,6 +1101,9 @@ public enum SLPLangKeyValue {
",但未能解除%s到%s的拴繩連接",
",然%s至%s之拴繩未解"
),
/**
* The Message leashdata remove block leashes suc fail.
*/
MESSAGE_LEASHDATA_REMOVE_BLOCK_LEASHES_SUC_FAIL(
LeashDataCommand.REMOVE_BLOCK_LEASHES_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to detach leash from %s to %s",
@ -875,6 +1111,9 @@ public enum SLPLangKeyValue {
"未能解除%s到%s的拴繩連接",
"%s至%s之拴繩未除"
),
/**
* The Message leashdata remove block leashes fail.
*/
MESSAGE_LEASHDATA_REMOVE_BLOCK_LEASHES_FAIL(
LeashDataCommand.REMOVE_BLOCK_LEASHES_FAIL, ModPartEnum.COMMAND,
"Failed to detach leash from %s to %s.",
@ -882,6 +1121,9 @@ public enum SLPLangKeyValue {
"成功解除%s的所有拴繩連接",
"%s之諸拴繩今盡解"
),
/**
* The Message leashdata remove all leashes.
*/
MESSAGE_LEASHDATA_REMOVE_ALL_LEASHES(
LeashDataCommand.REMOVE_ALL_LEASHES, ModPartEnum.COMMAND,
"Successfully detached all leash from %s",
@ -889,6 +1131,9 @@ public enum SLPLangKeyValue {
"成功解除%s的所有拴繩連接",
"%s之諸拴繩今盡解"
),
/**
* The Message leashdata transfer leash suc.
*/
MESSAGE_LEASHDATA_TRANSFER_LEASH_SUC(
LeashDataCommand.TRANSFER_LEASH_SUC, ModPartEnum.COMMAND,
"Successfully transferred leash from %s to %s",
@ -896,6 +1141,9 @@ public enum SLPLangKeyValue {
"成功將拴繩從%s轉移至%s",
"拴繩自%s移至%s其事已成"
),
/**
* The Message leashdata transfer leash suc fail.
*/
MESSAGE_LEASHDATA_TRANSFER_LEASH_SUC_FAIL(
LeashDataCommand.TRANSFER_LEASH_SUC_FAIL, ModPartEnum.COMMAND,
", but failed to transfer leash from %s to %s.",
@ -903,6 +1151,9 @@ public enum SLPLangKeyValue {
",但未能將拴繩從%s轉移至%s",
",然自%s至%s之遷移未竟"
),
/**
* The Message leashdata transfer leash fail.
*/
MESSAGE_LEASHDATA_TRANSFER_LEASH_FAIL(
LeashDataCommand.TRANSFER_LEASH_FAIL, ModPartEnum.COMMAND,
"Failed to transfer leash from %s to %s.",
@ -910,6 +1161,9 @@ public enum SLPLangKeyValue {
"未能將拴繩從%s轉移至%s",
"拴繩自%s遷於%s之舉未遂"
),
/**
* The Message leashdata apply force.
*/
MESSAGE_LEASHDATA_APPLY_FORCE(
LeashDataCommand.APPLY_FORCE, ModPartEnum.COMMAND,
"Successfully applied force on %s",
@ -917,6 +1171,54 @@ public enum SLPLangKeyValue {
"成功觸發%s的力",
"%s之力今已發"
),
/**
* The No leash effect.
*/
NO_LEASH_EFFECT(
SLPEffects.getEffectKey(SLPEffects.NO_SUPER_LEASH_EFFECT.get()), ModPartEnum.NAME,
"No Super Leash",
"禁拴",
"禁拴",
"禁系之效"
),
/**
* The No leash potion.
*/
NO_LEASH_POTION(
SLPPotions.getPotionNameKey("no_super_leash", (char) 0), ModPartEnum.NAME,
"No Super Leash Potion",
"禁拴药水",
"禁拴藥水",
"禁系汤剂"
),
/**
* The No leash potion splash.
*/
NO_LEASH_POTION_SPLASH(
SLPPotions.getPotionNameKey("no_super_leash", (char) 2), ModPartEnum.NAME,
"Splash No Super Leash Potion",
"喷溅型禁拴药水",
"噴濺型禁拴藥水",
"飞溅禁系汤"
),
/**
* The No leash potion lingering.
*/
NO_LEASH_POTION_LINGERING(
SLPPotions.getPotionNameKey("no_super_leash", (char) 1), ModPartEnum.NAME,
"Splash No Super Leash Potion",
"滞留型禁拴药水",
"滯留型禁拴藥水",
"缠绵禁系汤"
),
/**
* Author tooltip slp lang key value.
*/
AUTHOR_TOOLTIP(
"tooltip.superleadrope.author", ModPartEnum.DESCRIPTION,
"Author : R3944Realms", "作者 : R3944Realms",
"作者 : R3944Realms", "作者 : R3944Realms"
)
;
private final Supplier<?> supplier;

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