更新版本 v1.0.0 -> v1.1.0

添加了拴绳实体
新增新的附魔
调整拴绳数据cap实现
修改配置
删除无用代码
更新代码版权声明
优化import
This commit is contained in:
叁玖领域 2026-02-03 11:46:28 +08:00
parent ebec0d5dee
commit 3a519afad2
140 changed files with 2598 additions and 553 deletions

View File

@ -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=1.0.0
mod_version=1.1.0
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-11T17:31:55.2360112 Languages: zh_tw
d1253ab3534285cc6a4d6c0e5495720f48edd62f assets/superleadrope/lang/zh_tw.json
// 1.20.1 2026-02-03T08:44:54.0210684 Languages: zh_tw
f8980ca1dc25d142cc450ea10dee91381d04aea1 assets/superleadrope/lang/zh_tw.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-11T17:31:55.2360112 Languages: zh_cn
7f4db04637eb656488388de206cad9070a53ae48 assets/superleadrope/lang/zh_cn.json
// 1.20.1 2026-02-03T08:44:54.0190884 Languages: zh_cn
f319c4ab2544a1a96b32af977d688614a2f30e2a assets/superleadrope/lang/zh_cn.json

View File

@ -1,5 +1,4 @@
// 1.20.1 2025-12-11T18:08:58.6978167 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
50782bef004ff1c69c09aa397a8ee92b71a8b858 assets/superleadrope/models/item/doll.json
7b072a8cc70b53d54e37e5fa72d705bd07780943 assets/superleadrope/models/item/eternal_potato.json
4fb737a5f8f15642212aa581a02a81cf649fc36f assets/superleadrope/models/item/super_lead_rope.json

View File

@ -1,2 +1 @@
// 1.20.1 2025-12-11T17:31:55.2360112 Block States: superleadrope
6e9e15398c0d85d14941797931eb3f7c886a800a assets/superleadrope/blockstates/doll.json
// 1.20.1 2026-02-02T15:05:26.4884922 Block States: superleadrope

View File

@ -1,2 +1 @@
// 1.20.1 2025-12-11T17:31:55.2360112 Loot Tables
c31110372e9281cf7264482c2c89c8927fb67fe2 data/superleadrope/loot_tables/blocks/doll.json
// 1.20.1 2026-02-02T15:05:26.4750266 Loot Tables

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-11T17:31:55.2360112 Languages: lzh
c03cdd0fb0e9a7bcf525fc0e18fe31e2b906f8f0 assets/superleadrope/lang/lzh.json
// 1.20.1 2026-02-03T08:44:54.0200682 Languages: lzh
039042b02d04a096296478ccb038abf731ecec37 assets/superleadrope/lang/lzh.json

View File

@ -1,2 +1,2 @@
// 1.20.1 2025-12-11T17:31:55.2360112 Languages: en_us
d1d1d2a67f7602340c0f0e0dcf1ea1b93fdc23f4 assets/superleadrope/lang/en_us.json
// 1.20.1 2026-02-03T08:44:54.0200682 Languages: en_us
fc60a4eba1a5a5d6eb205d0f97a190932a25f1c4 assets/superleadrope/lang/en_us.json

View File

@ -1,34 +0,0 @@
{
"variants": {
"facing=east,waterlogged=false": {
"model": "superleadrope:block/doll",
"y": 90
},
"facing=east,waterlogged=true": {
"model": "superleadrope:block/doll",
"y": 90
},
"facing=north,waterlogged=false": {
"model": "superleadrope:block/doll"
},
"facing=north,waterlogged=true": {
"model": "superleadrope:block/doll"
},
"facing=south,waterlogged=false": {
"model": "superleadrope:block/doll",
"y": 180
},
"facing=south,waterlogged=true": {
"model": "superleadrope:block/doll",
"y": 180
},
"facing=west,waterlogged=false": {
"model": "superleadrope:block/doll",
"y": 270
},
"facing=west,waterlogged=true": {
"model": "superleadrope:block/doll",
"y": 270
}
}
}

View File

