Compare commits
10 Commits
e615fc6f09
...
6f69a24ed4
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f69a24ed4 | |||
| 8490da915d | |||
| ab54ed1521 | |||
| cf930334cb | |||
| 0b5b011eb8 | |||
| 24af58d4a4 | |||
| 8b759259ad | |||
| 0ecfe88683 | |||
| 22fc64797d | |||
| f10221a2c0 |
|
|
@ -1,4 +1,4 @@
|
|||
# 版本 0.0.3.9.9.8 提前介绍c[最终版本对于0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
|
||||
# 版本 0.0.4.0.4 提前介绍c[没有BUG的话,TeaCon最终版本将会是0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
|
||||
## 简介
|
||||
现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧(
|
||||
|
||||
|
|
@ -66,4 +66,5 @@
|
|||
* `LP.CanCommonPlayerChangeSelfTalkArea` - 此规则决定,是否普通玩家可以修改自己的聊天可见区域 [默认值: true]
|
||||
|
||||
## 联动内容
|
||||
# 与Nestle 的 贴贴拴绳箭 (未完成)
|
||||
# 与Nestle 的 贴贴拴绳箭
|
||||
射中实体生成贴贴拴绳实体并绑定在一起,解除需用到贴贴拴绳(不太好个人觉得)
|
||||
|
|
@ -35,7 +35,7 @@ mod_name=Leashed Player
|
|||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=MIT
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=0.0.3.9.9.8
|
||||
mod_version=0.0.4.0.4
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-11-27T00:15:38.1934553 Languages: en_us for mod: leashedplayer
|
||||
d32d19599105d6c5575757a7f0344f066445bd15 assets/leashedplayer/lang/en_us.json
|
||||
// 1.21 2024-12-15T17:40:40.0369665 Languages: en_us for mod: leashedplayer
|
||||
d88b57505584fdfde48b00652789cb078b469830 assets/leashedplayer/lang/en_us.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-11-27T00:15:38.1929375 Languages: zh_cn for mod: leashedplayer
|
||||
be8f599c80c4ea7e7f6de238f6acf213fe9827d2 assets/leashedplayer/lang/zh_cn.json
|
||||
// 1.21 2024-12-15T17:48:33.0549249 Languages: zh_cn for mod: leashedplayer
|
||||
72797aa9107025df7d91eaff3ea51745d410261c assets/leashedplayer/lang/zh_cn.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-11-27T00:15:38.1846441 Languages: zh_tw for mod: leashedplayer
|
||||
73006b0556ae8066c61837a9ff35a1b50126f510 assets/leashedplayer/lang/zh_tw.json
|
||||
// 1.21 2024-12-15T17:48:33.0539432 Languages: zh_tw for mod: leashedplayer
|
||||
a01c64ca969974766c47baadd465b24b6fb5803b assets/leashedplayer/lang/zh_tw.json
|
||||
|
|
|
|||
|
|
@ -58,6 +58,11 @@
|
|||
"item.minecraft.potion.effect.no_leash": "No Leash Potion",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "Splash No Leash Potion",
|
||||
"item.minecraft.tipped_arrow.effect.no_leash": "Arrow of No Leash",
|
||||
"item.nestle_rope_arrow.desc.1": "§7This arrow will carry the owner along with its flight:",
|
||||
"item.nestle_rope_arrow.desc.2": "§c1.§r If it hits an entity, it will leash the owner with the entity and drop as a normal arrow;",
|
||||
"item.nestle_rope_arrow.desc.3": "§c2.§r When fired from its launcher, the first player hit will become the arrow's owner and will fly along with it.",
|
||||
"item.nestle_rope_arrow.desc.4": "",
|
||||
"item.nestle_rope_arrow.desc.5": "",
|
||||
"item.spectral_leash_rope_arrow.desc": "§c2.§r Strike the entity to give it a §e§lGlowing§r effect.",
|
||||
"item.tipped_leash_rope_arrow.desc": "§c2.§rStrike the entity to give it a Potion effect.",
|
||||
"item.tipped_leash_rope_arrow.name": "Tipped Leash Rope Arrow Soaked By %1$s",
|
||||
|
|
|
|||
|
|
@ -58,6 +58,11 @@
|
|||
"item.minecraft.potion.effect.no_leash": "禁拴药水",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水",
|
||||
"item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭",
|
||||
"item.nestle_rope_arrow.desc.1": "§7该箭将会携带拥有者随其飞行",
|
||||
"item.nestle_rope_arrow.desc.2": "§c1.§r 若击中生物时,将持有者与其拴在一起并已普通箭形式掉落;",
|
||||
"item.nestle_rope_arrow.desc.3": "§c2.§r 当前其发射器里发射,第一个射中的玩家将成为此箭的持有者并随箭飞行.",
|
||||
"item.nestle_rope_arrow.desc.4": "",
|
||||
"item.nestle_rope_arrow.desc.5": "",
|
||||
"item.spectral_leash_rope_arrow.desc": "§c2.§r 击中实体给与其§e§l发光§7(§e§lGlowing§7)§r效果",
|
||||
"item.tipped_leash_rope_arrow.desc": "§c2.§r 击中实体给与其药水效果",
|
||||
"item.tipped_leash_rope_arrow.name": "用%1$s浸泡过的拴绳箭",
|
||||
|
|
|
|||
|
|
@ -58,6 +58,11 @@
|
|||
"item.minecraft.potion.effect.no_leash": "禁拴藥水",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水",
|
||||
"item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭",
|
||||
"item.nestle_rope_arrow.desc.1": "§7該箭將會攜帶擁有者隨其飛行:",
|
||||
"item.nestle_rope_arrow.desc.2": "§c1.§r 若擊中生物時,將持有者與其拴在一起其上並以普通箭的形式掉落;",
|
||||
"item.nestle_rope_arrow.desc.3": "§c2.§r 當箭從發射器發射時,第一個射中的玩家將成為此箭的持有者並隨箭飛行;",
|
||||
"item.nestle_rope_arrow.desc.4": "",
|
||||
"item.nestle_rope_arrow.desc.5": "",
|
||||
"item.spectral_leash_rope_arrow.desc": "擊中實體給予其§e§l發光§7(§e§lGlowing§7)§r效果",
|
||||
"item.tipped_leash_rope_arrow.desc": "擊中實體給予其药水效果",
|
||||
"item.tipped_leash_rope_arrow.name": "蘸有%1$s的拴繩箭",
|
||||
|
|
|
|||
|
|
@ -2,16 +2,13 @@ package com.r3944realms.leashedplayer;
|
|||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.r3944realms.leashedplayer.content.commands.*;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData;
|
||||
import com.r3944realms.leashedplayer.utils.Logger;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
|
|
@ -22,11 +19,8 @@ import net.minecraft.core.component.DataComponents;
|
|||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.animal.Fox;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
|
@ -102,23 +96,6 @@ public class CommonEventHandler {
|
|||
if (level.isClientSide()) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof LivingEntity living) {
|
||||
MobEffectInstance effect = living.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
|
||||
if (effect != null && effect.getDuration() != 0) {
|
||||
if (entity instanceof PlayerLeashable player) {
|
||||
if (player.getLeashHolder() != null) {
|
||||
if (player.getLeashHolder() instanceof LeashRopeArrow arrow)
|
||||
arrow.setOwner(null);
|
||||
player.dropLeash(true, !(player.getLeashHolder() instanceof LeashRopeArrow));
|
||||
}
|
||||
} else if (entity instanceof Leashable leashable) {
|
||||
if (leashable.getLeashHolder() != null) {
|
||||
if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow)
|
||||
arrow.setOwner(null);
|
||||
leashable.dropLeash(true, !(leashable.getLeashHolder() instanceof LeashRopeArrow));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entity instanceof Fox fox) {
|
||||
if (fox.getMainHandItem().is(ItemTags.ANVIL)) {
|
||||
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
|
|
@ -175,6 +152,6 @@ public class CommonEventHandler {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
package com.r3944realms.leashedplayer.compat.jei;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.compat.jei.common.PotionSubtypeInterpreter;
|
||||
import com.r3944realms.leashedplayer.compat.jei.crafting.TippedLeashArrowRecipeMaker;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.constants.RecipeTypes;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import mezz.jei.api.registration.ISubtypeRegistration;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@JeiPlugin
|
||||
public class JEIPlugin implements IModPlugin {
|
||||
private static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "jei_plugin");
|
||||
@Override
|
||||
public @NotNull ResourceLocation getPluginUid() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerItemSubtypes(ISubtypeRegistration registration) {
|
||||
registration.registerSubtypeInterpreter(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), PotionSubtypeInterpreter.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(@NotNull IRecipeRegistration registration) {
|
||||
registration.addRecipes(RecipeTypes.CRAFTING, TippedLeashArrowRecipeMaker.createRecipes());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.r3944realms.leashedplayer.compat.jei.common;
|
||||
|
||||
import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter;
|
||||
import mezz.jei.api.ingredients.subtypes.UidContext;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PotionSubtypeInterpreter implements IIngredientSubtypeInterpreter<ItemStack> {
|
||||
public static final PotionSubtypeInterpreter INSTANCE = new PotionSubtypeInterpreter();
|
||||
|
||||
private PotionSubtypeInterpreter() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String apply(ItemStack itemStack, @NotNull UidContext context) {
|
||||
if (itemStack.getComponentsPatch().isEmpty()) {
|
||||
return IIngredientSubtypeInterpreter.NONE;
|
||||
}
|
||||
PotionContents contents = itemStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
||||
String itemDescriptionId = itemStack.getItem().getDescriptionId();
|
||||
String potionEffectId = contents.potion().map(Holder::getRegisteredName).orElse("none");
|
||||
return itemDescriptionId + ".effect_id." + potionEffectId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.r3944realms.leashedplayer.compat.jei.crafting;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.compat.jei.util.RegistryUtil;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.minecraft.world.item.crafting.*;
|
||||
import net.neoforged.neoforge.common.crafting.DataComponentIngredient;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class TippedLeashArrowRecipeMaker {
|
||||
private static List<RecipeHolder<CraftingRecipe>> createRecipesA() {
|
||||
String group = "jei.tipped.leash_rope_arrow_a";
|
||||
ItemStack arrowStack = new ItemStack(ModItemRegister.LEASH_ROPE_ARROW.get());
|
||||
Ingredient arrowIngredient = Ingredient.of(arrowStack);
|
||||
|
||||
Registry<Potion> potionRegistry = RegistryUtil.getRegistry(Registries.POTION);
|
||||
return potionRegistry.holders()
|
||||
.map(potion -> {
|
||||
ItemStack input = PotionContents.createItemStack(Items.LINGERING_POTION, potion);
|
||||
ItemStack output = PotionContents.createItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), potion);
|
||||
output.setCount(8);
|
||||
|
||||
Ingredient potionIngredient = DataComponentIngredient.of(false, input);
|
||||
NonNullList<Ingredient> inputs = NonNullList.of(Ingredient.EMPTY,
|
||||
arrowIngredient, arrowIngredient, arrowIngredient,
|
||||
arrowIngredient, potionIngredient, arrowIngredient,
|
||||
arrowIngredient, arrowIngredient, arrowIngredient
|
||||
);
|
||||
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, group + "." + output.getDescriptionId());
|
||||
ShapedRecipePattern recipe = new ShapedRecipePattern(3,3, inputs, Optional.empty());
|
||||
CraftingRecipe recipe_ = new ShapedRecipe(group, CraftingBookCategory.MISC, recipe, output);
|
||||
return new RecipeHolder<>(id, recipe_);
|
||||
}).toList();
|
||||
}
|
||||
private static List<RecipeHolder<CraftingRecipe>> createRecipesB() {
|
||||
String group = "jei.tipped.leash_rope_arrow_b";
|
||||
ItemStack arrowStack = new ItemStack(Items.LEAD);
|
||||
Ingredient arrowIngredient = Ingredient.of(arrowStack);
|
||||
|
||||
Registry<Potion> potionRegistry = RegistryUtil.getRegistry(Registries.POTION);
|
||||
return potionRegistry.holders()
|
||||
.map(potion -> {
|
||||
ItemStack input = PotionContents.createItemStack(Items.TIPPED_ARROW, potion);
|
||||
ItemStack output = PotionContents.createItemStack(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), potion);
|
||||
output.setCount(1);
|
||||
|
||||
Ingredient potionIngredient = DataComponentIngredient.of(false, input);
|
||||
NonNullList<Ingredient> inputs = NonNullList.of(Ingredient.EMPTY,
|
||||
arrowIngredient,potionIngredient
|
||||
);
|
||||
ResourceLocation id = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, group + "." + output.getDescriptionId());
|
||||
|
||||
CraftingRecipe recipe_ = new ShapelessRecipe(group, CraftingBookCategory.MISC, output, inputs);
|
||||
return new RecipeHolder<>(id, recipe_);
|
||||
}).toList();
|
||||
}
|
||||
public static List<RecipeHolder<CraftingRecipe>> createRecipes() {
|
||||
List<RecipeHolder<CraftingRecipe>> ret = new ArrayList<>();
|
||||
ret.addAll(createRecipesA());
|
||||
ret.addAll(createRecipesB());
|
||||
return ret;
|
||||
}
|
||||
private TippedLeashArrowRecipeMaker() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.r3944realms.leashedplayer.compat.jei.util;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
public class RegistryUtil {
|
||||
public static <T> Registry<T> getRegistry(ResourceKey<? extends Registry<T>> key) {
|
||||
RegistryAccess registryAccess = getRegistryAccess();
|
||||
return registryAccess.registryOrThrow(key);
|
||||
}
|
||||
|
||||
public static RegistryAccess getRegistryAccess() {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
ClientLevel level = minecraft.level;
|
||||
if (level == null) {
|
||||
throw new IllegalStateException("Could not get registry, registry access is unavailable because the level is currently null");
|
||||
}
|
||||
return level.registryAccess();
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ public class LeashPlayerCommonConfig {
|
|||
public static final ModConfigSpec SPEC;
|
||||
public static final ModConfigSpec.ConfigValue<String> LeashedPlayerModCommandPrefix;
|
||||
public static final ModConfigSpec.BooleanValue EnableLeashPlayerCommandPrefix;
|
||||
public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet, TheLeashArrowMaxLifeTime;
|
||||
public static ModConfigSpec.IntValue MinimumLeashLengthCanBeSet, MaximumLeashLengthCanBeSet, TheLeashArrowMaxLifeTime, TheNestleArrowMaxLifeTime;
|
||||
public static ModConfigSpec.DoubleValue TheMultipleThatLeashRopeArrowBreakLength, TheLeashBreakLengthTimesBase;
|
||||
static {
|
||||
BUILDER.comment("Leash Player Config");
|
||||
|
|
@ -20,8 +20,9 @@ public class LeashPlayerCommonConfig {
|
|||
BUILDER.pop();
|
||||
BUILDER.comment("Leash Player Arrow");
|
||||
BUILDER.push("LeashRopeArrow");
|
||||
TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[2.0f, 10.0f] ]").defineInRange("TheMultipleArrowBreak", 5.0f, 2.0f , 10.0f);
|
||||
TheMultipleThatLeashRopeArrowBreakLength = BUILDER.comment("How many times is the length of the arrow rope based on BreakLength TimeBase", "[ Default : 5.0f, Invalid Range:[2.0f, 10.0f] ]").defineInRange("TheMultipleArrowBreak", 5.0f, 2.0f, 10.0f);
|
||||
TheLeashArrowMaxLifeTime = BUILDER.comment("If the LeashArrowEntity's life is bigger than this value ,it will be discarded", "[ Default : 2400, Invalid Range:[1200 , 10240]]").defineInRange("TheLeashArrowMaxLifeTime",2400, 1200, 10240);
|
||||
TheNestleArrowMaxLifeTime = BUILDER.comment("If the NestleArrowEntity's life is bigger than this value ,it will be discarded\", \"[ Default : 2400, Invalid Range:[1200 , 10240]]").defineInRange("TheNestleArrowMaxLifeTime",2400, 1200, 10240);
|
||||
BUILDER.pop();
|
||||
BUILDER.comment("Leash Player Misc");
|
||||
BUILDER.push("Misc");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.r3944realms.leashedplayer.content.effects;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.effects.type.NoLeashEffect;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectCategory;
|
||||
|
|
@ -12,9 +13,9 @@ import java.util.function.Supplier;
|
|||
|
||||
public class ModEffectRegister {
|
||||
public static DeferredRegister<MobEffect> MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, LeashedPlayer.MOD_ID);
|
||||
public static DeferredHolder<MobEffect, ? extends MobEffect> NO_LEASH_EFFECT = register(
|
||||
public static DeferredHolder<MobEffect, NoLeashEffect> NO_LEASH_EFFECT = register(
|
||||
"no_leash",
|
||||
() -> new MobEffect(MobEffectCategory.NEUTRAL, 12063764)
|
||||
() -> new NoLeashEffect(MobEffectCategory.NEUTRAL, 12063764)
|
||||
);
|
||||
public static <T extends MobEffect>DeferredHolder<MobEffect, T> register(String name, Supplier<T> effect) {
|
||||
return MOB_EFFECT.register(name, effect);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package com.r3944realms.leashedplayer.content.effects.type;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectCategory;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class NoLeashEffect extends MobEffect {
|
||||
|
||||
public NoLeashEffect(MobEffectCategory pCategory, int pColor) {
|
||||
super(pCategory, pColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyEffectTick(@NotNull LivingEntity pLivingEntity, int pAmplifier) {
|
||||
MobEffectInstance effect = pLivingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
|
||||
if(effect != null && effect.getDuration() != 0) {
|
||||
if (pLivingEntity instanceof Leashable leashable) {
|
||||
if (leashable.getLeashHolder() instanceof LeashRopeArrow arrow) {
|
||||
arrow.dropLeashHandler();
|
||||
leashable.dropLeash(true, false);
|
||||
}
|
||||
leashable.dropLeash(true, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyEffectTickThisTick(int pDuration, int pAmplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,9 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
|
||||
}
|
||||
private PotionContents getPotionContents() {
|
||||
return this.getPickupItemStackOrigin().getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
||||
ItemStack pickupItemStackOrigin = this.getPickupItemStackOrigin();
|
||||
pickupItemStackOrigin.setCount(1);
|
||||
return pickupItemStackOrigin.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
||||
}
|
||||
|
||||
public void addEffect(MobEffectInstance pEffectInstance) {
|
||||
|
|
@ -84,7 +86,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if(serverPlayer != null && !level().isClientSide) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(serverPlayer, (ServerLevel) level());
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.setOwner(null);
|
||||
leashRopeArrow.setOwner(null);//将先前的箭矢置空
|
||||
}
|
||||
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
|
||||
}
|
||||
|
|
@ -93,7 +95,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
public LeashRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
||||
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||
this.updateColor();
|
||||
if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
|
||||
if (pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.setOwner(null);
|
||||
|
|
@ -135,14 +137,43 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
|
||||
if(life <= 40 ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
|
||||
if(this.getOwner() == null) {//未有Owner始终可检
|
||||
return true;
|
||||
}
|
||||
if(life <= 240) {
|
||||
if(pPlayer.isShiftKeyDown()) {
|
||||
if(this.getOwner() != null) {//未有Owner始终可检
|
||||
if(life <= 240) {
|
||||
if(pPlayer.isShiftKeyDown()) {
|
||||
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
|
||||
if(this.ownedBy(pPlayer)) {
|
||||
this.pickup = Pickup.ALLOWED;
|
||||
if(this.equals(leashDataEntity)) {
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
playerLeashable.dropLeash(true, false);
|
||||
}
|
||||
} else {
|
||||
if(life >= 120) {
|
||||
Entity owner = getOwner();
|
||||
if( owner != null ) {
|
||||
// if(this.equals(leashDataEntity)) {
|
||||
if(owner instanceof PlayerLeashable player) {
|
||||
player.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
} else if(owner instanceof Leashable leashable) {
|
||||
leashable.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
|
||||
level().addFreshEntity(itemEntity);
|
||||
discard();
|
||||
// }
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
} else {
|
||||
((ServerPlayer)pPlayer).sendSystemMessage(Component.translatable(PUSH_SHIFT_TO_PICKUP_QUICKLY), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
|
||||
if(this.ownedBy(pPlayer)) {
|
||||
this.pickup = Pickup.ALLOWED;
|
||||
|
|
@ -151,53 +182,23 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
playerLeashable.dropLeash(true, false);
|
||||
}
|
||||
} else {
|
||||
if(life >= 120) {
|
||||
Entity owner = getOwner();
|
||||
if( owner != null ) {
|
||||
// if(this.equals(leashDataEntity)) {
|
||||
if(owner instanceof PlayerLeashable player) {
|
||||
player.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
} else if(owner instanceof Leashable leashable) {
|
||||
leashable.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
|
||||
level().addFreshEntity(itemEntity);
|
||||
discard();
|
||||
// }
|
||||
} else return true;
|
||||
} else return false;
|
||||
}
|
||||
} else {
|
||||
((ServerPlayer)pPlayer).sendSystemMessage(Component.translatable(PUSH_SHIFT_TO_PICKUP_QUICKLY), true);
|
||||
return false;
|
||||
}
|
||||
Entity owner = getOwner();
|
||||
if(owner instanceof PlayerLeashable player) {
|
||||
player.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
} else if(owner instanceof Leashable leashable) {
|
||||
leashable.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
|
||||
level().addFreshEntity(itemEntity);
|
||||
discard();
|
||||
|
||||
}
|
||||
else {
|
||||
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
|
||||
if(this.ownedBy(pPlayer)) {
|
||||
this.pickup = Pickup.ALLOWED;
|
||||
if(this.equals(leashDataEntity)) {
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
playerLeashable.dropLeash(true, false);
|
||||
}
|
||||
} else {
|
||||
Entity owner = getOwner();
|
||||
if(owner instanceof PlayerLeashable player) {
|
||||
player.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
} else if(owner instanceof Leashable leashable) {
|
||||
leashable.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
|
||||
level().addFreshEntity(itemEntity);
|
||||
discard();
|
||||
|
||||
}
|
||||
}
|
||||
} else if (this.pickup != Pickup.CREATIVE_ONLY) this.pickup = Pickup.ALLOWED;
|
||||
else return pPlayer.hasInfiniteMaterials() && this.pickup == Pickup.CREATIVE_ONLY;
|
||||
|
||||
}
|
||||
|
||||
return super.tryPickup(pPlayer);
|
||||
|
|
@ -225,7 +226,6 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
pLiving.addEffect(effectInstance, entity);
|
||||
}
|
||||
}
|
||||
//NOOP
|
||||
}
|
||||
protected ItemStack getOrginalItemStack() {
|
||||
return Items.ARROW.getDefaultInstance();
|
||||
|
|
@ -292,8 +292,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if(leashDataEntity != null) {
|
||||
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashDataEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
leashRopeArrow.setOwner(null);
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
|
||||
|
|
@ -330,14 +329,13 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
|
||||
@Override
|
||||
protected void onHitEntity(@NotNull EntityHitResult pResult) {
|
||||
if(!level().isClientSide()){
|
||||
if (!level().isClientSide()) {
|
||||
Entity entity = pResult.getEntity();
|
||||
hitOnEntityHandler(entity);
|
||||
if(this.getOwner() instanceof LivingEntity livingEntity ) {
|
||||
if (this.getOwner() instanceof LivingEntity livingEntity ) {
|
||||
MobEffectInstance effect = livingEntity.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
|
||||
if(effect != null && effect.getDuration() != 0) {
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
this.setOwner(null);
|
||||
if (effect != null && effect.getDuration() != 0) {
|
||||
this.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
if(entity instanceof LivingEntity livingEntity) {
|
||||
|
|
@ -348,22 +346,19 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if(leashDataEntity != null) {
|
||||
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
leashRopeArrow.setOwner(null);
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
|
||||
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
pL.setLeashedTo(this, true);
|
||||
return;
|
||||
} else if (this.getOwner() instanceof PlayerLeashable pL) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||
if(leashDataEntity != null) {
|
||||
pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
leashRopeArrow.setOwner(null);
|
||||
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
|
|
@ -374,14 +369,13 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
} else {
|
||||
if(entity instanceof Leashable leashable) {
|
||||
if (entity instanceof Leashable leashable) {
|
||||
if (getOwner() == null) {
|
||||
Entity leashDataEntity = leashable.getLeashHolder();
|
||||
if (leashDataEntity != null) {
|
||||
leashable.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
leashRopeArrow.setOwner(null);
|
||||
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
|
|
@ -390,8 +384,8 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if(entity instanceof LivingEntity living) {
|
||||
if(this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
|
||||
if (entity instanceof LivingEntity living) {
|
||||
if (this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
leashable.setLeashedTo(living, true);
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
|
|
@ -407,11 +401,10 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
|
||||
if (getOwner() instanceof PlayerLeashable pL) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||
if(leashDataEntity != null) {
|
||||
if (leashDataEntity != null) {
|
||||
pL.dropLeash(true, true);
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
leashRopeArrow.setOwner(null);
|
||||
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
|
|
@ -421,14 +414,12 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
pL.setLeashedTo(leashKnotFence, true);
|
||||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ItemEntity lead = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.LEAD.getDefaultInstance());
|
||||
this.level().addFreshEntity(lead);
|
||||
}
|
||||
}
|
||||
if(!level().isClientSide()) super.onHitEntity(pResult);
|
||||
}
|
||||
/**
|
||||
* Handles an entity event received from a {@link net.minecraft.network.protocol.game.ClientboundEntityEventPacket}.
|
||||
|
|
@ -459,5 +450,8 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
super.handleEntityEvent(pId);
|
||||
}
|
||||
}
|
||||
|
||||
public void dropLeashHandler() {
|
||||
this.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
this.setOwner(null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,156 @@
|
|||
package com.r3944realms.leashedplayer.content.entities;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import io.github.kunosayo.nestle.entity.NestleLeadNormalEntity;
|
||||
import io.github.kunosayo.nestle.entity.NestleLeadPlayerEntity;
|
||||
import io.github.kunosayo.nestle.entity.data.NestleLeadData;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class NestleRopeArrow extends AbstractArrow {
|
||||
public NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level pLevel) {
|
||||
private static final int maxLifeTime = LeashPlayerCommonConfig.TheNestleArrowMaxLifeTime.get();
|
||||
protected NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level pLevel) {
|
||||
super(pEntityType, pLevel);
|
||||
}
|
||||
public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) {
|
||||
super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||
if (serverPlayer != null && !level().isClientSide) {
|
||||
if(serverPlayer.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) {
|
||||
nestleRopeArrow.removePassenger(serverPlayer);//重置先前的箭矢
|
||||
nestleRopeArrow.setOwner(null);
|
||||
}
|
||||
serverPlayer.startRiding(this);
|
||||
this.setOwner(serverPlayer);
|
||||
} else this.setOwner(null);
|
||||
}
|
||||
|
||||
public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
|
||||
super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||
if (!level().isClientSide) {
|
||||
if(pOwner.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) {
|
||||
nestleRopeArrow.removePassenger(pOwner);//重置先前的箭矢
|
||||
nestleRopeArrow.setOwner(null);
|
||||
}
|
||||
pOwner.startRiding(this);
|
||||
this.setOwner(pOwner);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ItemStack getDefaultPickupItem() {
|
||||
return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
|
||||
}
|
||||
protected ItemStack getOrginalItemStack() {
|
||||
return Items.ARROW.getDefaultInstance();
|
||||
}
|
||||
protected ItemStack getSelfItemStack() {
|
||||
return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
|
||||
}
|
||||
protected void hitOnEntityHandler(Entity pEntity) {
|
||||
//NOOP
|
||||
}
|
||||
@Override
|
||||
public void setOwner(@Nullable Entity pEntity) {
|
||||
boolean isNull = pEntity == null;
|
||||
this.ownerUUID = isNull ? null : pEntity.getUUID();
|
||||
this.cachedOwner = isNull ? null : pEntity;
|
||||
this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tickDespawn() {
|
||||
this.life++;
|
||||
if (this.life >= maxLifeTime) {
|
||||
ItemEntity nestle_arrow_item = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack());
|
||||
this.level().addFreshEntity(nestle_arrow_item);
|
||||
this.discard();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean tryPickup(@NotNull Player pPlayer) {
|
||||
if (life <= 40)
|
||||
return false;
|
||||
else {
|
||||
this.pickup = Pickup.ALLOWED;
|
||||
}
|
||||
return super.tryPickup(pPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
Entity owner = getOwner();
|
||||
if (owner != null && !owner.level().isClientSide) {
|
||||
if (!inGround) {
|
||||
if (owner.getVehicle() == null) owner.startRiding(this);
|
||||
}
|
||||
else {
|
||||
owner.stopRiding();
|
||||
setOwner(null);
|
||||
}
|
||||
}
|
||||
if (this.inGround && this.inGroundTime != 0) {
|
||||
this.level().broadcastEntityEvent(this, (byte)0);
|
||||
this.setPickupItemStack(new ItemStack(getSelfItemStack().getItem()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHitEntity(@NotNull EntityHitResult pResult) {
|
||||
if(!level().isClientSide) {
|
||||
Entity entity = pResult.getEntity();
|
||||
hitOnEntityHandler(entity);
|
||||
Entity owner = this.getOwner();
|
||||
if (owner == null && entity instanceof Player player) {
|
||||
this.setOwner(player);
|
||||
}
|
||||
else if (owner != null && entity != owner ) {
|
||||
if (entity instanceof LivingEntity livingEntity && LeashedPlayer.IS_NESTLE_LOADED) {//保证即使没Nestle 也不会导致使用该物品会抛异常
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
if (livingEntity instanceof Player player) {
|
||||
if (NestleLeadData.isNestle(player, livingEntity)) {
|
||||
arrow.setItem(getSelfItemStack());
|
||||
} else {
|
||||
NestleLeadData.nestleTwo((Player) owner, player);
|
||||
NestleLeadPlayerEntity.inParamFrom = player.getUUID();
|
||||
NestleLeadPlayerEntity.inParamTarget = entity.getUUID();
|
||||
NestleLeadPlayerEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT);
|
||||
}
|
||||
} else {
|
||||
Player player = (Player) owner;
|
||||
if (NestleLeadData.isNestle(player, livingEntity)) {
|
||||
arrow.setItem(getSelfItemStack());
|
||||
} else {
|
||||
NestleLeadData.nestleTwo(player, livingEntity);
|
||||
NestleLeadNormalEntity.inParamFrom = player;
|
||||
NestleLeadNormalEntity.inParamTarget = livingEntity;
|
||||
NestleLeadNormalEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT);
|
||||
NestleLeadNormalEntity.inParamFrom = null;
|
||||
NestleLeadNormalEntity.inParamTarget = null;
|
||||
}
|
||||
|
||||
}
|
||||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
else super.onHitEntity(pResult);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.r3944realms.leashedplayer.content.items.type;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.entities.NestleRopeArrow;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Position;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -19,7 +19,12 @@ import javax.annotation.Nullable;
|
|||
import java.util.List;
|
||||
|
||||
public class NestleRopeArrowItem extends ArrowItem implements INestleRopeArrow {
|
||||
|
||||
public static final String descKey = "item.nestle_rope_arrow.description",
|
||||
DESC_1 = "item.nestle_rope_arrow.desc.1",
|
||||
DESC_2 = "item.nestle_rope_arrow.desc.2",
|
||||
DESC_3 = "item.nestle_rope_arrow.desc.3",
|
||||
DESC_4 = "item.nestle_rope_arrow.desc.4",
|
||||
DESC_5 = "item.nestle_rope_arrow.desc.5";
|
||||
public NestleRopeArrowItem(Item.Properties pProperties) {
|
||||
super(pProperties);
|
||||
}
|
||||
|
|
@ -30,10 +35,18 @@ public class NestleRopeArrowItem extends ArrowItem implements INestleRopeArrow {
|
|||
|
||||
@Override
|
||||
public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) {
|
||||
return new LeashRopeArrow(ModEntityRegister.NESTLE_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, pStack,null, null);
|
||||
NestleRopeArrow arrow = new NestleRopeArrow(ModEntityRegister.NESTLE_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, pStack, null, null);
|
||||
arrow.pickup = AbstractArrow.Pickup.DISALLOWED;
|
||||
return arrow;
|
||||
}
|
||||
|
||||
public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
|
||||
|
||||
pTooltipComponents.addAll(List.of(
|
||||
Component.translatable(DESC_1),
|
||||
Component.translatable(DESC_2),
|
||||
Component.translatable(DESC_3),
|
||||
Component.translatable(DESC_4),
|
||||
Component.translatable(DESC_5)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
|||
import com.r3944realms.leashedplayer.content.gamerules.Server.*;
|
||||
import com.r3944realms.leashedplayer.content.items.ModCreativeTab;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.content.items.type.LeadBreakerItem;
|
||||
import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem;
|
||||
import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem;
|
||||
import com.r3944realms.leashedplayer.content.items.type.TippedLeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.items.type.*;
|
||||
import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister;
|
||||
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModPaintingVariants;
|
||||
import com.r3944realms.leashedplayer.network.server.Code;
|
||||
|
|
@ -59,6 +56,12 @@ public enum ModLangKeyValue {
|
|||
DESC_ITEM_S_LEASH_R_ARROW_THREE(SpectralLeashRopeArrowItem.DESC, ModPartEnum.DESCRIPTION, "§c2.§r Strike the entity to give it a §e§lGlowing§r effect.", "§c2.§r 击中实体给与其§e§l发光§7(§e§lGlowing§7)§r效果", "擊中實體給予其§e§l發光§7(§e§lGlowing§7)§r效果", false),
|
||||
DESC_ITEM_T_LEASH_R_ARROW_THREE(TippedLeashRopeArrow.DESC, ModPartEnum.DESCRIPTION, "§c2.§rStrike the entity to give it a Potion effect.", "§c2.§r 击中实体给与其药水效果", "擊中實體給予其药水效果", false),
|
||||
DESC_ITEM_LEAD_BREAKER(LeadBreakerItem.HOVER_KEY, ModPartEnum.DESCRIPTION, "§7can break the link of leash", "§7可以破坏拴绳链接", "§7可以破壞拴繩鏈接", false),
|
||||
DESC_ITEM_NESTLE_R_ARROW_ONE(NestleRopeArrowItem.DESC_1, ModPartEnum.DESCRIPTION, "§7This arrow will carry the owner along with its flight:", "§7该箭将会携带拥有者随其飞行", "§7該箭將會攜帶擁有者隨其飛行:", false),
|
||||
DESC_ITEM_NESTLE_R_ARROW_TWO(NestleRopeArrowItem.DESC_2, ModPartEnum.DESCRIPTION, "§c1.§r If it hits an entity, it will leash the owner with the entity and drop as a normal arrow;", "§c1.§r 若击中生物时,将持有者与其拴在一起并已普通箭形式掉落;", "§c1.§r 若擊中生物時,將持有者與其拴在一起其上並以普通箭的形式掉落;", false),
|
||||
DESC_ITEM_NESTLE_R_ARROW_THREE(NestleRopeArrowItem.DESC_3, ModPartEnum.DESCRIPTION, "§c2.§r When fired from its launcher, the first player hit will become the arrow's owner and will fly along with it.", "§c2.§r 当前其发射器里发射,第一个射中的玩家将成为此箭的持有者并随箭飞行.", "§c2.§r 當箭從發射器發射時,第一個射中的玩家將成為此箭的持有者並隨箭飛行;", false),
|
||||
DESC_ITEM_NESTLE_R_ARROW_FORE(NestleRopeArrowItem.DESC_4, ModPartEnum.DESCRIPTION, "", "", "", false),
|
||||
DESC_ITEM_NESTLE_R_ARROW_FIVE(NestleRopeArrowItem.DESC_5, ModPartEnum.DESCRIPTION, "", "", "", false),
|
||||
|
||||
//PAINTING
|
||||
GROUP_PHOTO_TITLE(ModPaintingVariants.getPaintingVariantTitleKey(ModPaintingVariants.GROUP_PHOTO),ModPartEnum.TITLE, "§dGroup Photo §7[§6memorable§7]§r", "§d集体照 §7[§6纪念§7]§r", "§d集體照 §7[§6紀念§7]§r", false),
|
||||
GROUP_PHOTO_AUTHOR(ModPaintingVariants.getPaintingVariantAuthorKey(ModPaintingVariants.GROUP_PHOTO),ModPartEnum.AUTHOR, "§9Leisure §4Time §eDock§r","§9闲趣§4时§e坞§r","§9閑趣§4時§e塢§r",false),
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.integration.jei;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@JeiPlugin
|
||||
public class JEIPlugin implements IModPlugin {
|
||||
private static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "jei_plugin");
|
||||
@Override
|
||||
public @NotNull ResourceLocation getPluginUid() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerRecipes(@NotNull IRecipeRegistration registration) {
|
||||
var level = Minecraft.getInstance().level;
|
||||
assert level != null;
|
||||
var recipeManager = level.getRecipeManager();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.integration.jei;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.items.repcipe.TippedLeashRopeArrowRecipe;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
|
||||
public class JEIRecipeTypes {
|
||||
public static final RecipeType<TippedLeashRopeArrowRecipe.TippedLeashRopeArrowARecipe> TIPPED_LEASH_ROPE_ARROW_A =
|
||||
RecipeType.create(LeashedPlayer.MOD_ID, "tipped_leash_rope_arrow_a", TippedLeashRopeArrowRecipe.TippedLeashRopeArrowARecipe.class);
|
||||
|
||||
public static final RecipeType<TippedLeashRopeArrowRecipe.TippedLeashRopeArrowBRecipe> TIPPED_LEASH_ROPE_ARROW_B =
|
||||
RecipeType.create(LeashedPlayer.MOD_ID, "tipped_leash_rope_arrow_b", TippedLeashRopeArrowRecipe.TippedLeashRopeArrowBRecipe.class);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.integration.jei.category;
|
||||
|
||||
public class LeashedPlayerCategory {
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.r3944realms.leashedplayer.mixin.both;
|
|||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
|
|
@ -12,7 +11,6 @@ import net.minecraft.network.syncher.EntityDataAccessor;
|
|||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
|
|
@ -21,7 +19,6 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
|
|||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -30,10 +27,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(Player.class)
|
||||
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable, ILivingEntityExtension {
|
||||
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable, ILivingEntityExtension {
|
||||
|
||||
@Unique
|
||||
protected int Pl$LeashKeepTick;//保存状态,当超过断裂绳长时若LeashKeepTick大于0,则不断裂
|
||||
|
|
@ -106,87 +102,15 @@ public abstract class
|
|||
return;
|
||||
}
|
||||
|
||||
float leashLength = LeashCommand.MIN_VALUE;
|
||||
if (restrainedEntity instanceof ILivingEntityExtension iEntity) {
|
||||
// 获取绳长
|
||||
float leashLengthFormValue = iEntity.getLeashLength();
|
||||
leashLength = leashLengthFormValue > LeashCommand.MIN_VALUE ? leashLengthFormValue : LeashCommand.MIN_VALUE;
|
||||
}
|
||||
|
||||
// 两者距离
|
||||
float distance = holderEntity.distanceTo(restrainedEntity);
|
||||
Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity;
|
||||
|
||||
// 仅当距离大于绳长时施加拉力
|
||||
if (applyMovementEntity != null && distance > leashLength) {
|
||||
// 计算朝向持有者的拉力方向
|
||||
double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance;
|
||||
double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance;
|
||||
double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance;
|
||||
|
||||
// 拉力大小,距离越远拉力越强,但施加一个最大限制
|
||||
double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力
|
||||
applyMovementEntity.setDeltaMovement(
|
||||
applyMovementEntity.getDeltaMovement().add(
|
||||
dX * pullStrength,
|
||||
dY * pullStrength,
|
||||
dZ * pullStrength
|
||||
)
|
||||
);
|
||||
|
||||
// 控制速度不要过快,避免偏激移动
|
||||
Whimsy$Brake(applyMovementEntity, entity -> {
|
||||
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||
entity.setDeltaMovement(
|
||||
Math.min(Math.abs(deltaMovement.x), 1.0) * Math.signum(deltaMovement.x),
|
||||
Math.min(Math.abs(deltaMovement.y), 1.0) * Math.signum(deltaMovement.y),
|
||||
Math.min(Math.abs(deltaMovement.z), 1.0) * Math.signum(deltaMovement.z)
|
||||
);
|
||||
entity.hurtMarked = true;
|
||||
});
|
||||
}
|
||||
PlayerLeashable.legacyElasticRangeLeashBehaviour(holderEntity, restrainedEntity);
|
||||
|
||||
// 降低坠落伤害
|
||||
restrainedEntity.checkSlowFallDistance();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 刹车(
|
||||
* @param pEntity 刹车的实体
|
||||
* @param pMaxX X方向的最大动量
|
||||
* @param pMaxY Y方向的最大动量
|
||||
* @param pMaxZ Z方向的最大动量
|
||||
*/
|
||||
@Unique
|
||||
private static void Whimsy$Brake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) {
|
||||
Vec3 deltaMovement = pEntity.getDeltaMovement();
|
||||
double dX = Math.abs(deltaMovement.x) > pMaxX ? 0 : deltaMovement.x;
|
||||
double dY = Math.abs(deltaMovement.y) > pMaxY ? 0 : deltaMovement.y;
|
||||
double dZ = Math.abs(deltaMovement.z) > pMaxZ ? 0 : deltaMovement.z;
|
||||
pEntity.setDeltaMovement(dX, dY,dZ);
|
||||
pEntity.hurtMarked = true;
|
||||
}
|
||||
/**
|
||||
* 刹车(
|
||||
* @param pEntity 刹车的实体
|
||||
* @param pOpt 自定义规则
|
||||
*/
|
||||
@Unique
|
||||
private static void Whimsy$Brake(Entity pEntity, @Nullable Consumer<Entity> pOpt) {
|
||||
Consumer<Entity> consumer = pOpt;
|
||||
if(pOpt == null) {
|
||||
consumer = entity -> {
|
||||
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||
double dX = Math.abs(deltaMovement.x) > 1 ? 0 : deltaMovement.x;
|
||||
double dY = Math.abs(deltaMovement.y) > 1 ? 0 : deltaMovement.y;
|
||||
double dZ = Math.abs(deltaMovement.z) > 1 ? 0 : deltaMovement.z;
|
||||
entity.setDeltaMovement(dX, dY,dZ);
|
||||
entity.hurtMarked = true;
|
||||
};
|
||||
}
|
||||
consumer.accept(pEntity);
|
||||
}
|
||||
|
||||
|
||||
@Unique
|
||||
protected void Pl$tickLeash() {
|
||||
if(this.Pl$LeashData == null) return;//没有Data直接退出
|
||||
|
|
@ -203,12 +127,6 @@ public abstract class
|
|||
ILivingEntityExtension iEntityExtension = this;//获取设定值
|
||||
float leashLengthSelf = iEntityExtension.getLeashLength();
|
||||
leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE;
|
||||
MobEffectInstance effect = this.getEffect(ModEffectRegister.NO_LEASH_EFFECT);
|
||||
if(effect != null && effect.getDuration() != 0) {
|
||||
if (entity instanceof LeashRopeArrow arrow)
|
||||
arrow.setOwner(null);
|
||||
this.dropLeash(true, !(entity instanceof LeashRopeArrow));
|
||||
}
|
||||
if (entity != null) {
|
||||
double breakDistanceTime = (entity instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||
if(!isAlive() || !entity.isAlive() ||( distanceTo(entity) > Math.max(leashLength * breakDistanceTime, LeashCommand.MIN_VALUE * breakDistanceTime) && keepLeashTick == 0)){
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.r3944realms.leashedplayer.mixin.item;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
|
@ -46,6 +47,9 @@ public class MixinLeadItem implements Equipable {
|
|||
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
|
||||
if(leashDataEntity != null) {
|
||||
playerLeashable.dropLeash(true, true);
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
//获取拴绳结实体
|
||||
LeashFenceKnotEntity leashfenceknotentity = LeashFenceKnotEntity.getOrCreateKnot(pLevel, pPos);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.r3944realms.leashedplayer.modInterface;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
|
@ -10,6 +12,7 @@ import net.minecraft.world.entity.Leashable;
|
|||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -61,6 +64,72 @@ public interface PlayerLeashable extends Leashable {
|
|||
//这边覆写去掉了乘坐相关的逻辑,即乘坐状态下也可以正常被栓住,不影响其乘坐状态
|
||||
|
||||
}
|
||||
static void legacyElasticRangeLeashBehaviour(Entity holderEntity, Entity restrainedEntity) {
|
||||
float leashLength = LeashCommand.MIN_VALUE;
|
||||
if (restrainedEntity instanceof ILivingEntityExtension iEntity) {
|
||||
// 获取绳长
|
||||
float leashLengthFormValue = iEntity.getLeashLength();
|
||||
leashLength = leashLengthFormValue > LeashCommand.MIN_VALUE ? leashLengthFormValue : LeashCommand.MIN_VALUE;
|
||||
}
|
||||
|
||||
// 两者距离
|
||||
float distance = holderEntity.distanceTo(restrainedEntity);
|
||||
Entity applyMovementEntity = restrainedEntity.isPassenger() ? restrainedEntity.getVehicle() : restrainedEntity;
|
||||
// 仅当距离大于绳长时施加拉力
|
||||
if (applyMovementEntity != null && distance > leashLength) {
|
||||
MethodA(holderEntity, applyMovementEntity, distance, leashLength);
|
||||
// 控制速度不要过快,避免偏激移动
|
||||
Util.MovementBrake(applyMovementEntity, entity -> {
|
||||
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||
entity.setDeltaMovement(
|
||||
Math.min(Math.abs(deltaMovement.x), 1.0) * Math.signum(deltaMovement.x),
|
||||
Math.min(Math.abs(deltaMovement.y), 1.0) * Math.signum(deltaMovement.y),
|
||||
Math.min(Math.abs(deltaMovement.z), 1.0) * Math.signum(deltaMovement.z)
|
||||
);
|
||||
entity.hurtMarked = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
private static void MethodA(Entity holderEntity, Entity applyMovementEntity, float distance, float leashLength) {
|
||||
// 计算朝向持有者的拉力方向
|
||||
double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance;
|
||||
double dY = (holderEntity.getY() - applyMovementEntity.getY()) / (double) distance;
|
||||
double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance;
|
||||
|
||||
// 拉力大小,距离越远拉力越强,但施加一个最大限制
|
||||
double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力
|
||||
applyMovementEntity.setDeltaMovement(
|
||||
applyMovementEntity.getDeltaMovement().add(
|
||||
dX * pullStrength,
|
||||
dY * pullStrength,
|
||||
dZ * pullStrength
|
||||
)
|
||||
);
|
||||
}
|
||||
private static void MethodB(Entity holderEntity, Entity applyMovementEntity, float distance, float leashLength) {
|
||||
// 计算朝向持有者的拉力方向
|
||||
double dX = (holderEntity.getX() - applyMovementEntity.getX()) / (double) distance;
|
||||
double dZ = (holderEntity.getZ() - applyMovementEntity.getZ()) / (double) distance;
|
||||
|
||||
// 稳定点的目标高度
|
||||
double targetY = holderEntity.getY() + 1.0; // 根据需要调整目标高度
|
||||
double currentY = applyMovementEntity.getY();
|
||||
double heightDifference = targetY - currentY;
|
||||
|
||||
// 控制垂直方向的拉力
|
||||
double dY = heightDifference > 0.5 ? 0.1 : (heightDifference < -0.5 ? -0.1 : 0);
|
||||
|
||||
// 拉力大小,距离越远拉力越强,但施加一个最大限制
|
||||
double pullStrength = Math.min((distance - leashLength) * 0.1, 1.0); // 限制最大拉力
|
||||
applyMovementEntity.setDeltaMovement(
|
||||
applyMovementEntity.getDeltaMovement().add(
|
||||
dX * pullStrength,
|
||||
dY,
|
||||
dZ * pullStrength
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Entity getLeashDataEntity(@NotNull ServerPlayer serverPlayer , @NotNull ServerLevel serverLevel) {
|
||||
LeashData leashDataFromEntityData = ((PlayerLeashable) serverPlayer).getLeashDataFromEntityData();
|
||||
|
|
|
|||
|
|
@ -41,13 +41,15 @@ public record DecreaseLeashRopeLength(Code code, String playerUUID) implements C
|
|||
if ((leashDataEntity != null && code == Code.OTHER_ST && leashDataEntity == player ) || (leashDataEntity != null && code == Code.OTHER_ST)) {
|
||||
float newValue = Math.max(Math.min(entityExtension.getLeashLength() - 1, LeashedPlayer.M4()), LeashedPlayer.M3());
|
||||
entityExtension.setLeashLength(newValue);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(DECREASE_LEASH_ROPE_LENGTH, playerByUUID.getDisplayName(), newValue), true);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(DECREASE_SELF_LEASH_ROPE_LENGTH, newValue), true);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(DECREASE_LEASH_ROPE_LENGTH, playerByUUID.getDisplayName(), newValue), true);
|
||||
} else if (code == Code.SELF) {
|
||||
float newValue = Math.max(Math.min(entityExtension.getLeashLength() - 1, LeashedPlayer.M4()), LeashedPlayer.M3());
|
||||
entityExtension.setLeashLength(newValue);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(DECREASE_SELF_LEASH_ROPE_LENGTH, newValue), true);
|
||||
} else {
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,13 +42,16 @@ public record IncreaseLeashRopeLength(Code code, String playerUUID) implements C
|
|||
if ((leashDataEntity != null && code == Code.OTHER_ST && leashDataEntity == player ) || (leashDataEntity != null && code == Code.OTHER_ST)) {
|
||||
float newValue = Math.max(Math.min(entityExtension.getLeashLength() + 1, LeashedPlayer.M4()), LeashedPlayer.M3());
|
||||
entityExtension.setLeashLength(newValue);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(INCREASE_LEASH_ROPE_LENGTH, playerByUUID.getDisplayName(), newValue), true);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(INCREASE_SELF_LEASH_ROPE_LENGTH, newValue), true);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(INCREASE_LEASH_ROPE_LENGTH, playerByUUID.getDisplayName(), newValue), true);
|
||||
} else if (code == Code.SELF) {
|
||||
float newValue = Math.max(Math.min(entityExtension.getLeashLength() + 1, LeashedPlayer.M4()), LeashedPlayer.M3());
|
||||
entityExtension.setLeashLength(newValue);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(INCREASE_SELF_LEASH_ROPE_LENGTH, newValue), true);
|
||||
} else {
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import java.io.File;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.r3944realms.leashedplayer.utils.Logger.logger;
|
||||
|
|
@ -98,4 +99,38 @@ public class Util {
|
|||
}
|
||||
else return null;
|
||||
}
|
||||
/**
|
||||
* 刹车(
|
||||
* @param pEntity 刹车的实体
|
||||
* @param pMaxX X方向的最大动量
|
||||
* @param pMaxY Y方向的最大动量
|
||||
* @param pMaxZ Z方向的最大动量
|
||||
*/
|
||||
public static void MovementBrake(Entity pEntity, double pMaxX, double pMaxY, double pMaxZ) {
|
||||
Vec3 deltaMovement = pEntity.getDeltaMovement();
|
||||
double dX = Math.abs(deltaMovement.x) > pMaxX ? 0 : deltaMovement.x;
|
||||
double dY = Math.abs(deltaMovement.y) > pMaxY ? 0 : deltaMovement.y;
|
||||
double dZ = Math.abs(deltaMovement.z) > pMaxZ ? 0 : deltaMovement.z;
|
||||
pEntity.setDeltaMovement(dX, dY,dZ);
|
||||
pEntity.hurtMarked = true;
|
||||
}
|
||||
/**
|
||||
* 刹车(
|
||||
* @param pEntity 刹车的实体
|
||||
* @param pOpt 自定义规则
|
||||
*/
|
||||
public static void MovementBrake(Entity pEntity, @javax.annotation.Nullable Consumer<Entity> pOpt) {
|
||||
Consumer<Entity> consumer = pOpt;
|
||||
if(pOpt == null) {
|
||||
consumer = entity -> {
|
||||
Vec3 deltaMovement = entity.getDeltaMovement();
|
||||
double dX = Math.abs(deltaMovement.x) > 1 ? 0 : deltaMovement.x;
|
||||
double dY = Math.abs(deltaMovement.y) > 1 ? 0 : deltaMovement.y;
|
||||
double dZ = Math.abs(deltaMovement.z) > 1 ? 0 : deltaMovement.z;
|
||||
entity.setDeltaMovement(dX, dY,dZ);
|
||||
entity.hurtMarked = true;
|
||||
};
|
||||
}
|
||||
consumer.accept(pEntity);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 63 KiB |
Loading…
Reference in New Issue
Block a user