支持其它生物,待修复渲染和箭矢功能异常BUG
This commit is contained in:
parent
9de55bd40d
commit
557795ab02
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 NeoForged project
|
||||
Copyright (c) 2025 R3944Realms
|
||||
|
||||
This license applies to the template files as supplied by github.com/NeoForged/MDK
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
plugins {
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.184'
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.185'
|
||||
}
|
||||
|
||||
tasks.named('wrapper', Wrapper).configure {
|
||||
|
|
|
|||
|
|
@ -7,26 +7,26 @@ org.gradle.configuration-cache=false
|
|||
|
||||
#read more on this at https://github.com/neoforged/NeoGradle/blob/NG_7.0/README.md#apply-parchment-mappings
|
||||
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
|
||||
neogradle.subsystems.parchment.minecraftVersion=1.21.4
|
||||
neogradle.subsystems.parchment.mappingsVersion=2025.03.23
|
||||
neogradle.subsystems.parchment.minecraftVersion=1.21.5
|
||||
neogradle.subsystems.parchment.mappingsVersion=2025.06.15
|
||||
# Environment Properties
|
||||
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
|
||||
# The Minecraft version must agree with the Neo version to get a valid artifact
|
||||
minecraft_version=1.21.5
|
||||
minecraft_version=1.21.6
|
||||
# The Minecraft version range can use any release version of Minecraft as bounds.
|
||||
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
|
||||
# as they do not follow standard versioning conventions.
|
||||
minecraft_version_range=[1.21.5]
|
||||
minecraft_version_range=[1.21.6]
|
||||
# The Neo version must agree with the Minecraft version to get a valid artifact
|
||||
neo_version=21.5.30-beta
|
||||
neo_version=21.6.0-beta
|
||||
# The Neo version range can use any version of Neo as bounds
|
||||
neo_version_range=[21.5.30-beta,)
|
||||
neo_version_range=[21.6.0-beta,)
|
||||
# The loader version range can only use the major version of FML as bounds
|
||||
loader_version_range=[1,)
|
||||
|
||||
## Mod Properties
|
||||
|
||||
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
|
||||
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
|
||||
# Must match the String constant located in the main mod class annotated with @Mod.
|
||||
mod_id=leashedplayer
|
||||
# The human-readable display name for the mod.
|
||||
|
|
|
|||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.12-bin.zip
|
||||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.14.2-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ pluginManagement {
|
|||
mavenLocal()
|
||||
gradlePluginPortal()
|
||||
maven { url = 'https://maven.neoforged.net/releases' }
|
||||
maven { url = 'https://maven.parchmentmc.org' } // Add this line
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0405054 Registries
|
||||
// 1.21.6 2025-06-18T18:13:35.4577733 Registries
|
||||
f2536789df7f06362718a59ba4a96890e2f9b8aa data/leashedplayer/jukebox_song/what_does_the_fox_say.json
|
||||
84106976f4f71012fc5bd1784303a0d135623c77 data/leashedplayer/painting_variant/group_photo.json
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// 1.21.5 2025-03-29T16:40:02.9875592 Tags for minecraft:item mod id leashedplayer
|
||||
// 1.21.6 2025-06-18T18:13:35.4379687 Tags for minecraft:item mod id leashedplayer
|
||||
84707301f1fe2490a899deb51302d413cfff5a89 data/c/tags/item/tools/shear.json
|
||||
bde6ca31173d1f22d5f6fe355dc90c9faa35b239 data/minecraft/tags/item/amethyst_tool_materials.json
|
||||
63e4ad58dc8397171f84264d53dfe4fb503c7b1e data/minecraft/tags/item/arrows.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0435015 Languages: en_us for mod: leashedplayer
|
||||
2c7f061dfc276db13135adce15c68cfc145ccf37 assets/leashedplayer/lang/en_us.json
|
||||
// 1.21.6 2025-06-18T18:13:35.4587797 Languages: en_us for mod: leashedplayer
|
||||
0d9f238cc355f438904865d0105ea2288d8ab5ba assets/leashedplayer/lang/en_us.json
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0112992 Tags for minecraft:block mod id leashedplayer
|
||||
// 1.21.6 2025-06-18T18:13:35.4478159 Tags for minecraft:block mod id leashedplayer
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0510463 Sound Definitions
|
||||
// 1.21.6 2025-06-18T18:13:35.4661082 Sound Definitions
|
||||
81f1cc9f404c2670bf7cc679107177ffb0b48c77 assets/leashedplayer/sounds.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0163693 Tags for minecraft:painting_variant mod id leashedplayer
|
||||
// 1.21.6 2025-06-18T18:13:35.4508133 Tags for minecraft:painting_variant mod id leashedplayer
|
||||
e081a053d7c2f2d3238cf38436185ef23d234505 data/minecraft/tags/painting_variant/placeable.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21.5 2025-03-29T16:40:02.9987109 Languages: lzh for mod: leashedplayer
|
||||
// 1.21.6 2025-06-18T18:13:35.4409646 Languages: lzh for mod: leashedplayer
|
||||
7536eb6d1c69695c06ebb9da5b57a391174b02cb assets/leashedplayer/lang/lzh.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0306291 Languages: zh_cn for mod: leashedplayer
|
||||
f7bcf89907a8ca5f575e4b519d53cd0628bb1e6b assets/leashedplayer/lang/zh_cn.json
|
||||
// 1.21.6 2025-06-18T18:13:35.4553638 Languages: zh_cn for mod: leashedplayer
|
||||
bd16693f46f05f6bd5d6b9cb26a8bf7c460d34b9 assets/leashedplayer/lang/zh_cn.json
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0040344 LeashedPlayer Recipes
|
||||
// 1.21.6 2025-06-18T18:13:35.4448617 LeashedPlayer Recipes
|
||||
13ebe9a580731296eb10c05d1844657d58e07cc1 data/leashedplayer/advancement/recipes/misc/amethyst_shears.json
|
||||
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
|
||||
a26d63c2360b32df0b636a5dec96dd919139e022 data/leashedplayer/advancement/recipes/misc/spectral_leash_rope_arrow.json
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0481 Model Definitions - leashedplayer
|
||||
// 1.21.6 2025-06-18T18:13:35.4621401 Model Definitions - leashedplayer
|
||||
4239e6d8ef328b74d7ea1a48309758fe7979861c assets/leashedplayer/blockstates/test_block.json
|
||||
d213db38f45b911f2023c83e15b018371a630ae0 assets/leashedplayer/items/amethyst_shears.json
|
||||
bc53c9feb22db83882974d60456bef0d3ef3ef5e assets/leashedplayer/items/fabric.json
|
||||
e4e426067245e93d282a3d953c420fca04c23f3d assets/leashedplayer/items/leash_rope_arrow.json
|
||||
6151e1b11ec884d511b2fd595e39c9f12674e824 assets/leashedplayer/items/spectral_leash_rope_arrow.json
|
||||
e08c92045a5fb984dee259c719ddd6b3a3f06615 assets/leashedplayer/items/test_block_item.json
|
||||
1b914911c9077563701e9ac4b7f8c425f6eff4ee assets/leashedplayer/items/tipped_leash_rope_arrow.json
|
||||
149b31dffff370f181edceef0284696c0ab31130 assets/leashedplayer/models/block/test_block.json
|
||||
766c487fbf0c59e9045eeaf81daf583eb679b0e1 assets/leashedplayer/models/item/amethyst_shears.json
|
||||
5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json
|
||||
845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json
|
||||
|
|
@ -12,6 +15,7 @@ e4e426067245e93d282a3d953c420fca04c23f3d assets/leashedplayer/items/leash_rope_a
|
|||
bb0d76077719c83c8a8bd4346a24ea1766175125 assets/leashedplayer/models/item/fabric.json
|
||||
114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json
|
||||
c4748995a5fe190d20e3bd16f4b2244164ec0f83 assets/leashedplayer/models/item/spectral_leash_rope_arrow.json
|
||||
de0da544ae0eaab40c8560af30ceb760dded3758 assets/leashedplayer/models/item/test_block_item.json
|
||||
ba065b1a88d82f95e10d026bf7bfdac7923de24c assets/leashedplayer/models/item/tipped_leash_rope_arrow.json
|
||||
fe3d4b8fd83f9ba4e2a951ec2e23ea98a347c2cc assets/minecraft/items/bow.json
|
||||
12be767d961ae273ae0968ad06f022b57afbb0b0 assets/minecraft/items/crossbow.json
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// 1.21.5 2025-03-30T19:34:30.4253532 Advancements
|
||||
// 1.21.6 2025-06-18T18:13:35.4686422 Advancements
|
||||
4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json
|
||||
f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json
|
||||
bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0241113 Languages: zh_tw for mod: leashedplayer
|
||||
c23825af72a73bc54b72ad3817acb5a03d299375 assets/leashedplayer/lang/zh_tw.json
|
||||
// 1.21.6 2025-06-18T18:13:35.4528154 Languages: zh_tw for mod: leashedplayer
|
||||
112cc45974d69bb6427982c2e8c906d300e91585 assets/leashedplayer/lang/zh_tw.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "leashedplayer:block/test_block"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/test_block_item"
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
"advancement.leashedplayer.no_leash.desc": "You cannot be leashed by ANY",
|
||||
"advancement.leashedplayer.tipped_leash_arrow": "God said there should be more arrows",
|
||||
"advancement.leashedplayer.tipped_leash_arrow.desc": "A dazzling array of Leash Rope arrows",
|
||||
"block.leashedplayer.test_block": "Test Block",
|
||||
"creativetab.leashedplayer.leashedplayer_tab": "Leashed Player",
|
||||
"effect.leashedplayer.no_leash": "No Leash",
|
||||
"entity.leashedplayer.kid_player": "Kid",
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
"item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
|
||||
"item.leashedplayer.neoforge": "NeoForge",
|
||||
"item.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow",
|
||||
"item.leashedplayer.test_block_item": "Test Block",
|
||||
"item.minecraft.lingering_potion.effect.no_leash": "Splash No Leash Potion",
|
||||
"item.minecraft.potion.effect.no_leash": "No Leash Potion",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "Splash No Leash Potion",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"advancement.leashedplayer.no_leash.desc": "你不会被任何东西拴住",
|
||||
"advancement.leashedplayer.tipped_leash_arrow": "神说要有更多箭矢",
|
||||
"advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅满目啊",
|
||||
"block.leashedplayer.test_block": "测试方块",
|
||||
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
|
||||
"effect.leashedplayer.no_leash": "禁拴",
|
||||
"entity.leashedplayer.kid_player": "小孩",
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
"item.leashedplayer.leash_rope_arrow": "拴绳箭",
|
||||
"item.leashedplayer.neoforge": "NeoForge",
|
||||
"item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
|
||||
"item.leashedplayer.test_block_item": "测试方块",
|
||||
"item.minecraft.lingering_potion.effect.no_leash": "滞留型禁拴药水",
|
||||
"item.minecraft.potion.effect.no_leash": "禁拴药水",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"advancement.leashedplayer.no_leash.desc": "恁不會被任何拴住",
|
||||
"advancement.leashedplayer.tipped_leash_arrow": "神說要有更多箭矢",
|
||||
"advancement.leashedplayer.tipped_leash_arrow.desc": "真是琳琅滿目啊",
|
||||
"block.leashedplayer.test_block": "測試方塊",
|
||||
"creativetab.leashedplayer.leashedplayer_tab": "可拴玩家",
|
||||
"effect.leashedplayer.no_leash": "禁拴",
|
||||
"entity.leashedplayer.kid_player": "小孩",
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
"item.leashedplayer.leash_rope_arrow": "拴繩箭",
|
||||
"item.leashedplayer.neoforge": "NeoForge",
|
||||
"item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
|
||||
"item.leashedplayer.test_block_item": "測試方塊",
|
||||
"item.minecraft.lingering_potion.effect.no_leash": "滯留型禁拴藥水",
|
||||
"item.minecraft.potion.effect.no_leash": "禁拴藥水",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "leashedplayer:block/test_block"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/test_block_item"
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ public class ClientEventHandler {
|
|||
assert player != null;
|
||||
if (ModKeyMapping.KEY_ADD_LEASH_LENGTH.isDown()) {
|
||||
PlayerLeashable playerLeashable = (PlayerLeashable) player;
|
||||
if (playerLeashable.getLeashDataFromEntityData() == null) {
|
||||
if (playerLeashable.getLeashData() == null) {
|
||||
assert minecraft.level != null;
|
||||
List<HitResult> refLookAtEntityHitResult = Util.getRefLookAtEntityHitResult(player, minecraft.level, 32, entity -> entity instanceof LivingEntity);
|
||||
Entity theNearestEntityFromHitResultList = Util.getTheNearestEntityFromHitResultList(player, refLookAtEntityHitResult);
|
||||
|
|
@ -65,13 +65,13 @@ public class ClientEventHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (playerLeashable.getLeashDataFromEntityData() != null) {
|
||||
if (playerLeashable.getLeashData() != null) {
|
||||
PacketDistributor.sendToServer(new IncreaseLeashRopeLength(Code.SELF, player.getStringUUID()));
|
||||
}
|
||||
}
|
||||
if (ModKeyMapping.KEY_SUB_LEASH_LENGTH.isDown()) {
|
||||
PlayerLeashable playerLeashable = (PlayerLeashable) player;
|
||||
if (playerLeashable.getLeashDataFromEntityData() == null) {
|
||||
if (playerLeashable.getLeashData() == null) {
|
||||
assert minecraft.level != null;
|
||||
List<HitResult> refLookAtEntityHitResult = Util.getRefLookAtEntityHitResult(player, minecraft.level, 32, entity -> entity instanceof LivingEntity);
|
||||
Entity theNearestEntityFromHitResultList = Util.getTheNearestEntityFromHitResultList(player, refLookAtEntityHitResult);
|
||||
|
|
@ -81,7 +81,7 @@ public class ClientEventHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (playerLeashable.getLeashDataFromEntityData() != null) {
|
||||
if (playerLeashable.getLeashData() != null) {
|
||||
PacketDistributor.sendToServer(new DecreaseLeashRopeLength(Code.SELF, player.getStringUUID()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,32 @@
|
|||
package com.r3944realms.leashedplayer;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.r3944realms.leashedplayer.content.blocks.ModBlocksRegister;
|
||||
import com.r3944realms.leashedplayer.content.blocks.entity.ItemMemoryBlockEntity;
|
||||
import com.r3944realms.leashedplayer.content.capabilities.ModCapabilities;
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.content.commands.MotionCommand;
|
||||
import com.r3944realms.leashedplayer.content.commands.TickCommand;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.network.client.SyncLeashRopeLength;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.animal.Fox;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.alchemy.PotionBrewing;
|
||||
|
|
@ -26,10 +36,16 @@ import net.minecraft.world.level.block.DispenserBlock;
|
|||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
import net.neoforged.neoforge.event.AnvilUpdateEvent;
|
||||
import net.neoforged.neoforge.event.RegisterCommandsEvent;
|
||||
import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.neoforged.neoforge.event.tick.EntityTickEvent;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class CommonEventHandler {
|
||||
|
|
@ -47,6 +63,7 @@ public class CommonEventHandler {
|
|||
PotionBrewing.Builder builder = event.getBuilder();
|
||||
builder.addMix(Potions.WATER, Items.SLIME_BALL, ModPotionRegister.NO_LEASH);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void OnLivingTickEvent(EntityTickEvent.Post event) {
|
||||
Entity entity = event.getEntity();
|
||||
|
|
@ -74,19 +91,67 @@ public class CommonEventHandler {
|
|||
|
||||
}
|
||||
}
|
||||
if (entity instanceof Leashable leashable) {
|
||||
IEntityLeadExtension leadExtension = (IEntityLeadExtension) entity;
|
||||
if (leashable.isLeashed() && leadExtension.hasLeadLengthSync()) {
|
||||
PacketDistributor.sendToAllPlayers(
|
||||
new SyncLeashRopeLength(entity.getUUID().toString(), leadExtension.getLeashLength())
|
||||
);
|
||||
leadExtension.setLeadLengthSync(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void onBlockInteract(PlayerInteractEvent.RightClickBlock event) {
|
||||
Level level = event.getLevel();
|
||||
BlockPos pos = event.getPos();
|
||||
Player player = event.getEntity();
|
||||
ItemStack heldItem = player.getItemInHand(event.getHand());
|
||||
if (level.getBlockEntity(pos) instanceof ItemMemoryBlockEntity be) {
|
||||
if(level.isClientSide) event.setCanceled(true);
|
||||
// 阻止默认操作(如打开GUI)
|
||||
event.setCanceled(true);
|
||||
if (!heldItem.isEmpty()) {
|
||||
// 如果手持物品,记忆并复制
|
||||
be.setMemorizedItem(heldItem);
|
||||
copyAndDropItem(level, pos, heldItem.copy());
|
||||
} else {
|
||||
// 如果空手,使用记忆的物品复制
|
||||
ItemStack memorized = be.getMemorizedItem();
|
||||
if (!memorized.isEmpty()) {
|
||||
copyAndDropItem(level, pos, memorized.copy());
|
||||
} else {
|
||||
player.displayClientMessage(Component.literal("No item memorized!"), true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// 复制并丢出物品
|
||||
private static void copyAndDropItem(Level level, BlockPos pos, ItemStack stack) {
|
||||
if (!level.isClientSide) {
|
||||
ItemEntity itemEntity = new ItemEntity(
|
||||
level,
|
||||
pos.getX() + 0.5,
|
||||
pos.getY() + 1.0,
|
||||
pos.getZ() + 0.5,
|
||||
stack
|
||||
);
|
||||
level.addFreshEntity(itemEntity);
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void OnAnvilUpdated(AnvilUpdateEvent event) {
|
||||
String name = event.getName();
|
||||
ItemStack left = event.getLeft();
|
||||
if (left.is(Items.ANVIL) && name != null && name.equals("NeoForge")) {
|
||||
event.setCost(1);
|
||||
event.setXpCost(1);
|
||||
event.setOutput(ModItemRegister.NEOFORGE.get().getDefaultInstance());
|
||||
} else if (left.is(ModItemRegister.NEOFORGE.get().asItem()) && name != null && name.equals("Forge")) {
|
||||
ItemStack instance = Items.ANVIL.getDefaultInstance();
|
||||
instance.set(DataComponents.CUSTOM_NAME, Component.literal("Forge").withStyle(ChatFormatting.BOLD).withStyle(ChatFormatting.AQUA));
|
||||
event.setOutput(instance);
|
||||
event.setCost(1);
|
||||
event.setXpCost(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,6 +166,30 @@ public class CommonEventHandler {
|
|||
DispenserBlock.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior());
|
||||
});
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRegisterCapabilities(RegisterCapabilitiesEvent event) {
|
||||
event.registerBlock(
|
||||
ModCapabilities.ITEM_MEMORY_COPY_BLOCK_CAP,
|
||||
((level, pos, state, blockEntity, context) -> new ItemStackHandler(1) {
|
||||
@Override
|
||||
public boolean isItemValid(int slot, @NotNull ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) {
|
||||
if (!simulate && !stack.isEmpty()) {
|
||||
if (blockEntity instanceof ItemMemoryBlockEntity itemMemoryBlockEntity)
|
||||
itemMemoryBlockEntity.setMemorizedItem(stack);
|
||||
else throw new IllegalStateException("BlockEntity must be an instance of ItemMemoryBlockEntity");
|
||||
}
|
||||
return stack; // 不实际存储物品,直接返回原物品
|
||||
}
|
||||
}),
|
||||
ModBlocksRegister.TEST_BLOCK.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.r3944realms.leashedplayer;
|
||||
|
||||
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||
import com.r3944realms.leashedplayer.content.blocks.ModBlocksRegister;
|
||||
import com.r3944realms.leashedplayer.content.blocks.entity.ModBlockEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
|
||||
|
|
@ -26,6 +28,8 @@ public class LeashedPlayer {
|
|||
private static Integer M4; //拴绳最大长度
|
||||
public LeashedPlayer(IEventBus event) {
|
||||
ModItemRegister.register(event);
|
||||
ModBlocksRegister.register(event);
|
||||
ModBlockEntityRegister.register(event);
|
||||
ModRecipeRegister.register(event);
|
||||
ModSoundRegister.register(event);
|
||||
ModPaintingsRegister.register(event);
|
||||
|
|
@ -66,5 +70,8 @@ public class LeashedPlayer {
|
|||
}
|
||||
return M4;
|
||||
}
|
||||
public static Double maxSize() {
|
||||
return M1() * M4();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
|
|||
import com.mojang.datafixers.util.Either;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.client.Camera;
|
||||
|
|
@ -298,7 +298,7 @@ public class LeashRendererUtil {
|
|||
double entityRotationAngleRadians = (double)(cameraEntity.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
|
||||
// 计算实体的绳索偏移,此处add偏移让渲染拴绳显示在玩家头部下(大约在脖子处
|
||||
Vec3 cameraEntityLeashOffset = cameraEntity.getLeashOffset(partialTick).add(0, -0.2, -0.5);
|
||||
Vec3 cameraEntityLeashOffset = ((Leashable)cameraEntity).getLeashOffset(partialTick).add(0, -0.2, -0.5);
|
||||
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ public class LeashRendererUtil {
|
|||
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.options.getCameraType().isFirstPerson()) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashData();
|
||||
if(leashDataFromEntityData == null) continue;
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
if(delayedLeashInfo != null) {
|
||||
|
|
@ -373,7 +373,7 @@ public class LeashRendererUtil {
|
|||
if (playerByUUID != null) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID, Vec3.ZERO);
|
||||
} else {
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
|
||||
double MaxLeashLength = ((IEntityLeadExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
|
|
@ -423,7 +423,7 @@ public class LeashRendererUtil {
|
|||
}
|
||||
|
||||
public static void createPlayerLeashState(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, float partialTick) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashData();
|
||||
Leashable.LeashData leashData = ((PlayerLeashable) abstractClientPlayer).getLeashData();
|
||||
PlayerRenderState playerRs = (PlayerRenderState)playerRenderState;
|
||||
if (leashDataFromEntityData != null) {
|
||||
|
|
@ -441,12 +441,12 @@ public class LeashRendererUtil {
|
|||
playerRenderState.setPlayerLeashState(null);
|
||||
}
|
||||
} else if(leashData != null) {
|
||||
playerRs.leashState = null;
|
||||
playerRs.leashStates = null;
|
||||
Entity leashHolder = ((PlayerLeashable) abstractClientPlayer).getLeashHolder();
|
||||
PlayerLeashState playerLeashState = playerRenderState.getPlayerLeashState();
|
||||
if (leashHolder != null & playerLeashState != null) {
|
||||
float f = leashHolder.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0);
|
||||
Vec3 vec3 = abstractClientPlayer.getLeashOffset(partialTick).yRot(-f);
|
||||
Vec3 vec3 = ((Leashable)abstractClientPlayer).getLeashOffset(partialTick).yRot(-f);
|
||||
BlockPos blockpos1 = BlockPos.containing(abstractClientPlayer.getEyePosition(partialTick));
|
||||
BlockPos blockpos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
|
||||
playerLeashState.vanilaLeashState = new EntityRenderState.LeashState();
|
||||
|
|
@ -498,7 +498,7 @@ public class LeashRendererUtil {
|
|||
playerLeashState.pos = playerByUUID.position().add(0.0, playerByUUID.getEyeHeight() * 0.6, 0);
|
||||
} else {
|
||||
double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * breakDistanceTime;
|
||||
double MaxLeashLength = ((IEntityLeadExtension) abstractClientPlayer).getLeashLength() * breakDistanceTime;
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
|
|
@ -9,6 +8,7 @@ import net.neoforged.api.distmarker.Dist;
|
|||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
import org.joml.Matrix3x2fStack;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ public class AdaptiveGuiRendererHandler {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void onRendererLevel(RenderGuiEvent.Pre event) {
|
||||
PoseStack matrixStack = event.getGuiGraphics().pose();
|
||||
Matrix3x2fStack matrixStack = event.getGuiGraphics().pose();
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
processBars.keySet().forEach(
|
||||
processBar -> {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
import com.r3944realms.leashedplayer.client.processBar.TestProcessBar;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import org.joml.Matrix3x2fStack;
|
||||
|
||||
public interface IFadingProcessBarRenderer<T extends IProcessBar> extends IProcessBarRenderer<T> {
|
||||
/**
|
||||
|
|
@ -57,11 +57,11 @@ public interface IFadingProcessBarRenderer<T extends IProcessBar> extends IProce
|
|||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
default void renderProcessBar(PoseStack poseStack, GuiGraphics guiGraphics) {
|
||||
default void renderProcessBar(Matrix3x2fStack poseStack, GuiGraphics guiGraphics) {
|
||||
updateFadeEffect();
|
||||
renderProcessBar0(poseStack, guiGraphics);
|
||||
}
|
||||
void renderProcessBar0(PoseStack poseStack, GuiGraphics guiGraphics);
|
||||
void renderProcessBar0(Matrix3x2fStack poseStack, GuiGraphics guiGraphics);
|
||||
|
||||
default void fadeInTick(float fadeSpeed) {
|
||||
if (getFadeAlpha() >= 1.0f) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import org.joml.Matrix3x2fStack;
|
||||
|
||||
public interface IProcessBarRenderer<T extends IProcessBar> {
|
||||
T getProcessBar();
|
||||
void setProcessBar(T processBar);
|
||||
void renderProcessBar(PoseStack poseStack, GuiGraphics guiGraphics);
|
||||
void renderProcessBar(Matrix3x2fStack poseStack, GuiGraphics guiGraphics);
|
||||
default void stopRender() {
|
||||
T processBar = getProcessBar();
|
||||
processBar.decreaseAliveCount();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
|
|
@ -10,6 +9,7 @@ import net.neoforged.bus.api.SubscribeEvent;
|
|||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
||||
import org.joml.Matrix3x2fStack;
|
||||
|
||||
@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, value = Dist.CLIENT)
|
||||
public class ProcessBarRenderer {
|
||||
|
|
@ -35,7 +35,7 @@ public class ProcessBarRenderer {
|
|||
}
|
||||
@SubscribeEvent
|
||||
public static void onRendererLevel(RenderGuiEvent.Pre event) {
|
||||
PoseStack matrixStack = event.getGuiGraphics().pose();
|
||||
Matrix3x2fStack matrixStack = event.getGuiGraphics().pose();
|
||||
GuiGraphics guiGraphics = event.getGuiGraphics();
|
||||
if(isRendering) {
|
||||
renderProgressBar(matrixStack, guiGraphics);
|
||||
|
|
@ -44,7 +44,7 @@ public class ProcessBarRenderer {
|
|||
public static float getProgress() {
|
||||
return (float) currentProgress / progressDuration;
|
||||
}
|
||||
private static void renderProgressBar(PoseStack matrixStack, GuiGraphics guiGraphics) {
|
||||
private static void renderProgressBar(Matrix3x2fStack matrixStack, GuiGraphics guiGraphics) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
int screenWidth = mc.getWindow().getGuiScaledWidth();
|
||||
int screenHeight = mc.getWindow().getGuiScaledHeight();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
import com.r3944realms.leashedplayer.client.processBar.TestProcessBar;
|
||||
import com.r3944realms.leashedplayer.utils.ColorUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix3x2fStack;
|
||||
|
||||
public class TestProcessBarRenderer implements IFadingProcessBarRenderer<IProcessBar>{
|
||||
@Nullable
|
||||
|
|
@ -122,7 +122,7 @@ public class TestProcessBarRenderer implements IFadingProcessBarRenderer<IProces
|
|||
|
||||
|
||||
@Override
|
||||
public void renderProcessBar0(PoseStack poseStack, GuiGraphics guiGraphics) {
|
||||
public void renderProcessBar0(Matrix3x2fStack poseStack, GuiGraphics guiGraphics) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
int screenWidth = mc.getWindow().getGuiScaledWidth();
|
||||
int screenHeight = mc.getWindow().getGuiScaledHeight();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.r3944realms.leashedplayer.content.blocks;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
|
||||
public enum ModBlockResourceKeys {
|
||||
TEST_BLOCK(ModBlocksRegister.TEST_BLOCK)
|
||||
;
|
||||
private final ResourceKey<Block> resourceKey;
|
||||
ModBlockResourceKeys(String name) {
|
||||
resourceKey = ResourceKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, name));
|
||||
}
|
||||
ModBlockResourceKeys(DeferredHolder<Block, ? extends Block> block) {
|
||||
resourceKey = ResourceKey.create(Registries.BLOCK, block.getId());
|
||||
}
|
||||
|
||||
public ResourceKey<Block> getResourceKey() {
|
||||
return resourceKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.r3944realms.leashedplayer.content.blocks;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.blocks.type.ItemMemoryBlock;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModBlocksRegister {
|
||||
public static DeferredRegister<Block> BLOCKS = DeferredRegister.createBlocks(LeashedPlayer.MOD_ID);
|
||||
public static DeferredHolder<Block, Block> TEST_BLOCK = register("test_block",
|
||||
() -> new ItemMemoryBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.GLASS)
|
||||
.setId(ModBlockResourceKeys.TEST_BLOCK.getResourceKey()))
|
||||
);
|
||||
public static <T extends Block> DeferredHolder<Item, BlockItem> registerBlockItem(String name , DeferredHolder<T, ? extends T> block, ResourceKey<Item> itemResourceKey){
|
||||
return ModItemRegister.registerBlockItem(
|
||||
name,
|
||||
() -> new BlockItem(block.get(),new Item.Properties().setId(itemResourceKey))
|
||||
);
|
||||
}
|
||||
private static DeferredHolder<Block, Block> register(String name, Supplier<Block> blockSupplier) {
|
||||
return BLOCKS.register(name, blockSupplier);
|
||||
}
|
||||
public static void register(IEventBus eventBus) {
|
||||
BLOCKS.register(eventBus);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.r3944realms.leashedplayer.content.blocks.entity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ItemMemoryBlockEntity extends BlockEntity {
|
||||
|
||||
private ItemStack memorizedItem = ItemStack.EMPTY;
|
||||
public ItemMemoryBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(ModBlockEntityRegister.ITEM_MEMORY_BLOCK.get(), pos, blockState);
|
||||
}
|
||||
// 记忆物品
|
||||
public void setMemorizedItem(ItemStack memorizedItem) {
|
||||
this.memorizedItem = memorizedItem.copy();
|
||||
this.memorizedItem.setCount(1);
|
||||
setChanged();
|
||||
}
|
||||
// 获取记忆的物品
|
||||
public ItemStack getMemorizedItem() {
|
||||
return memorizedItem.copy();
|
||||
}
|
||||
//--- 数据持久化(必须实现)---//
|
||||
@Override
|
||||
protected void saveAdditional(@NotNull ValueOutput valueOutput) {
|
||||
super.saveAdditional(valueOutput);
|
||||
if (!memorizedItem.isEmpty()) {
|
||||
valueOutput.store("memorizedItem", ItemStack.CODEC, memorizedItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAdditional(@NotNull ValueInput valueInput) {
|
||||
super.loadAdditional(valueInput);
|
||||
memorizedItem = valueInput.read("memorizedItem", ItemStack.CODEC).orElse(ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.r3944realms.leashedplayer.content.blocks.entity;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.blocks.ModBlocksRegister;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
|
||||
import java.util.Set;
|
||||
public class ModBlockEntityRegister {
|
||||
public static DeferredRegister<BlockEntityType<?>> BLOCK_ENTITY = DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, LeashedPlayer.MOD_ID);
|
||||
public static DeferredHolder<BlockEntityType<?>, BlockEntityType<ItemMemoryBlockEntity>> ITEM_MEMORY_BLOCK =
|
||||
BLOCK_ENTITY.register(
|
||||
"item_memory_block_entity",
|
||||
() -> new BlockEntityType<>(
|
||||
ItemMemoryBlockEntity::new,
|
||||
Set.of(ModBlocksRegister.TEST_BLOCK.get())
|
||||
)
|
||||
);
|
||||
public static void register(IEventBus eventBus) {
|
||||
BLOCK_ENTITY.register(eventBus);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.r3944realms.leashedplayer.content.blocks.type;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.blocks.entity.ItemMemoryBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ItemMemoryBlock extends Block implements EntityBlock {
|
||||
public ItemMemoryBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState state) {
|
||||
return new ItemMemoryBlockEntity(pos, state);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.r3944realms.leashedplayer.content.capabilities;
|
||||
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.neoforge.capabilities.BlockCapability;
|
||||
import net.neoforged.neoforge.capabilities.EntityCapability;
|
||||
import net.neoforged.neoforge.capabilities.ItemCapability;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
|
||||
public class ModCapabilities {
|
||||
public static final BlockCapability<IItemHandler, Void> ITEM_MEMORY_COPY_BLOCK_CAP =
|
||||
BlockCapability.createVoid(
|
||||
ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "item_memory_copy_block_cap"),
|
||||
IItemHandler.class
|
||||
);
|
||||
// public static final EntityCapability<IItemHandler, Void> ENTITY_LEASH_LENGTH_CAP =
|
||||
// EntityCapability.createVoid(
|
||||
// ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "entity_leash_length_cap"),
|
||||
// IItemHandler.class
|
||||
// );
|
||||
}
|
||||
|
|
@ -6,10 +6,11 @@ import com.mojang.brigadier.arguments.FloatArgumentType;
|
|||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
|
|
@ -63,7 +64,7 @@ public class LeashCommand {
|
|||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = source.getPlayerOrException();
|
||||
float leashLength = ((ILivingEntityExtension)player).getLeashLength();
|
||||
float leashLength = ((IEntityLeadExtension)player).getLeashLength();
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SHOW, player.getDisplayName(), leashLength), true);
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
|
|
@ -75,7 +76,7 @@ public class LeashCommand {
|
|||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||
float leashLength = ((ILivingEntityExtension)player).getLeashLength();
|
||||
float leashLength = ((IEntityLeadExtension)player).getLeashLength();
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SHOW, player.getDisplayName(), leashLength), true);
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
|
|
@ -88,7 +89,7 @@ public class LeashCommand {
|
|||
try {
|
||||
Collection<ServerPlayer> playerCol = EntityArgument.getPlayers(context, "targetPlayers");
|
||||
playerCol.forEach(player -> {
|
||||
float leashLength = ((ILivingEntityExtension) player).getLeashLength();
|
||||
float leashLength = ((IEntityLeadExtension) player).getLeashLength();
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SHOW, player.getDisplayName(), leashLength), true);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
|
@ -97,12 +98,28 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> getRefEntitiesLeashLength = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
Collection<? extends Entity> entities = EntityArgument.getEntities(context, "targetEntities");
|
||||
entities.stream().filter(i->i instanceof Leashable).forEach(entity -> {
|
||||
float leashLength = ((IEntityLeadExtension) entity).getLeashLength();
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SHOW, entity.getDisplayName(), leashLength), true);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setSelfLengthLeashLength = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = source.getPlayerOrException();
|
||||
float leashLength = context.getArgument("leashLength", Float.class);
|
||||
((ILivingEntityExtension)player).setLeashLength(leashLength);
|
||||
IEntityLeadExtension player1 = (IEntityLeadExtension) player;
|
||||
player1.setLeashLength(leashLength);
|
||||
player1.setLeadLengthSync(false);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SET, player.getDisplayName(), leashLength), true);
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
|
|
@ -115,7 +132,9 @@ public class LeashCommand {
|
|||
try {
|
||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||
float leashLength = context.getArgument("leashLength", Float.class);
|
||||
((ILivingEntityExtension)player).setLeashLength(leashLength);
|
||||
IEntityLeadExtension player1 = (IEntityLeadExtension) player;
|
||||
player1.setLeashLength(leashLength);
|
||||
player1.setLeadLengthSync(false);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SET, player.getDisplayName(), leashLength), true);
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
|
|
@ -130,7 +149,9 @@ public class LeashCommand {
|
|||
Collection<ServerPlayer> playerCol = EntityArgument.getPlayers(context, "targetPlayers");
|
||||
playerCol.forEach(player -> {
|
||||
try {
|
||||
((ILivingEntityExtension)player).setLeashLength(leashLength);
|
||||
IEntityLeadExtension player1 = (IEntityLeadExtension) player;
|
||||
player1.setLeashLength(leashLength);
|
||||
player1.setLeadLengthSync(false);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SET, player.getDisplayName(), leashLength), true);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
|
@ -143,6 +164,28 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setRefEntitiesLengthLeashLength = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
float leashLength = context.getArgument("leashLength", Float.class);
|
||||
try {
|
||||
Collection<? extends Entity> entities = EntityArgument.getEntities(context, "targetEntities");
|
||||
entities.stream().filter(i->i instanceof Leashable).forEach(entity -> {
|
||||
try {
|
||||
IEntityLeadExtension iEntityLeadExtension = (IEntityLeadExtension) entity;
|
||||
iEntityLeadExtension.setLeashLength(leashLength);
|
||||
iEntityLeadExtension.setLeadLengthSync(false);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_LENGTH_SET, entity.getDisplayName(), leashLength), true);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
//获取Data 构造一个MutableComponent显示数据
|
||||
Command<CommandSourceStack> geSelfLeashData = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
|
|
@ -187,6 +230,24 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> getRefEntitiesLeashData = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
Collection<? extends Entity> entities = EntityArgument.getEntities(context, "targetEntities");
|
||||
entities.stream().filter(i->i instanceof Leashable).forEach(entity -> {
|
||||
try {
|
||||
LeashLengthGetResultInt(entity, source);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
//设置前要判断其实体距离(同一维度,且距离不得大于其绳长的1.2倍(待定,也许可以设置在配置文件里)
|
||||
Command<CommandSourceStack> setSelfLeashDataEntity = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
|
|
@ -201,21 +262,8 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setSelfLeashDataByBlockPos = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = source.getPlayerOrException();
|
||||
Integer x = LeashDataBlockPosSetResultInt(context, source, player);
|
||||
if (x != null) return x;
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
Command<CommandSourceStack> setRefPlayerLeashDataEntity = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
|
|
@ -246,6 +294,50 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setRefEntitiesLeashDataEntity = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
Collection<? extends Entity> entities = EntityArgument.getEntities(context, "targetEntities");
|
||||
entities.stream().filter(i->i instanceof Leashable).forEach(entity -> {
|
||||
try {
|
||||
LeashDataEntitySetResultInt(context, entity, source);
|
||||
} catch (CommandSyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setSelfLeashDataByBlockPos = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = source.getPlayerOrException();
|
||||
Integer x = LeashDataBlockPosSetResultInt(context, source, player);
|
||||
if (x != null) return x;
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setRefPlayerLeashDataByBlockPos = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||
Integer x = LeashDataBlockPosSetResultInt(context, source, player);
|
||||
if (x != null) return x;
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setRefPlayersLeashDataByBlockPos = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
|
|
@ -260,12 +352,13 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> setRefPlayerLeashDataByBlockPos = context -> {
|
||||
Command<CommandSourceStack> setRefEntitiesLeashDataByBlockPos = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
ServerPlayer player = EntityArgument.getPlayer(context, "targetPlayer");
|
||||
Integer x = LeashDataBlockPosSetResultInt(context, source, player);
|
||||
if (x != null) return x;
|
||||
Collection<? extends Entity> entities = EntityArgument.getEntities(context, "targetEntities");
|
||||
entities.stream().filter(i->i instanceof Leashable).forEach(entity -> {
|
||||
LeashDataBlockPosSetResultInt(context, source, entity);
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
|
|
@ -317,6 +410,24 @@ public class LeashCommand {
|
|||
}
|
||||
return 0;
|
||||
};
|
||||
Command<CommandSourceStack> clearRefEntitiesLeashData = context -> {
|
||||
CommandSourceStack source = context.getSource();
|
||||
try {
|
||||
Collection<? extends Entity> entities = EntityArgument.getEntities(context, "targetEntities");
|
||||
entities.stream().filter(i->i instanceof Leashable).forEach(entity -> {
|
||||
try {
|
||||
LeashDataClearResultInt(source, PlayerLeashable.getLeashDataEntity(entity, source.getLevel()),entity);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
source.sendFailure(Component.translatable(LEASH_FAILED));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> SelfLeashLength = $$leashRoot.then(Commands.literal("length").executes(getSelfLeashLength)
|
||||
|
|
@ -326,7 +437,7 @@ public class LeashCommand {
|
|||
)
|
||||
);
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> RefPlayerLeashLength = $$leashRoot.then(
|
||||
LiteralArgumentBuilder<CommandSourceStack> RefEntitiesLeashLength = $$leashRoot.then(
|
||||
Commands.literal("length")
|
||||
.then(Commands.argument("targetPlayer", EntityArgument.player()).executes(getRefPlayerLeashLength)
|
||||
.then(Commands.literal("get").executes(getRefPlayerLeashLength))
|
||||
|
|
@ -344,9 +455,18 @@ public class LeashCommand {
|
|||
)
|
||||
)
|
||||
)
|
||||
.then(Commands.argument("targetEntities", EntityArgument.entities()).executes(getRefEntitiesLeashLength)
|
||||
.then(Commands.literal("get").executes(getRefEntitiesLeashLength))
|
||||
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
||||
.then(
|
||||
Commands.argument("leashLength", FloatArgumentType.floatArg(MIN_VALUE, MAX_VALUE)).executes(setRefEntitiesLengthLeashLength)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> RefPLayerData = $$leashRoot.then(
|
||||
LiteralArgumentBuilder<CommandSourceStack> RefEntitiesData = $$leashRoot.then(
|
||||
Commands.literal("data")
|
||||
.then(Commands.argument("targetPlayer", EntityArgument.player()).executes(getRefPlayerLeashData)
|
||||
.then(Commands.literal("get")
|
||||
|
|
@ -375,7 +495,22 @@ public class LeashCommand {
|
|||
)
|
||||
)
|
||||
.then(Commands.literal("clear").requires(cs -> cs.hasPermission(2)).executes(clearRefPlayersLeashData))
|
||||
));
|
||||
)
|
||||
.then(Commands.argument("targetEntities", EntityArgument.entities()).executes(getRefEntitiesLeashData)
|
||||
.then(Commands.literal("get")
|
||||
.executes(getRefEntitiesLeashData)
|
||||
)
|
||||
.then(Commands.literal("set").requires(cs -> cs.hasPermission(2))
|
||||
.then(Commands.argument("holderEntity", EntityArgument.entity())
|
||||
.executes(setRefEntitiesLeashDataEntity)
|
||||
)
|
||||
.then(Commands.argument("BlockPos", BlockPosArgument.blockPos())
|
||||
.executes(setRefEntitiesLeashDataByBlockPos)
|
||||
)
|
||||
)
|
||||
.then(Commands.literal("clear").requires(cs -> cs.hasPermission(2)).executes(clearRefEntitiesLeashData))
|
||||
)
|
||||
);
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> SelfData = $$leashRoot.then(
|
||||
Commands.literal("data")
|
||||
|
|
@ -397,9 +532,9 @@ public class LeashCommand {
|
|||
|
||||
if(shouldUsePrefix) {
|
||||
literalArgumentBuilder
|
||||
.then(RefPlayerLeashLength)
|
||||
.then(RefEntitiesLeashLength)
|
||||
.then(SelfLeashLength)
|
||||
.then(RefPLayerData)
|
||||
.then(RefEntitiesData)
|
||||
.then(SelfData);
|
||||
dispatcher.register(literalArgumentBuilder);
|
||||
} else {
|
||||
|
|
@ -408,24 +543,26 @@ public class LeashCommand {
|
|||
|
||||
}
|
||||
|
||||
private static @Nullable Integer LeashLengthGetResultInt(ServerPlayer player, CommandSourceStack source) throws Exception {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) player).getLeashDataFromEntityData();
|
||||
|
||||
private static @Nullable Integer LeashLengthGetResultInt(Entity entity, CommandSourceStack source) throws Exception {
|
||||
Leashable.LeashData leashDataFromEntityData;
|
||||
if(entity instanceof Leashable leashable)
|
||||
leashDataFromEntityData = leashable.getLeashData();
|
||||
else return null;
|
||||
if(leashDataFromEntityData == null) {
|
||||
source.sendSuccess(() -> Component.translatable(NO_LEASH_DATA, player.getDisplayName()), true);
|
||||
source.sendSuccess(() -> Component.translatable(NO_LEASH_DATA, entity.getDisplayName()), true);
|
||||
return 1;
|
||||
} else {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntityOrThrown(leashDataFromEntityData, source.getLevel());
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_DATA_SHOW, player.getDisplayName(), leashDataEntity.getDisplayName()), true);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_DATA_SHOW, entity.getDisplayName(), leashDataEntity.getDisplayName()), true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static @Nullable Integer LeashDataBlockPosSetResultInt(CommandContext<CommandSourceStack> context, CommandSourceStack source, ServerPlayer player) {
|
||||
private static @Nullable Integer LeashDataBlockPosSetResultInt(CommandContext<CommandSourceStack> context, CommandSourceStack source, Entity entity) {
|
||||
BlockPos blockPos = BlockPosArgument.getBlockPos(context, "BlockPos");
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashFenceKnotEntity(source.getLevel(), blockPos);
|
||||
PlayerLeashable leashedPlayer = (PlayerLeashable) player;
|
||||
Component targetPlayerDisplayName = player.getDisplayName();
|
||||
Leashable leashedPlayer = (Leashable) entity;
|
||||
Component targetPlayerDisplayName = entity.getDisplayName();
|
||||
if(leashDataEntity == null) {
|
||||
ServerLevel level = context.getSource().getLevel();
|
||||
if(GameruleRegistry.getGameruleBoolValue(level,CreateLeashFenceKnotEntityIfAbsent.ID)) {
|
||||
|
|
@ -441,43 +578,43 @@ public class LeashCommand {
|
|||
}
|
||||
Component leashDataEntityDisplayName = leashDataEntity.getDisplayName();
|
||||
|
||||
return LeashDataCommonPartSetResultInt(source, player, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
||||
return LeashDataCommonPartSetResultInt(source, entity, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
||||
}
|
||||
|
||||
private static @Nullable Integer LeashDataEntitySetResultInt(CommandContext<CommandSourceStack> context, ServerPlayer player, CommandSourceStack source) throws CommandSyntaxException {
|
||||
private static @Nullable Integer LeashDataEntitySetResultInt(CommandContext<CommandSourceStack> context, Entity entity, CommandSourceStack source) throws CommandSyntaxException {
|
||||
Entity leashDataEntity = EntityArgument.getEntity(context, "holderEntity");
|
||||
PlayerLeashable leashedPlayer = (PlayerLeashable) player;
|
||||
Component targetPlayerDisplayName = player.getDisplayName();
|
||||
Leashable leashable = (Leashable) entity;
|
||||
Component targetPlayerDisplayName = entity.getDisplayName();
|
||||
Component leashDataEntityDisplayName = leashDataEntity.getDisplayName();
|
||||
if(player.equals(leashDataEntity)) {
|
||||
if(entity.equals(leashDataEntity)) {
|
||||
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_FORBID_SAME_ENTITY));
|
||||
return 1;
|
||||
}
|
||||
return LeashDataCommonPartSetResultInt(source, player, leashDataEntity, leashedPlayer, targetPlayerDisplayName, leashDataEntityDisplayName);
|
||||
return LeashDataCommonPartSetResultInt(source, entity, leashDataEntity, leashable, targetPlayerDisplayName, leashDataEntityDisplayName);
|
||||
}
|
||||
|
||||
private static @Nullable Integer LeashDataCommonPartSetResultInt(CommandSourceStack source, ServerPlayer player, Entity leashDataEntity, PlayerLeashable leashedPlayer, Component targetPlayerDisplayName, Component leashDataEntityDisplayName) {
|
||||
if(player.level() != leashDataEntity.level()) {
|
||||
private static @Nullable Integer LeashDataCommonPartSetResultInt(CommandSourceStack source, Entity entity, Entity leashDataEntity, Leashable leashable, Component targetPlayerDisplayName, Component leashDataEntityDisplayName) {
|
||||
if(entity.level() != leashDataEntity.level()) {
|
||||
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_DIFF_LEVEL, targetPlayerDisplayName, leashDataEntityDisplayName));
|
||||
return 2;
|
||||
}
|
||||
ILivingEntityExtension targetPlayerExtension = (ILivingEntityExtension) player;
|
||||
if (player.distanceTo(leashDataEntity) > targetPlayerExtension.getLeashLength() * 1.2f) {
|
||||
IEntityLeadExtension targetPlayerExtension = (IEntityLeadExtension) entity;
|
||||
if (entity.distanceTo(leashDataEntity) > targetPlayerExtension.getLeashLength() * LeashedPlayer.M1()) {
|
||||
source.sendFailure(Component.translatable(LEASH_DATA_SET_FAILED_TOO_FAR, targetPlayerDisplayName, leashDataEntityDisplayName, targetPlayerExtension.getLeashLength()));
|
||||
return 3;
|
||||
}
|
||||
leashedPlayer.setLeashedTo(leashDataEntity, true);
|
||||
leashable.setLeashedTo(leashDataEntity, true);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_DATA_SET, targetPlayerDisplayName, leashDataEntityDisplayName), true);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static @Nullable Integer LeashDataClearResultInt(CommandSourceStack source, Entity leashDataEntity, ServerPlayer serverPlayer) {
|
||||
private static @Nullable Integer LeashDataClearResultInt(CommandSourceStack source, Entity leashDataEntity, Entity entity) {
|
||||
if(leashDataEntity == null) {
|
||||
source.sendFailure(Component.translatable(LEASH_DATA_CLEAR_FAILED_NO_DATA, serverPlayer.getDisplayName()));
|
||||
source.sendFailure(Component.translatable(LEASH_DATA_CLEAR_FAILED_NO_DATA, entity.getDisplayName()));
|
||||
return 1;
|
||||
}
|
||||
Leashable.dropLeash((Entity & Leashable) serverPlayer, true, false);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_DATA_CLEAR, serverPlayer.getDisplayName(), leashDataEntity.getDisplayName()), true);
|
||||
Leashable.dropLeash((Entity & Leashable) entity, true, false);
|
||||
source.sendSuccess(() -> Component.translatable(LEASH_DATA_CLEAR, entity.getDisplayName(), leashDataEntity.getDisplayName()), true);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class LeashPlayerTrigger extends SimpleCriterionTrigger<LeashPlayerTrigge
|
|||
|
||||
public boolean matches(ServerPlayer player, Entity holder) {
|
||||
PlayerLeashable ppl = (PlayerLeashable) player;
|
||||
return ppl.isLeashed() && holder.equals(PlayerLeashable.getLeashDataEntity(player, player.serverLevel())) && this.holder.isPresent() && this.holder.get().matches(player, holder);
|
||||
return ppl.isLeashed() && holder.equals(PlayerLeashable.getLeashDataEntity(player, player.level())) && this.holder.isPresent() && this.holder.get().matches(player, holder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
|
|||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTime;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.particles.ColorParticleOption;
|
||||
|
|
@ -86,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((Entity) null);//将先前的箭矢置空
|
||||
}
|
||||
((PlayerLeashable)serverPlayer).setLeashedTo(this, true);
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if (pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) lPlayer, (ServerLevel) level());
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.setOwner(null);
|
||||
leashRopeArrow.setOwner((Entity) null);
|
||||
}
|
||||
lPlayer.setLeashedTo(this, true);
|
||||
}
|
||||
|
|
@ -112,8 +112,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
@Override
|
||||
public void setOwner(@Nullable Entity pEntity) {
|
||||
boolean isNull = pEntity == null;
|
||||
this.ownerUUID = isNull ? null : pEntity.getUUID();
|
||||
this.cachedOwner = isNull ? null : pEntity;
|
||||
this.owner = null;
|
||||
this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
|
||||
}
|
||||
|
||||
|
|
@ -142,11 +141,11 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
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();
|
||||
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity(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);
|
||||
pPlayer.playSound(SoundEvents.LEAD_BREAK, 1, 1);
|
||||
Leashable.dropLeash((Entity & Leashable)playerLeashable, true, false);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -156,10 +155,10 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
// if(this.equals(leashDataEntity)) {
|
||||
if(owner instanceof PlayerLeashable player) {
|
||||
player.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
pPlayer.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
} else if(owner instanceof Leashable leashable) {
|
||||
leashable.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
pPlayer.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
|
||||
level().addFreshEntity(itemEntity);
|
||||
|
|
@ -174,21 +173,21 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
|
||||
} else {
|
||||
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()) : this.getOwner();
|
||||
Entity leashDataEntity = this.getOwner() instanceof PlayerLeashable ? PlayerLeashable.getLeashDataEntity(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);
|
||||
pPlayer.playSound(SoundEvents.LEAD_BREAK, 1, 1);
|
||||
Leashable.dropLeash((Entity & Leashable) playerLeashable,true, false);
|
||||
}
|
||||
} else {
|
||||
Entity owner = getOwner();
|
||||
if(owner instanceof PlayerLeashable player) {
|
||||
player.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
pPlayer.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
} else if(owner instanceof Leashable leashable) {
|
||||
leashable.setLeashedTo(pPlayer, true);
|
||||
pPlayer.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
pPlayer.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
}
|
||||
ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), getOrginalItemStack());
|
||||
level().addFreshEntity(itemEntity);
|
||||
|
|
@ -288,7 +287,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if(!level().isClientSide) {
|
||||
if (getOwner() instanceof PlayerLeashable pL) {
|
||||
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(getOwner(), (ServerLevel) level());
|
||||
if(leashDataEntity != null) {
|
||||
Leashable.dropLeash((Entity & Leashable) pL, true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
|
|
@ -296,10 +295,10 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
}
|
||||
Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos());
|
||||
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
|
||||
IEntityLeadExtension pLL = (IEntityLeadExtension) pL;
|
||||
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
||||
pL.setLeashedTo(leashKnotFence, true);
|
||||
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
leashKnotFence.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
|
|
@ -308,15 +307,15 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if (this.level().getBlockState(pResult.getBlockPos()).is(BlockTags.FENCES)) {
|
||||
Entity leashDataEntity = this.getOwner();
|
||||
if(leashDataEntity != null) {
|
||||
leashDataEntity.playSound(SoundEvents.LEASH_KNOT_BREAK, 1, 1);
|
||||
leashDataEntity.playSound(SoundEvents.LEAD_BREAK, 1, 1);
|
||||
Leashable.dropLeash((Entity & Leashable) L,true, false);
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.setOwner(null);
|
||||
leashRopeArrow.setOwner((Entity) null);
|
||||
}
|
||||
}
|
||||
Entity leashKnotFence = LeashFenceKnotEntity.getOrCreateKnot(this.level(), pResult.getBlockPos());
|
||||
L.setLeashedTo(leashKnotFence, true);
|
||||
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
leashKnotFence.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
|
|
@ -342,19 +341,19 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
if(livingEntity.equals(this.getOwner())) return;
|
||||
if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成
|
||||
setOwner(livingEntity);
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(getOwner(), (ServerLevel) level());
|
||||
if(leashDataEntity != null) {
|
||||
Leashable.dropLeash((Entity & Leashable) pL,true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if(leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
|
||||
IEntityLeadExtension pLL = (IEntityLeadExtension) pL;
|
||||
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
livingEntity.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
pL.setLeashedTo(this, true);
|
||||
} else if (this.getOwner() instanceof PlayerLeashable pL) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(getOwner(), (ServerLevel) level());
|
||||
if(leashDataEntity != null) {
|
||||
Leashable.dropLeash((Entity & Leashable) pL, true, !(leashDataEntity instanceof LeashRopeArrow));
|
||||
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
|
|
@ -362,9 +361,9 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
}
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
|
||||
IEntityLeadExtension pLL = (IEntityLeadExtension) pL;
|
||||
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
livingEntity.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
pL.setLeashedTo(pResult.getEntity(), true);
|
||||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
|
|
@ -378,7 +377,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
leashRopeArrow.dropLeashHandler();
|
||||
}
|
||||
}
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
livingEntity.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
leashable.setLeashedTo(this, true);
|
||||
this.setOwner(entity);
|
||||
return;
|
||||
|
|
@ -386,7 +385,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
if (entity instanceof LivingEntity living) {
|
||||
if (this.getOwner() != null && this.getOwner()instanceof Leashable leashable) {
|
||||
livingEntity.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
livingEntity.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
leashable.setLeashedTo(living, true);
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
this.level().addFreshEntity(arrow);
|
||||
|
|
@ -400,7 +399,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
else if (entity instanceof LeashFenceKnotEntity leashKnotFence) {
|
||||
if (getOwner() instanceof PlayerLeashable pL) {
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level());
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(getOwner(), (ServerLevel) level());
|
||||
if (leashDataEntity != null) {
|
||||
Leashable.dropLeash((Entity & Leashable) pL,true, true);
|
||||
if (leashDataEntity instanceof LeashRopeArrow leashRopeArrow) {
|
||||
|
|
@ -408,9 +407,9 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
}
|
||||
ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
|
||||
ILivingEntityExtension pLL = (ILivingEntityExtension) pL;
|
||||
IEntityLeadExtension pLL = (IEntityLeadExtension) pL;
|
||||
pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID));
|
||||
leashKnotFence.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
leashKnotFence.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
pL.setLeashedTo(leashKnotFence, true);
|
||||
this.level().addFreshEntity(arrow);
|
||||
discard();
|
||||
|
|
@ -451,7 +450,7 @@ public class LeashRopeArrow extends AbstractArrow {
|
|||
}
|
||||
}
|
||||
public void dropLeashHandler() {
|
||||
this.playSound(SoundEvents.LEASH_KNOT_PLACE, 1, 1);
|
||||
this.setOwner(null);
|
||||
this.playSound(SoundEvents.LEAD_TIED, 1, 1);
|
||||
this.setOwner((Entity) null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.r3944realms.leashedplayer.content.entities;
|
|||
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
|
|
@ -13,6 +12,8 @@ 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.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
|
@ -48,17 +49,16 @@ public class SpectralLeashRopeArrow extends LeashRopeArrow {
|
|||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
@Override
|
||||
public void readAdditionalSaveData(@NotNull CompoundTag pCompound) {
|
||||
super.readAdditionalSaveData(pCompound);
|
||||
if (pCompound.contains("Duration")) {
|
||||
this.duration = pCompound.getInt("Duration").orElse(200);
|
||||
}
|
||||
public void readAdditionalSaveData(@NotNull ValueInput valueInput) {
|
||||
super.readAdditionalSaveData(valueInput);
|
||||
this.duration = valueInput.getInt("Duration").orElse(200);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(@NotNull CompoundTag pCompound) {
|
||||
super.addAdditionalSaveData(pCompound);
|
||||
pCompound.putInt("Duration", this.duration);
|
||||
public void addAdditionalSaveData(@NotNull ValueOutput valueOutput) {
|
||||
super.addAdditionalSaveData(valueOutput);
|
||||
valueOutput.putInt("Duration", this.duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import net.minecraft.world.item.Items;
|
|||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.common.CommonHooks;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
package com.r3944realms.leashedplayer.content.items;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.blocks.ModBlocksRegister;
|
||||
import com.r3944realms.leashedplayer.content.items.type.*;
|
||||
import com.r3944realms.leashedplayer.datagen.provider.attributes.ModJukeboxSongs;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.JukeboxSong;
|
||||
import net.minecraft.world.item.Rarity;
|
||||
import net.minecraft.world.item.ShearsItem;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
|
|
@ -44,11 +45,14 @@ public class ModItemRegister {
|
|||
public static final DeferredHolder<Item, Item> NEOFORGE = ModItemRegister.register("neoforge",
|
||||
() -> new Item(DistProperties(ModJukeboxSongs.FOX_MUSIC)
|
||||
.setId(ModItemResourceKeys.NEOFORGE.getResourceKey())));
|
||||
|
||||
public static final DeferredHolder<Item, BlockItem> TEST_BLOCK_ITEM =
|
||||
ModBlocksRegister.registerBlockItem("test_block_item", ModBlocksRegister.TEST_BLOCK, ModItemResourceKeys.TEST_BLOCK_ITEM.getResourceKey());
|
||||
public static Item.Properties DistProperties(ResourceKey<JukeboxSong> song) {
|
||||
return new Item.Properties().stacksTo(1).rarity(Rarity.RARE).jukeboxPlayable(song);
|
||||
}
|
||||
|
||||
public static DeferredHolder<Item, BlockItem> registerBlockItem(String name, Supplier<? extends BlockItem> sup) {
|
||||
return ITEMS.register(name, sup);
|
||||
}
|
||||
public static DeferredHolder<Item, Item> register(String name, Supplier<Item> supplier) {
|
||||
return register(name, supplier, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,14 @@ public enum ModItemResourceKeys {
|
|||
TIPPED_LEASH_ROPE_ARROW (ModItemRegister.TIPPED_LEASH_ROPE_ARROW),
|
||||
AMETHYST_SHEARS(ModItemRegister.AMETHYST_SHEARS),
|
||||
FABRIC(ModItemRegister.FABRIC),
|
||||
NEOFORGE(ModItemRegister.NEOFORGE)
|
||||
NEOFORGE(ModItemRegister.NEOFORGE),
|
||||
TEST_BLOCK_ITEM("test_block_item"),
|
||||
;
|
||||
private final ResourceKey<Item> resourceKey;
|
||||
ModItemResourceKeys(String name) {
|
||||
resourceKey = ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, name));
|
||||
}
|
||||
ModItemResourceKeys(DeferredHolder<Item, Item> item) {
|
||||
ModItemResourceKeys(DeferredHolder<Item, ? extends Item> item) {
|
||||
resourceKey = ResourceKey.create(Registries.ITEM, item.getId());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ public class LeadBreakerItem extends ShearsItem {
|
|||
}
|
||||
if(pLevel.isClientSide) {
|
||||
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
|
||||
if (playerLeashable.getLeashDataFromEntityData() != null) {
|
||||
if (playerLeashable.getLeashData() != null) {
|
||||
pPlayer.playSound(SoundEvents.SHEEP_SHEAR, 1.0F, 1.0F);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.r3944realms.leashedplayer.content.items.type;
|
|||
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Position;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -17,7 +16,6 @@ import net.minecraft.world.level.Level;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ 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.SpectralLeashRopeArrow;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Position;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -18,7 +17,6 @@ import net.minecraft.world.level.Level;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import net.minecraft.world.item.alchemy.Potions;
|
|||
import net.minecraft.world.item.component.TooltipDisplay;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class LeadBreakItemBehavior extends OptionalDispenseItemBehavior {
|
|||
ServerLevel serverLevel = blockSource.level();
|
||||
if(!serverLevel.isClientSide()) {
|
||||
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
|
||||
this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item));
|
||||
this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos));
|
||||
if (this.isSuccess()) {
|
||||
item.hurtAndBreak(1, serverLevel, null, p_348118_ -> {
|
||||
});
|
||||
|
|
@ -53,7 +53,7 @@ public class LeadBreakItemBehavior extends OptionalDispenseItemBehavior {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos, ItemStack item) {
|
||||
private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos) {
|
||||
for (LivingEntity livingentity : level.getEntitiesOfClass(LivingEntity.class, new AABB(pos), EntitySelector.NO_SPECTATORS)) {
|
||||
if (livingentity instanceof PlayerLeashable playerLeashable) {
|
||||
if (playerLeashable.isLeashed()){
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.r3944realms.leashedplayer.datagen.LanguageAndOtherData;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.ModKeyMapping;
|
||||
import com.r3944realms.leashedplayer.content.blocks.ModBlocksRegister;
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.content.commands.MotionCommand;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModEffectRegister;
|
||||
|
|
@ -43,6 +44,8 @@ public enum ModLangKeyValue {
|
|||
AMETHYST_SHEARS(ModItemRegister.AMETHYST_SHEARS, ModPartEnum.ITEM, "Amethyst Shears", "紫水晶剪刀", "紫水晶剪刀", true),
|
||||
NEO_FORGE(ModItemRegister.NEOFORGE, ModPartEnum.ITEM, "NeoForge", "NeoForge", "NeoForge", false),
|
||||
TIPPED_LEASH_ROPE_ARROW(TippedLeashRopeArrowItem.TIPPED_LEASH_ROPE_ARROW_NAME, ModPartEnum.ITEM, "Tipped Leash Rope Arrow Soaked By %1$s", "用%1$s浸泡过的拴绳箭", "蘸有%1$s的拴繩箭", false),
|
||||
//BLOCK_ITEM
|
||||
BLOCK_ITEM_TEST_BLOCK(ModItemRegister.TEST_BLOCK_ITEM, ModPartEnum.ITEM, "Test Block", "测试方块", "測試方塊", true),
|
||||
//ITEM_DESC
|
||||
DESC_ITEM_LEASH_R_ARROW_ONE(LeashRopeArrowItem.DESC_1, ModPartEnum.DESCRIPTION, "§7This arrow will carry the owner along with its flight:", "§7该箭将会携带拥有者随其飞行", "§7該箭將會攜帶擁有者隨其飛行:", false),
|
||||
DESC_ITEM_LEASH_R_ARROW_TWO(LeashRopeArrowItem.DESC_2, ModPartEnum.DESCRIPTION, "§c1.§r If it hits a fence or an entity, it will leash the owner to it and drop as a normal arrow.", "§c1.§r 若击中栅栏或生物时,将持有者拴在其上并已普通箭形式掉落;", "§c1.§r 若擊中柵欄或生物時,將持有者拴在其上並以普通箭的形式掉落;", false),
|
||||
|
|
@ -55,7 +58,8 @@ 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(TippedLeashRopeArrowItem.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),
|
||||
|
||||
//BLOCK
|
||||
BLOCK_TEST_BLOCK(ModBlocksRegister.TEST_BLOCK, ModPartEnum.BLOCK, "Test Block", "测试方块", "測試方塊", 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,5 +1,6 @@
|
|||
package com.r3944realms.leashedplayer.datagen.generator;
|
||||
|
||||
import com.r3944realms.leashedplayer.content.blocks.ModBlocksRegister;
|
||||
import net.minecraft.client.data.models.BlockModelGenerators;
|
||||
import net.minecraft.client.data.models.ItemModelOutput;
|
||||
import net.minecraft.client.data.models.blockstates.BlockModelDefinitionGenerator;
|
||||
|
|
@ -16,6 +17,6 @@ public class ModBlockModelGenerator extends BlockModelGenerators {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
this.createTrivialCube(ModBlocksRegister.TEST_BLOCK.get());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
|||
import com.r3944realms.leashedplayer.datagen.LanguageAndOtherData.ModItemTags;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.tags.ItemTagsProvider;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
import net.neoforged.neoforge.common.data.ItemTagsProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
@ -17,7 +17,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
public class ModItemTagProvider extends ItemTagsProvider {
|
||||
|
||||
public ModItemTagProvider(PackOutput pOutput, CompletableFuture<HolderLookup.Provider> pLookupProvider, CompletableFuture<TagLookup<Block>> pBlockTags) {
|
||||
super(pOutput, pLookupProvider, pBlockTags, LeashedPlayer.MOD_ID);
|
||||
super(pOutput, pLookupProvider,LeashedPlayer.MOD_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,20 +1,52 @@
|
|||
package com.r3944realms.leashedplayer.mixin.both;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public abstract class MixinEntity {
|
||||
@Shadow public abstract void igniteForSeconds(float pSeconds);
|
||||
|
||||
public abstract class MixinEntity implements IEntityLeadExtension {
|
||||
@Unique int Pl$LeashKeepTick;//保存状态,当超过断裂绳长时若LeashKeepTick大于0,则不断裂
|
||||
@Unique float Pl$LeashLength;
|
||||
@Unique boolean Pl$isSync;
|
||||
@Shadow public abstract Level level();
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public float getLeashLength() {
|
||||
return Math.max(Pl$LeashLength, 6.0f);
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public void setLeashLength(float length) {
|
||||
this.Pl$LeashLength = length;
|
||||
}
|
||||
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public void setKeepLeashTick(int keepTick) {
|
||||
this.Pl$LeashKeepTick = Math.max(keepTick, 0);
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public int getKeepLeashTick() {
|
||||
return this.Pl$LeashKeepTick;
|
||||
}
|
||||
|
||||
/**
|
||||
* 这里重定向,当实体类实现了{@link PlayerLeashable}接口时,<br/>
|
||||
|
|
@ -30,8 +62,34 @@ public abstract class MixinEntity {
|
|||
<E extends Entity & Leashable> void checkAndCancelIfTure(ServerLevel f, E entity) {
|
||||
if(!(entity instanceof PlayerLeashable) && level() instanceof ServerLevel serverLevel_) {
|
||||
Leashable.tickLeash(serverLevel_, entity);
|
||||
} else {
|
||||
PlayerLeashable.tickLeash(f, entity);
|
||||
}
|
||||
}
|
||||
@Inject(
|
||||
method = {"saveWithoutId"}, at = {@At("RETURN")}
|
||||
)//数据保存
|
||||
private void addSaveData(ValueOutput valueOutput, CallbackInfo ci) {
|
||||
valueOutput.putFloat("LeashLength", ((IEntityLeadExtension)this).getLeashLength());
|
||||
}
|
||||
@Inject(
|
||||
method = {"load"}, at = {@At("RETURN")}
|
||||
)//数据读取
|
||||
private void readSaveData(ValueInput valueInput, CallbackInfo ci) {
|
||||
Optional<Float> leashLength = valueInput.read("LeashLength", Codec.FLOAT);
|
||||
leashLength.ifPresent(i->((IEntityLeadExtension)this).setLeashLength(i));
|
||||
if(!this.level().isClientSide) ((IEntityLeadExtension)this).setLeadLengthSync(false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public boolean hasLeadLengthSync() {
|
||||
return Pl$isSync;
|
||||
}
|
||||
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public void setLeadLengthSync(boolean sync) {
|
||||
Pl$isSync = sync;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package com.r3944realms.leashedplayer.mixin.both;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(Leashable.class)
|
||||
public interface MixinLeashable {
|
||||
@WrapMethod(method = "leashSnapDistance")
|
||||
default double leashSnapDistance(Operation<Double> original) {
|
||||
if (this instanceof IEntityLeadExtension entityLeadExtension) {
|
||||
int keepLeashTick = entityLeadExtension.getKeepLeashTick();
|
||||
if (keepLeashTick != 0)
|
||||
return Double.MAX_VALUE;
|
||||
return entityLeadExtension.getLeashLength() * LeashedPlayer.M1();
|
||||
}
|
||||
return original.call();
|
||||
}
|
||||
@WrapMethod(method = "leashElasticDistance")
|
||||
default double leashElasticDistance(Operation<Double> original) {
|
||||
if (this instanceof IEntityLeadExtension entityLeadExtension) {
|
||||
return entityLeadExtension.getLeashLength();
|
||||
}
|
||||
return original.call();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,13 @@
|
|||
package com.r3944realms.leashedplayer.mixin.both;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import com.r3944realms.leashedplayer.utils.Logger;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
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.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -27,296 +15,41 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
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 {
|
||||
|
||||
@Unique
|
||||
protected int Pl$LeashKeepTick;//保存状态,当超过断裂绳长时若LeashKeepTick大于0,则不断裂
|
||||
public abstract class MixinPlayer extends LivingEntity implements PlayerLeashable {
|
||||
|
||||
@Unique
|
||||
@Nullable
|
||||
private LeashData Pl$LeashData;//Data
|
||||
|
||||
@SuppressWarnings("WrongEntityDataParameterClass")
|
||||
@Unique//客户端与服务器端的实体同步数据
|
||||
private static final EntityDataAccessor<CompoundTag> Pl$LEASH_DATA = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
|
||||
|
||||
@Unique
|
||||
@SuppressWarnings("WrongEntityDataParameterClass")
|
||||
private static final EntityDataAccessor<Float> DATA_ENTITY_LEASH_LENGTH = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT);
|
||||
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public float getLeashLength() {
|
||||
return this.entityData.get(DATA_ENTITY_LEASH_LENGTH);
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public void setLeashLength(float length) {
|
||||
this.entityData.set(DATA_ENTITY_LEASH_LENGTH, length);
|
||||
}
|
||||
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public void setKeepLeashTick(int keepTick) {
|
||||
this.Pl$LeashKeepTick = Math.max(keepTick, 0);
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public int getKeepLeashTick() {
|
||||
return this.Pl$LeashKeepTick;
|
||||
}
|
||||
|
||||
private Leashable.LeashData Pl$LeashData;//Data
|
||||
|
||||
protected MixinPlayer(EntityType<? extends LivingEntity> pEntityType, Level pLevel) {
|
||||
super(pEntityType, pLevel);
|
||||
}
|
||||
|
||||
@Inject(method = {"tick"}, at = {@At("HEAD")})
|
||||
private void tickForLeash(CallbackInfo ci) {
|
||||
if(!this.level().isClientSide) {
|
||||
Pl$tickLeash();//服务器端每tick任务
|
||||
}
|
||||
PlayerLeashable playerLeashable = this;
|
||||
Entity leashHolder = playerLeashable.getLeashHolder();
|
||||
if(leashHolder != null ) {
|
||||
//存在则更新
|
||||
Pl$UpdateLeash(leashHolder, (Entity) playerLeashable);
|
||||
try {
|
||||
Objects.requireNonNull(this.getAttribute(Attributes.STEP_HEIGHT)).setBaseValue(1.25f);
|
||||
} catch (Exception e) {
|
||||
Logger.logger.error(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Objects.requireNonNull(this.getAttribute(Attributes.STEP_HEIGHT)).setBaseValue(0.6f);
|
||||
} catch (Exception e) {
|
||||
Logger.logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@Unique
|
||||
private static void Pl$UpdateLeash(Entity holderEntity, Entity restrainedEntity) {
|
||||
if (holderEntity == null || holderEntity.level() != restrainedEntity.level()) {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
// 降低坠落伤害
|
||||
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直接退出
|
||||
ILivingEntityExtension self = this;
|
||||
int keepLeashTick = self.getKeepLeashTick();
|
||||
|
||||
//info -> Holder整理
|
||||
Pl$RestoreLeashFormSave();
|
||||
//默认值设为
|
||||
float leashLength = LeashCommand.MIN_VALUE;
|
||||
Entity entity = this.Pl$LeashData.leashHolder;
|
||||
//保存数据
|
||||
saveLeashData(Pl$LeashData);
|
||||
ILivingEntityExtension iEntityExtension = this;//获取设定值
|
||||
float leashLengthSelf = iEntityExtension.getLeashLength();
|
||||
leashLength = leashLengthSelf > LeashCommand.MIN_VALUE ? leashLengthSelf : LeashCommand.MIN_VALUE;
|
||||
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)){
|
||||
//玩家死亡 或 持有者不存在 或 距离大于设定值的 breakDistanceTime 倍且keepTick <=0(长度的 breakDistanceTime 倍若低于 LeashCommand.MIN_VALUE 格,则选 LeashCommand.MIN_VALUE 格) ,
|
||||
// 则取消拴绳关系,并掉落拴绳
|
||||
boolean shouldDrop = !(entity instanceof LeashRopeArrow);
|
||||
Leashable.dropLeash((Entity & Leashable) this, true, shouldDrop);
|
||||
} else if(distanceTo(entity) > leashLength * 0.65f * breakDistanceTime && entity.onGround()) {
|
||||
//大于eashLength * 0.65f * breakDistanceTime 倍绳长且在地面则会让其跳跃(在<1.25格阻拦情况下,跳跃阻拦//TODO:待擴展
|
||||
Entity applyMovementEntity = this.isPassenger() ? this.getVehicle() : this;
|
||||
if(applyMovementEntity instanceof LivingEntity applyMovementLivingEntity) {
|
||||
applyMovementLivingEntity.jumpFromGround();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(keepLeashTick > 0) {//keepTick--
|
||||
self.setKeepLeashTick(keepLeashTick - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getLeashHolder() {
|
||||
if (Pl$LeashData == null) return null;
|
||||
if (Pl$LeashData.leashHolder == null && Pl$LeashData.delayedLeashHolderId != 0 ) {
|
||||
Pl$LeashData.leashHolder = this.level().getEntity(Pl$LeashData.delayedLeashHolderId);
|
||||
}
|
||||
return Pl$LeashData.leashHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据整理 -> 如果Pl$LeashData非null,最终Pl$LeashData的leashHolder将不为null
|
||||
*/
|
||||
@Unique
|
||||
private void Pl$RestoreLeashFormSave() {
|
||||
assert this.Pl$LeashData != null;
|
||||
if(!(this.level() instanceof ServerLevel)) {
|
||||
//非服务器端退出
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.Pl$LeashData.delayedLeashInfo == null) {
|
||||
//delayedLeashInfo无数据
|
||||
if(Pl$LeashData.leashHolder != null) {//且LeashHolder不为null,则直接用它
|
||||
setLeashedTo(Pl$LeashData.leashHolder, true);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
if(this.Pl$LeashData.delayedLeashInfo.left().isPresent()) {
|
||||
//如果有实体的UUID(一般是LivingEntity),则在服务器其通过UUID来查找实体
|
||||
Entity entity = ((ServerLevel) this.level()).getEntity(this.Pl$LeashData.delayedLeashInfo.left().get());
|
||||
if(entity != null) {
|
||||
setLeashedTo(entity, true);
|
||||
}
|
||||
} else if(this.Pl$LeashData.delayedLeashInfo.right().isPresent()) {
|
||||
//如果有实体的坐标(一般就是拴绳结),在服务器端获取拴绳结实体(通过给定坐标和维度获取)
|
||||
setLeashedTo(LeashFenceKnotEntity.getOrCreateKnot(this.level(), this.Pl$LeashData.delayedLeashInfo.right().get()), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
@Override
|
||||
public LeashData getLeashData() {
|
||||
return Pl$LeashData;
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
@Nullable
|
||||
public LeashData getLeashDataFromEntityData() {
|
||||
CompoundTag compoundTag = this.entityData.get(Pl$LEASH_DATA);
|
||||
return compoundTag.read("Pl$LeashData", Leashable.LeashData.CODEC).orElse(null);
|
||||
}
|
||||
@Override
|
||||
public void setLeashData(@org.jetbrains.annotations.Nullable Leashable.LeashData pLeashData) {
|
||||
this.Pl$LeashData = pLeashData;
|
||||
saveLeashData(pLeashData);
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Unique
|
||||
private void saveLeashData(@org.jetbrains.annotations.Nullable LeashData pLeashData) {
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
this.writeLeashData(compoundTag, pLeashData);
|
||||
|
||||
this.entityData.set(Pl$LEASH_DATA, compoundTag);
|
||||
}
|
||||
@SuppressWarnings("AddedMixinMembersNamePattern")
|
||||
@Override
|
||||
public boolean canBeLeashedInstantly(Player player) {
|
||||
return !isLeashed();
|
||||
}
|
||||
@Inject(
|
||||
method = {"defineSynchedData"}, at = {@At("TAIL")}
|
||||
)
|
||||
//定义Client/Server player 同步数据
|
||||
private void defineSyncData (SynchedEntityData.Builder pBuilder, CallbackInfo ci) {
|
||||
CompoundTag leashCompoundTag = new CompoundTag();
|
||||
this.writeLeashData(leashCompoundTag, null);
|
||||
pBuilder.define(Pl$LEASH_DATA, leashCompoundTag);
|
||||
pBuilder.define(DATA_ENTITY_LEASH_LENGTH, 5.0F);
|
||||
}
|
||||
@Inject(
|
||||
method = {"addAdditionalSaveData"}, at = {@At("RETURN")}
|
||||
)//数据保存
|
||||
private void addSaveData(CompoundTag pCompound, CallbackInfo ci) {
|
||||
CompoundTag pLeashTag = new CompoundTag();
|
||||
writeLeashData(pLeashTag, Pl$LeashData);
|
||||
pCompound.put("Pl$LeashData", pLeashTag);
|
||||
this.entityData.set(Pl$LEASH_DATA, pLeashTag);
|
||||
pCompound.putFloat("LeashLength", getLeashLength());
|
||||
private void addSaveData(ValueOutput valueOutput, CallbackInfo ci) {
|
||||
writeLeashData(valueOutput, Pl$LeashData);
|
||||
}
|
||||
@Inject(
|
||||
method = {"readAdditionalSaveData"}, at = {@At("RETURN")}
|
||||
)//数据读取
|
||||
private void readSaveData(CompoundTag pCompound, CallbackInfo ci) {
|
||||
this.readLeashData(pCompound);
|
||||
private void readSaveData(ValueInput valueInput, CallbackInfo ci) {
|
||||
this.readLeashData(valueInput);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
package com.r3944realms.leashedplayer.mixin.client;
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.renderer.LeashRendererUtil;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
|
@ -33,7 +34,7 @@ public abstract class MixinLevelRenderer {
|
|||
method = {"renderLevel"},
|
||||
at = @At(value = "HEAD")
|
||||
)
|
||||
private void renderLevel(GraphicsResourceAllocator graphicsResourceAllocator, DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, Matrix4f frustumMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
private void renderLevel(GraphicsResourceAllocator graphicsResourceAllocator, DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, Matrix4f frustumMatrix, Matrix4f projectionMatrix, GpuBufferSlice gpuBufferSlice, Vector4f vector4f, boolean flag,CallbackInfo ci) {
|
||||
assert this.level != null;
|
||||
PoseStack poseStack = new PoseStack();
|
||||
MultiBufferSource.BufferSource multibuffersource$buffersource = this.renderBuffers.bufferSource();
|
||||
|
|
|
|||
|
|
@ -3,16 +3,17 @@ package com.r3944realms.leashedplayer.mixin.item;
|
|||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.LeadItem;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
|
@ -21,7 +22,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
import java.util.List;
|
||||
|
||||
@Mixin(LeadItem.class)
|
||||
public class MixinLeadItem {
|
||||
public abstract class MixinLeadItem extends Item {
|
||||
public MixinLeadItem(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拴住自己的逻辑
|
||||
*/
|
||||
|
|
@ -30,7 +35,7 @@ public class MixinLeadItem {
|
|||
at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private static void selfLeash(Player pPlayer, Level pLevel, BlockPos pPos, CallbackInfoReturnable<InteractionResult> cir) {
|
||||
List<Leashable> list = LeadItem.leashableInArea(pLevel, pPos, p_353025_ -> p_353025_.getLeashHolder() == pPlayer);
|
||||
List<Leashable> list = Leashable.leashableInArea(pLevel, Vec3.atCenterOf(pPos), p_353025_ -> p_353025_.getLeashHolder() == pPlayer);
|
||||
if (list.isEmpty()) {
|
||||
ItemStack mainHandItem = pPlayer.getMainHandItem();
|
||||
if (!(mainHandItem.getItem() instanceof LeadItem )) {
|
||||
|
|
@ -39,7 +44,7 @@ public class MixinLeadItem {
|
|||
//非创造模式减少,防止刷物品
|
||||
if(!pPlayer.isCreative()) mainHandItem.shrink(1);
|
||||
//自己
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) pPlayer, (ServerLevel) pLevel);
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(pPlayer, (ServerLevel) pLevel);
|
||||
PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer;
|
||||
if(leashDataEntity != null) {
|
||||
Leashable.dropLeash((Entity & Leashable) playerLeashable, true, true);
|
||||
|
|
|
|||
|
|
@ -39,16 +39,16 @@ public class MixinServerGamePacketListenerImpl {
|
|||
}
|
||||
@Inject(method = {"teleport(Lnet/minecraft/world/entity/PositionMoveRotation;Ljava/util/Set;)V"}, at = {@At("TAIL")})
|
||||
private void teleportTail(PositionMoveRotation moveRotation, Set<Relative> pRelativeSet, CallbackInfo ci) {
|
||||
if(GameruleRegistry.getGameruleBoolValue(this.player.serverLevel(), TeleportWithLeashedPlayers.ID)) {
|
||||
if(GameruleRegistry.getGameruleBoolValue(this.player.level(), TeleportWithLeashedPlayers.ID)) {
|
||||
for (Entity Pl$LeashPlayer : this.Pl$LeashPlayers) {
|
||||
if(Pl$LeashPlayer instanceof ServerPlayer) {
|
||||
if(Pl$LeashPlayer instanceof PlayerLeashable playerLeashable) {
|
||||
Leashable.dropLeash((Entity & Leashable) playerLeashable, false,false);
|
||||
if(((ServerPlayer) playerLeashable).serverLevel() == this.player.serverLevel()) {
|
||||
if(((ServerPlayer) playerLeashable).level() == this.player.level()) {
|
||||
((ServerPlayer) playerLeashable).connection.teleport(moveRotation, pRelativeSet);
|
||||
} else {
|
||||
Vec3 vec3 = moveRotation.deltaMovement();
|
||||
((ServerPlayer) playerLeashable).teleportTo(this.player.serverLevel(), vec3.x, vec3.y, vec3.z, pRelativeSet, moveRotation.yRot(), moveRotation.yRot(),false);
|
||||
((ServerPlayer) playerLeashable).teleportTo(this.player.level(), vec3.x, vec3.y, vec3.z, pRelativeSet, moveRotation.yRot(), moveRotation.yRot(),false);
|
||||
((ServerPlayer) playerLeashable).stopRiding();
|
||||
}
|
||||
playerLeashable.setLeashedTo(this.player, true);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.r3944realms.leashedplayer.modInterface;
|
||||
|
||||
public interface ILivingEntityExtension {
|
||||
public interface IEntityLeadExtension {
|
||||
/**
|
||||
* 获取拴绳的长度
|
||||
* @return length 拴绳的长度(Float)
|
||||
|
|
@ -25,4 +25,16 @@ public interface ILivingEntityExtension {
|
|||
* @return keepTick 等待tick(int)
|
||||
*/
|
||||
int getKeepLeashTick();
|
||||
|
||||
/**
|
||||
* 是否需要同步
|
||||
* @apiNote 该为服务器方法,只能在服务器端调用,切勿在客户端线程调用
|
||||
* @return boolean
|
||||
*/
|
||||
boolean hasLeadLengthSync();
|
||||
/**
|
||||
* 设置是否需要同步
|
||||
* @apiNote 该为服务器方法,只能在服务器端调用,切勿在客户端线程调用
|
||||
*/
|
||||
void setLeadLengthSync(boolean sync);
|
||||
}
|
||||
|
|
@ -1,58 +1,179 @@
|
|||
package com.r3944realms.leashedplayer.modInterface;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.criteriaTriggers.ModCriteriaTriggers;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.network.client.UpdatePlayerMovement;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface PlayerLeashable extends Leashable {
|
||||
|
||||
/**
|
||||
* 获取拴绳的持有者实体 可能不存在
|
||||
*/
|
||||
@Nullable
|
||||
Entity getLeashHolder();
|
||||
static <E extends Entity & Leashable> void tickLeash(ServerLevel level, E p_entity) {
|
||||
Leashable.LeashData leashable$leashdata = p_entity.getLeashData();
|
||||
if (leashable$leashdata != null && leashable$leashdata.delayedLeashInfo != null) {
|
||||
restoreLeashFromSave(p_entity, leashable$leashdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拴绳的持有者数据 (从EntityData中获取
|
||||
*/
|
||||
LeashData getLeashDataFromEntityData();
|
||||
if (leashable$leashdata != null && leashable$leashdata.leashHolder != null) {
|
||||
if (!p_entity.isAlive() || !leashable$leashdata.leashHolder.isAlive()) {
|
||||
if (level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
||||
p_entity.dropLeash();
|
||||
} else {
|
||||
p_entity.removeLeash();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否立即可被拴住
|
||||
*/
|
||||
boolean canBeLeashedInstantly(Player player);
|
||||
Entity entity = p_entity.getLeashHolder();
|
||||
if (entity != null && entity.level() == p_entity.level()) {
|
||||
double d0 = p_entity.leashDistanceTo(entity);
|
||||
p_entity.whenLeashedTo(entity);
|
||||
int keepLeashTick = 0;
|
||||
if(entity instanceof IEntityLeadExtension leadExtension) {
|
||||
keepLeashTick = leadExtension.getKeepLeashTick();
|
||||
}
|
||||
if (d0 > p_entity.leashSnapDistance() && keepLeashTick == 0) {
|
||||
level.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F);
|
||||
p_entity.leashTooFarBehaviour();
|
||||
|
||||
} else if (d0 > p_entity.leashElasticDistance() - entity.getBbWidth() - p_entity.getBbWidth()
|
||||
&& p_entity.checkElasticInteractions(entity, leashable$leashdata)) {
|
||||
p_entity.onElasticLeashPull();
|
||||
} else {
|
||||
p_entity.closeRangeLeashBehaviour(entity);
|
||||
}
|
||||
|
||||
p_entity.setYRot((float)(p_entity.getYRot() - leashable$leashdata.angularMomentum));
|
||||
leashable$leashdata.angularMomentum = leashable$leashdata.angularMomentum * Leashable.angularFriction(p_entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
default void writeLeashData(CompoundTag tag, @org.jetbrains.annotations.Nullable Leashable.LeashData leashData) {
|
||||
tag.storeNullable("Pl$LeashData", Leashable.LeashData.CODEC, leashData);
|
||||
default boolean checkElasticInteractions(Entity p_entity, Leashable.@NotNull LeashData p_418158_) {
|
||||
boolean flag = p_entity.supportQuadLeashAsHolder() && this.supportQuadLeash();
|
||||
List<Leashable.Wrench> list = computeElasticInteraction(
|
||||
(Entity & Leashable)this,
|
||||
p_entity,
|
||||
flag ? SHARED_QUAD_ATTACHMENT_POINTS : ENTITY_ATTACHMENT_POINT,
|
||||
flag ? SHARED_QUAD_ATTACHMENT_POINTS : LEASHER_ATTACHMENT_POINT
|
||||
);
|
||||
if (list.isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
Leashable.Wrench leashable$wrench = Leashable.Wrench.accumulate(list).scale(flag ? 0.25 : 1.0);
|
||||
p_418158_.angularMomentum = p_418158_.angularMomentum + 10.0 * leashable$wrench.torque();
|
||||
|
||||
Entity applyMovementEntity = ((Entity & Leashable)this).isPassenger() ? ((Entity & Leashable)this).getVehicle() : ((Entity & Leashable)this);
|
||||
Vec3 vec3 = Leashable.getHolderMovement(((Entity & Leashable)this)).subtract(((Entity)this).getKnownMovement());
|
||||
if (applyMovementEntity != null) {
|
||||
Vec3 add = leashable$wrench.force().multiply(AXIS_SPECIFIC_ELASTICITY).add(vec3.scale(0.11));
|
||||
if (applyMovementEntity instanceof ServerPlayer player) {
|
||||
PacketDistributor.sendToPlayer(player,new UpdatePlayerMovement(UpdatePlayerMovement.Operation.ADD, add.x, add.y, add.z));
|
||||
} else applyMovementEntity.addDeltaMovement(add);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private static <E extends Entity & Leashable> List<Leashable.Wrench> computeElasticInteraction(
|
||||
E p_418297_, Entity p_418456_, List<Vec3> p_418351_, List<Vec3> p_418397_
|
||||
) {
|
||||
double d0 = p_418297_.leashElasticDistance();
|
||||
Vec3 vec3 = Leashable.getHolderMovement(p_418297_);
|
||||
float f = p_418297_.getYRot() * (float) (Math.PI / 180.0);
|
||||
Vec3 vec31 = new Vec3(p_418297_.getBbWidth(), p_418297_.getBbHeight(), p_418297_.getBbWidth());
|
||||
float f1 = p_418456_.getYRot() * (float) (Math.PI / 180.0);
|
||||
Vec3 vec32 = new Vec3(p_418456_.getBbWidth(), p_418456_.getBbHeight(), p_418456_.getBbWidth());
|
||||
List<Leashable.Wrench> list = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < p_418351_.size(); i++) {
|
||||
Vec3 vec33 = p_418351_.get(i).multiply(vec31).yRot(-f);
|
||||
Vec3 vec34 = p_418297_.position().add(vec33);
|
||||
Vec3 vec35 = p_418397_.get(i).multiply(vec32).yRot(-f1);
|
||||
Vec3 vec36 = p_418456_.position().add(vec35);
|
||||
Leashable.computeDampenedSpringInteraction(vec36, vec34, d0, vec3, vec33).ifPresent(list::add);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
@Override
|
||||
default double leashElasticDistance() {
|
||||
if (this instanceof IEntityLeadExtension entityLeadExtension) {
|
||||
return entityLeadExtension.getLeashLength();
|
||||
}
|
||||
return 6.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void readLeashData(CompoundTag tag) {
|
||||
CompoundTag compoundTag = tag.read("Pl$LeashData", CompoundTag.CODEC).orElse(null);
|
||||
if (compoundTag != null) {
|
||||
Leashable.LeashData leashable$leashdata = compoundTag.read("Pl$LeashData", Leashable.LeashData.CODEC).orElse(null);
|
||||
if (this.getLeashData() != null && leashable$leashdata == null) {
|
||||
this.removeLeash();
|
||||
}
|
||||
this.setLeashData(leashable$leashdata);
|
||||
default double leashSnapDistance() {
|
||||
if (this instanceof IEntityLeadExtension entityLeadExtension) {
|
||||
return entityLeadExtension.getLeashLength() * LeashedPlayer.M1();
|
||||
}
|
||||
return 12.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void leashTooFarBehaviour() {
|
||||
boolean shouldDrop = !(this instanceof LeashRopeArrow);
|
||||
Leashable.dropLeash((Entity & Leashable) this, true, shouldDrop);
|
||||
}
|
||||
|
||||
|
||||
static <E extends Entity & Leashable> void restoreLeashFromSave(E p_entity, Leashable.LeashData leashData) {
|
||||
if (leashData.delayedLeashInfo != null && p_entity.level() instanceof ServerLevel serverlevel) {
|
||||
Optional<UUID> optional1 = leashData.delayedLeashInfo.left();
|
||||
Optional<BlockPos> optional = leashData.delayedLeashInfo.right();
|
||||
if (optional1.isPresent()) {
|
||||
Entity entity = serverlevel.getEntity(optional1.get());
|
||||
if (entity != null) {
|
||||
setLeashedTo(p_entity, entity, true);
|
||||
return;
|
||||
}
|
||||
} else if (optional.isPresent()) {
|
||||
setLeashedTo(p_entity, LeashFenceKnotEntity.getOrCreateKnot(serverlevel, optional.get()), true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_entity.tickCount > 100) {
|
||||
p_entity.spawnAtLocation(serverlevel, Items.LEAD);
|
||||
p_entity.setLeashData(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default void writeLeashData(@NotNull ValueOutput valueOutput, @org.jetbrains.annotations.Nullable Leashable.LeashData leashData) {
|
||||
valueOutput.storeNullable("Pl$LeashData", Leashable.LeashData.CODEC, leashData);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void readLeashData(ValueInput valueInput) {
|
||||
LeashData leashData = valueInput.read("Pl$LeashData", Leashable.LeashData.CODEC).orElse(null);
|
||||
if (getLeashData() != null && leashData == null) {
|
||||
this.removeLeash();
|
||||
}
|
||||
this.setLeashData(leashData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -82,101 +203,36 @@ 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();
|
||||
if (leashDataFromEntityData != null) {
|
||||
return getLeashDataEntity(leashDataFromEntityData, serverLevel);
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
static Entity getLeashDataEntityOrThrown(@NotNull ServerPlayer serverPlayer ,@NotNull ServerLevel serverLevel) throws Exception {
|
||||
Entity leashedEntity = getLeashDataEntity(serverPlayer, serverLevel);
|
||||
if(leashedEntity == null) throw new Exception("invalid");
|
||||
else return leashedEntity;
|
||||
Entity entity = getLeashDataEntity(serverPlayer, serverLevel);
|
||||
if(entity == null) throw new Exception("invalid");
|
||||
else return entity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Entity getLeashDataEntity(@NotNull Leashable.LeashData leashDataFromEntityData, @NotNull ServerLevel level) {
|
||||
if(leashDataFromEntityData.delayedLeashInfo != null) {
|
||||
Optional<UUID> UUID = leashDataFromEntityData.delayedLeashInfo.left();
|
||||
Optional<BlockPos> BlockPos = leashDataFromEntityData.delayedLeashInfo.right();
|
||||
static Entity getLeashDataEntity(@NotNull Entity entity, @NotNull ServerLevel level) {
|
||||
if (entity instanceof Leashable leashable) {
|
||||
LeashData data = leashable.getLeashData();
|
||||
if (data != null) {
|
||||
return PlayerLeashable.getLeashDataEntity(data, level);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Nullable
|
||||
static Entity getLeashDataEntity(@NotNull Leashable.LeashData leashData, @NotNull ServerLevel level) {
|
||||
if(leashData.delayedLeashInfo != null) {
|
||||
Optional<UUID> UUID = leashData.delayedLeashInfo.left();
|
||||
Optional<BlockPos> BlockPos = leashData.delayedLeashInfo.right();
|
||||
if (UUID.isPresent()) {
|
||||
return level.getEntity(UUID.get());
|
||||
} else return BlockPos.map(pos -> LeashFenceKnotEntity.getOrCreateKnot(level, pos)).orElse(null);
|
||||
}
|
||||
else if(leashDataFromEntityData.leashHolder != null) {
|
||||
return leashDataFromEntityData.leashHolder;
|
||||
else if(leashData.leashHolder != null) {
|
||||
return leashData.leashHolder;
|
||||
}
|
||||
else if(leashDataFromEntityData.delayedLeashHolderId != 0) {
|
||||
return level.getEntity(leashDataFromEntityData.delayedLeashHolderId);
|
||||
else if(leashData.delayedLeashHolderId != 0) {
|
||||
return level.getEntity(leashData.delayedLeashHolderId);
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
|
@ -207,20 +263,6 @@ public interface PlayerLeashable extends Leashable {
|
|||
throw new Exception("invalid leash data");
|
||||
}
|
||||
}
|
||||
static boolean isLeashFenceKnotEntityExisted(ServerLevel pLevel, BlockPos pPos) {
|
||||
int i = pPos.getX();
|
||||
int j = pPos.getY();
|
||||
int k = pPos.getZ();
|
||||
|
||||
for (LeashFenceKnotEntity leashfenceknotentity : pLevel.getEntitiesOfClass(
|
||||
LeashFenceKnotEntity.class, new AABB((double)i - 1.0, (double)j - 1.0, (double)k - 1.0, (double)i + 1.0, (double)j + 1.0, (double)k + 1.0)
|
||||
)) {
|
||||
if (leashfenceknotentity.getPos().equals(pPos)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Nullable
|
||||
static Entity getLeashFenceKnotEntity(ServerLevel pLevel, BlockPos pPos) {
|
||||
int i = pPos.getX();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package com.r3944realms.leashedplayer.network;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.network.client.SyncLeashRopeLength;
|
||||
import com.r3944realms.leashedplayer.network.client.UpdatePlayerMovement;
|
||||
import com.r3944realms.leashedplayer.network.server.DecreaseLeashRopeLength;
|
||||
import com.r3944realms.leashedplayer.network.server.IncreaseLeashRopeLength;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
||||
|
|
@ -20,6 +22,11 @@ public class LeashedPlayerNetwork {
|
|||
UpdatePlayerMovement.STREAM_CODEC,
|
||||
UpdatePlayerMovement::handle
|
||||
);
|
||||
registrar.playToClient(
|
||||
SyncLeashRopeLength.TYPE,
|
||||
SyncLeashRopeLength.STREAM_CODEC,
|
||||
SyncLeashRopeLength::handle
|
||||
);
|
||||
registrar.playToServer(
|
||||
IncreaseLeashRopeLength.TYPE,
|
||||
IncreaseLeashRopeLength.STREAM_CODEC,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package com.r3944realms.leashedplayer.network.client;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record SyncLeashRopeLength(String entityUUID, float length) implements CustomPacketPayload {
|
||||
public static final Type<SyncLeashRopeLength> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID,"sync_leash_rope_length"));
|
||||
public static final StreamCodec<FriendlyByteBuf, SyncLeashRopeLength> STREAM_CODEC =
|
||||
StreamCodec.composite(
|
||||
ByteBufCodecs.STRING_UTF8, SyncLeashRopeLength::entityUUID,
|
||||
ByteBufCodecs.FLOAT, SyncLeashRopeLength::length,
|
||||
SyncLeashRopeLength::new
|
||||
);
|
||||
public void handle(IPayloadContext context) {
|
||||
context.enqueueWork(() -> {
|
||||
Entity entity = context.player().level().getEntity(UUID.fromString(entityUUID));
|
||||
if (entity instanceof IEntityLeadExtension entityLeadExtension) {
|
||||
entityLeadExtension.setLeashLength(length);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package com.r3944realms.leashedplayer.network.server;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -36,16 +36,18 @@ public record DecreaseLeashRopeLength(Code code, String playerUUID) implements C
|
|||
ServerLevel level = (ServerLevel) player.level();
|
||||
Player playerByUUID = level.getPlayerByUUID(UUID.fromString(playerUUID));
|
||||
if (playerByUUID != null) {
|
||||
ILivingEntityExtension entityExtension = (ILivingEntityExtension) playerByUUID;
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) playerByUUID, level);
|
||||
IEntityLeadExtension entityExtension = (IEntityLeadExtension) playerByUUID;
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(playerByUUID, level);
|
||||
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);
|
||||
entityExtension.setLeadLengthSync(false);
|
||||
((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);
|
||||
entityExtension.setLeadLengthSync(false);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(DECREASE_SELF_LEASH_ROPE_LENGTH, newValue), true);
|
||||
} else {
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.r3944realms.leashedplayer.network.server;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IEntityLeadExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -19,12 +19,12 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
import java.util.UUID;
|
||||
|
||||
public record IncreaseLeashRopeLength(Code code, String playerUUID) implements CustomPacketPayload {
|
||||
public record IncreaseLeashRopeLength(Code code, String entityUUID) implements CustomPacketPayload {
|
||||
public static final Type<IncreaseLeashRopeLength> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID,"add_leash_rope_length"));
|
||||
public static final StreamCodec<FriendlyByteBuf, IncreaseLeashRopeLength> STREAM_CODEC =
|
||||
StreamCodec.composite(
|
||||
NeoForgeStreamCodecs.enumCodec(Code.class), IncreaseLeashRopeLength::code,
|
||||
ByteBufCodecs.STRING_UTF8, IncreaseLeashRopeLength::playerUUID,
|
||||
ByteBufCodecs.STRING_UTF8, IncreaseLeashRopeLength::entityUUID,
|
||||
IncreaseLeashRopeLength::new
|
||||
);
|
||||
public static final String INCREASE_LEASH_ROPE_LENGTH = "leashedplayer.leash_rope.length.increase",
|
||||
|
|
@ -35,18 +35,20 @@ public record IncreaseLeashRopeLength(Code code, String playerUUID) implements C
|
|||
context.enqueueWork(() -> {
|
||||
Player player = context.player();
|
||||
ServerLevel level = (ServerLevel) player.level();
|
||||
Player playerByUUID = level.getPlayerByUUID(UUID.fromString(playerUUID));
|
||||
Player playerByUUID = level.getPlayerByUUID(UUID.fromString(entityUUID));
|
||||
if (playerByUUID != null) {
|
||||
ILivingEntityExtension entityExtension = (ILivingEntityExtension) playerByUUID;
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) playerByUUID, level);
|
||||
IEntityLeadExtension entityExtension = (IEntityLeadExtension) playerByUUID;
|
||||
Entity leashDataEntity = PlayerLeashable.getLeashDataEntity(playerByUUID, level);
|
||||
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);
|
||||
entityExtension.setLeadLengthSync(false);
|
||||
((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);
|
||||
entityExtension.setLeadLengthSync(false);
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(INCREASE_SELF_LEASH_ROPE_LENGTH, newValue), true);
|
||||
} else {
|
||||
((ServerPlayer) playerByUUID).sendSystemMessage(Component.translatable(Code.LEASH_LENGTH_FAILED_SET), true);
|
||||
|
|
|
|||
|
|
@ -22,4 +22,8 @@ public net.minecraft.world.effect.MobEffect <init>(Lnet/minecraft/world/effect/M
|
|||
public net.minecraft.world.inventory.ArmorSlot #ArmorSlot
|
||||
#private -> protected
|
||||
protected net.minecraft.world.entity.projectile.Projectile cachedOwner # cachedOwner
|
||||
protected net.minecraft.world.entity.projectile.Projectile ownerUUID # ownerUUID
|
||||
protected net.minecraft.world.entity.projectile.Projectile ownerUUID # ownerUUID
|
||||
public net.minecraft.world.entity.Leashable$Wrench torqueFromForce(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;)D # torqueFromForce
|
||||
public net.minecraft.world.entity.Leashable$Wrench accumulate(Ljava/util/List;)Lnet/minecraft/world/entity/Leashable$Wrench; # accumulate
|
||||
public net.minecraft.world.entity.Leashable computeDampenedSpringInteraction(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;DLnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;)Ljava/util/Optional; # computeDampenedSpringInteraction
|
||||
public net.minecraft.world.entity.Leashable getHolderMovement(Lnet/minecraft/world/entity/Entity;)Lnet/minecraft/world/phys/Vec3; # getHolderMovement
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 212 B |
Binary file not shown.
|
After Width: | Height: | Size: 253 B |
|
|
@ -2,6 +2,7 @@
|
|||
"package": "com.r3944realms.leashedplayer.mixin",
|
||||
"mixins": [
|
||||
"both.MixinEntity",
|
||||
"both.MixinLeashable",
|
||||
"both.MixinLivingEntity",
|
||||
"both.MixinPlayer",
|
||||
"item.MixinArmorSlotMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user