@ -1,9 +1,11 @@
{
"block.superleadrope.doll": "Doll",
"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.ring_toss": "Ring Toss",
"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",

View File

@ -1,9 +1,11 @@
{
"block.superleadrope.doll": "戲像",
"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.ring_toss": "套圈",
"entity.superleadrope.super_lead_knot": "神駒羈縻索結",
"entity.superleadrope.super_leash_rope": "神駒羈縻索",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "若阙则创超级繫绳结",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "若栅等支处阙超级繫绳结,则创之",
"gamerule.SLP.TeleportWithLeashedEntities": "繫畜隨持者傳送",

View File

@ -1,9 +1,11 @@
{
"block.superleadrope.doll": "玩偶",
"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.ring_toss": "套圈",
"entity.superleadrope.super_lead_knot": "超级拴绳结",
"entity.superleadrope.super_leash_rope": "超级拴绳",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "如果缺失则创建超级拴绳结",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "如果在栅栏等支持处缺失超级拴绳结,则创建它",
"gamerule.SLP.TeleportWithLeashedEntities": "被拴实体随持有者传送",

View File

@ -1,9 +1,11 @@
{
"block.superleadrope.doll": "玩偶",
"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.ring_toss": "套圈",
"entity.superleadrope.super_lead_knot": "超級拴繩結",
"entity.superleadrope.super_leash_rope": "超級拴繩",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "如果缺失則創建超級拴繩結",
"gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "如果在柵欄等支持處缺失超級拴繩結,則創建它",
"gamerule.SLP.TeleportWithLeashedEntities": "被拴实体随持有者傳送",

View File

@ -1,3 +0,0 @@
{
"parent": "superleadrope:block/doll"
}

View File

@ -1,21 +0,0 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "superleadrope:doll"
}
],
"rolls": 1.0
}
],
"random_sequence": "superleadrope:blocks/doll"
}

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;
@ -75,6 +79,7 @@ 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;
@ -472,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.
*
@ -501,6 +527,7 @@ public class CommonEventHandler {
event.enqueueWork(Mod::checkAndSet);
event.enqueueWork(SLPGameruleRegistry::register);
event.enqueueWork(SLPPotionRecipeRegistry::init);
event.enqueueWork(() -> DispenserBlock.registerBehavior(SLPItems.SUPER_LEAD_ROPE.get(), SuperLeashRopeEntity.SuperLeashRopeItemBehavior.INSTANCE));
}
/**
@ -573,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/>.
@ -55,6 +55,7 @@ public class SuperLeadRope {
SLPEntityTypes.register(eventBus);
SLPSoundEvents.register(eventBus);
SLPEffects.register(eventBus);
SLPEnchantments.register(eventBus);
SLPPotions.register(eventBus);
NetworkHandler.register();
initialize();

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/>.

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/>.
@ -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,6 +23,9 @@ import net.minecraftforge.fml.ModList;
* The type Curtain compat.
*/
public class CurtainCompat{
/**
* The constant isModLoaded.
*/
public final static boolean isModLoaded = ModList.get().isLoaded("curtain");
/**

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

@ -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.compat;
import com.ibm.icu.impl.Pair;
@ -29,17 +44,43 @@ 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);
@ -88,6 +129,12 @@ public class WayStoneCompat {
}
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();

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,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,9 @@ public class LeashCommonConfig {
*/
// Leash settings
public final ForgeConfigSpec.DoubleValue maxLeashLength;
/**
* The Max movement.
*/
public final ForgeConfigSpec.DoubleValue maxMovement;
/**
* The Elastic distance scale.
@ -158,7 +176,7 @@ public class LeashCommonConfig {
.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", 100.0, 10.0, Double.MAX_VALUE);
.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);

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/>.
@ -65,8 +65,14 @@ 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<>();
@ -319,6 +325,12 @@ public class LeashConfigManager {
* @return the max leash length
*/
public double getMaxLeashLength() { return maxLeashLength; }
/**
* Gets max movement.
*
* @return the max movement
*/
public double getMaxMovement() { return maxMovement; }
/**
@ -458,8 +470,11 @@ 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;
@ -597,6 +612,8 @@ public class LeashConfigManager {
/**
* 从NBT反序列化配置管理器状态
*
* @param tag the tag
*/
public void deserializeFromNBT(CompoundTag tag) {
if (tag == null || tag.isEmpty()) return;
@ -676,6 +693,8 @@ public class LeashConfigManager {
/**
* 计算配置哈希值用于快速比较配置是否变化
*
* @return the int
*/
public int calculateConfigHash() {
// 使用FNV-1a哈希算法
@ -787,11 +806,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,144 +0,0 @@
package top.r3944realms.superleadrope.content.block;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation")
public class DollBlock extends HorizontalDirectionalBlock implements SimpleWaterloggedBlock {
private static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
private static final VoxelShape DOLL_SHAPE = Block.box(2.0d, 0.0d, 2.0d, 14.0d, 12.0d, 14.0d);
private static final double PARTICLE_OFFSET_RANGE = 0.25;
private static final double PARTICLE_HEIGHT_OFFSET = 1.0;
private static final double PARTICLE_HEIGHT_VARIANCE = 0.2;
private static final float NOTE_COLOR_DIVISOR = 24.0F;
private static final int MAX_NOTE_COLORS = 4;
private static final float BASE_VOLUME = 1.0f;
private static final float PITCH_VARIANCE = 0.5f;
private static final float BASE_PITCH = 0.75f;
public DollBlock() {
super(BlockBehaviour.Properties.of()
.instrument(NoteBlockInstrument.BASEDRUM)
.sound(SoundType.WOOL)
.strength(0f, 10f)
.noOcclusion());
this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.SOUTH)
.setValue(WATERLOGGED, false));
}
@Override
public @NotNull BlockState updateShape(@NotNull BlockState currentState, @NotNull Direction direction, @NotNull BlockState neighborState,
@NotNull LevelAccessor level, @NotNull BlockPos currentPos, @NotNull BlockPos neighborPos) {
if (currentState.getValue(WATERLOGGED)) {
level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
}
return super.updateShape(currentState, direction, neighborState, level, currentPos, neighborPos);
}
@Override
public @NotNull FluidState getFluidState(@NotNull BlockState blockState) {
return blockState.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(blockState);
}
@Override
public @NotNull InteractionResult use(@NotNull BlockState blockState, @NotNull Level level, @NotNull BlockPos blockPos, @NotNull Player player,
@NotNull InteractionHand hand, @NotNull BlockHitResult hitResult) {
if (level instanceof ServerLevel serverLevel) {
// 播放粒子效果
spawnNoteParticles(serverLevel, blockPos);
// 播放音效
playDollSound(serverLevel, blockPos);
}
return InteractionResult.SUCCESS;
}
/**
* 在玩偶位置生成音符粒子效果
*/
private void spawnNoteParticles(ServerLevel serverLevel, BlockPos blockPos) {
Vec3 particlePosition = calculateParticlePosition(serverLevel, blockPos);
float noteColor = calculateNoteColor(serverLevel);
serverLevel.sendParticles(ParticleTypes.NOTE,
particlePosition.x(), particlePosition.y(), particlePosition.z(),
0, noteColor, 0, 0, 1);
}
/**
* 计算粒子生成位置添加随机偏移
*/
private @NotNull Vec3 calculateParticlePosition(@NotNull ServerLevel serverLevel, BlockPos blockPos) {
return Vec3.atBottomCenterOf(blockPos).add(
(serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2,
PARTICLE_HEIGHT_OFFSET + serverLevel.getRandom().nextFloat() * PARTICLE_HEIGHT_VARIANCE,
(serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2
);
}
/**
* 计算音符粒子的颜色
*/
private float calculateNoteColor(@NotNull ServerLevel serverLevel) {
return serverLevel.getRandom().nextInt(MAX_NOTE_COLORS) / NOTE_COLOR_DIVISOR;
}
/**
* 播放玩偶音效
*/
private void playDollSound(@NotNull ServerLevel serverLevel, BlockPos blockPos) {
float pitch = BASE_PITCH + serverLevel.random.nextFloat() * PITCH_VARIANCE;
serverLevel.playSound(null, blockPos, SoundEvents.NOTE_BLOCK_BASEDRUM.get(),
SoundSource.BLOCKS, BASE_VOLUME, pitch);
}
@Override
public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) {
FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos());
boolean isWaterlogged = fluidState.getType() == Fluids.WATER;
return this.defaultBlockState()
.setValue(FACING, context.getHorizontalDirection().getOpposite())
.setValue(WATERLOGGED, isWaterlogged);
}
@Override
public @NotNull VoxelShape getShape(@NotNull BlockState blockState, @NotNull BlockGetter level, @NotNull BlockPos blockPos, @NotNull CollisionContext context) {
return DOLL_SHAPE;
}
@Override
protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) {
builder.add(FACING, WATERLOGGED);
}
}

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;
@ -48,6 +48,7 @@ import top.r3944realms.superleadrope.compat.CurtainCompat;
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;
@ -343,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);
@ -806,10 +813,16 @@ public class LeashDataImpl implements ILeashData {
boolean hasForce = !combinedForce.equals(Vec3.ZERO);
Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce);
if(targetEntity instanceof LocalPlayer && hasForce){
entity.addDeltaMovement(limitMovement(combinedForce));
entity.addDeltaMovement(combinedForce);
}
}
/**
* 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(
@ -857,7 +870,9 @@ 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) {
@ -869,7 +884,7 @@ public class LeashDataImpl implements ILeashData {
if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player) ) {
// 是真实玩家则交给客户端自行处理拴绳逻辑
// DO NOTHING
if(targetEntity != entity){
if(targetEntity == entity) {
NetworkHandler.sendToPlayer(new UpdatePlayerMovementPacket(UpdatePlayerMovementPacket.Operation.ADD, limitMovement(combinedForce)), player);
}
return;
@ -889,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){
@ -1050,8 +1064,6 @@ public class LeashDataImpl implements ILeashData {
return null;
}
// 2. 正常弹性拉力逻辑
Vec3 pullForce = Vec3.ZERO;
if (distance > elasticLimitDistance) {
@ -1121,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(
@ -1556,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);
@ -1641,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

@ -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.content.effect;
import net.minecraft.sounds.SoundSource;
@ -13,7 +28,16 @@ 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);
}

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,23 +0,0 @@
package top.r3944realms.superleadrope.content.item;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.superleadrope.core.register.SLPBlocks;
import java.util.List;
public class DollItem extends BlockItem {
public DollItem(Properties properties) {
super(SLPBlocks.DOLL.get(), properties);
}
@Override
public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, List<Component> tooltip, @NotNull TooltipFlag flag) {
tooltip.add(Component.translatable("tooltip.superleadrope.author"));
}
}

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,16 +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;
@ -34,12 +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;
@ -48,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* The type Super lead rope item.
*/
//TODO:
// 1. 可抛掷使用 ***下个版本实现
// 1. 可抛掷使用
// - 可转移拴绳
// 2. 多绑定一个生物可以被多个加强拴绳绑定产生共同作用效果
// 3. 支持更多支撑方块
@ -59,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; // 最大蓄力功率
/**
@ -78,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.
*
@ -106,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;
}
/**
@ -137,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;
// 查找当前玩家持有的可拴生物
@ -187,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();

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/>.

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

@ -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.core.register;
import net.minecraft.world.level.block.Block;
@ -6,16 +21,32 @@ 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.block.DollBlock;
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);
public static final RegistryObject<Block> DOLL = BLOCKS.register("doll", DollBlock::new);
/**
* 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

@ -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.core.register;
import net.minecraft.core.registries.Registries;
@ -11,22 +26,59 @@ 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/>.
@ -16,13 +16,11 @@
package top.r3944realms.superleadrope.core.register;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity;
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.item.DollItem;
import top.r3944realms.superleadrope.content.item.EternalPotatoItem;
import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem;
@ -51,15 +49,6 @@ public class SLPItems {
.stacksTo(1) // 只能有一颗
.fireResistant() // 防火
));
public static final RegistryObject<Item> DOLL =
ITEMS.register("doll",
() -> new DollItem(
new Item.Properties()
.stacksTo(1)
.fireResistant()
.rarity(Rarity.EPIC)
)
);
/**
* Register.

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,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.core.register;
import net.minecraft.world.item.ItemStack;
@ -13,10 +28,23 @@ 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;
@ -38,15 +66,32 @@ public class SLPPotionRecipeRegistry {
}
}
}
/**
* 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)));

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.core.register;
import net.minecraft.core.registries.Registries;
@ -10,18 +25,41 @@ 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/>]
@ -34,10 +72,22 @@ public class SLPPotions {
)
+ ".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/>.

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