diff --git a/Deprecated/BasicEntityModel.java b/Deprecated/BasicEntityModel.java new file mode 100644 index 0000000..91e6185 --- /dev/null +++ b/Deprecated/BasicEntityModel.java @@ -0,0 +1,39 @@ +package com.r3944realms.leashedplayer.client.models; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; + +import java.util.function.Function; + +public abstract class BasicEntityModel extends EntityModel { + public int textureWidth = 64; + public int textureHeight = 32; + + protected BasicEntityModel() { + this(RenderType::entityCutoutNoCull); + } + + protected BasicEntityModel(Function pRenderType) { + super(pRenderType); + } + + @Override + public void renderToBuffer(PoseStack p_103013_, VertexConsumer p_103014_, int p_103015_, int p_103016_, float p_103017_, float p_103018_, float p_103019_, float p_103020_) { + this.parts().forEach((p_103030_) -> { + p_103030_.render(p_103013_, p_103014_, p_103015_, p_103016_, p_103017_, p_103018_, p_103019_, p_103020_); + }); + } + + public abstract Iterable parts(); + + @Override + public abstract void setupAnim(T p_102618_, float p_102619_, float p_102620_, float p_102621_, float p_102622_, float p_102623_); + + @Override + public void prepareMobModel(T p_102614_, float p_102615_, float p_102616_, float p_102617_) { + } +} \ No newline at end of file diff --git a/Deprecated/BasicModelPart.java b/Deprecated/BasicModelPart.java new file mode 100644 index 0000000..f06a11b --- /dev/null +++ b/Deprecated/BasicModelPart.java @@ -0,0 +1,314 @@ +package com.r3944realms.leashedplayer.client.models; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.neoforge.client.event.RenderTooltipEvent; +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.joml.Vector4f; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import net.minecraft.core.Direction; + + +import java.util.Random; + +/* + * @since 1.9.0 + * Duplicate of ModelPart class which is not final + */ +@OnlyIn(Dist.CLIENT) +public class BasicModelPart { + public float textureWidth = 64.0F; + public float textureHeight = 32.0F; + public int textureOffsetX; + public int textureOffsetY; + public float rotationPointX; + public float rotationPointY; + public float rotationPointZ; + public float rotateAngleX; + public float rotateAngleY; + public float rotateAngleZ; + public boolean mirror; + public boolean showModel = true; + private final ObjectList cubeList = new ObjectArrayList<>(); + private final ObjectList childModels = new ObjectArrayList<>(); + + public BasicModelPart(BasicEntityModel model) { + this.setTextureSize(model.textureWidth, model.textureHeight); + } + + public BasicModelPart(BasicEntityModel model, int texOffX, int texOffY) { + this(model.textureWidth, model.textureHeight, texOffX, texOffY); + } + + public BasicModelPart(int textureWidthIn, int textureHeightIn, int textureOffsetXIn, int textureOffsetYIn) { + this.setTextureSize(textureWidthIn, textureHeightIn); + this.setTextureOffset(textureOffsetXIn, textureOffsetYIn); + } + + private BasicModelPart() { + } + + public BasicModelPart getModelAngleCopy() { + BasicModelPart BasicModelPart = new BasicModelPart(); + BasicModelPart.copyModelAngles(this); + return BasicModelPart; + } + + public void copyModelAngles(BasicModelPart BasicModelPartIn) { + this.rotateAngleX = BasicModelPartIn.rotateAngleX; + this.rotateAngleY = BasicModelPartIn.rotateAngleY; + this.rotateAngleZ = BasicModelPartIn.rotateAngleZ; + this.rotationPointX = BasicModelPartIn.rotationPointX; + this.rotationPointY = BasicModelPartIn.rotationPointY; + this.rotationPointZ = BasicModelPartIn.rotationPointZ; + } + + /** + * Sets the current box's rotation points and rotation angles to another box. + */ + public void addChild(BasicModelPart renderer) { + this.childModels.add(renderer); + } + + public BasicModelPart setTextureOffset(int x, int y) { + this.textureOffsetX = x; + this.textureOffsetY = y; + return this; + } + + public BasicModelPart addBox(String partName, float x, float y, float z, int width, int height, int depth, float delta, int texX, int texY) { + this.setTextureOffset(texX, texY); + this.addBox(this.textureOffsetX, this.textureOffsetY, x, y, z, (float)width, (float)height, (float)depth, delta, delta, delta, this.mirror, false); + return this; + } + + public BasicModelPart addBox(float x, float y, float z, float width, float height, float depth) { + this.addBox(this.textureOffsetX, this.textureOffsetY, x, y, z, width, height, depth, 0.0F, 0.0F, 0.0F, this.mirror, false); + return this; + } + + public BasicModelPart addBox(float x, float y, float z, float width, float height, float depth, boolean mirrorIn) { + this.addBox(this.textureOffsetX, this.textureOffsetY, x, y, z, width, height, depth, 0.0F, 0.0F, 0.0F, mirrorIn, false); + return this; + } + + public void addBox(float x, float y, float z, float width, float height, float depth, float delta) { + this.addBox(this.textureOffsetX, this.textureOffsetY, x, y, z, width, height, depth, delta, delta, delta, this.mirror, false); + } + + public void addBox(float x, float y, float z, float width, float height, float depth, float deltaX, float deltaY, float deltaZ) { + this.addBox(this.textureOffsetX, this.textureOffsetY, x, y, z, width, height, depth, deltaX, deltaY, deltaZ, this.mirror, false); + } + + public void addBox(float x, float y, float z, float width, float height, float depth, float delta, boolean mirrorIn) { + this.addBox(this.textureOffsetX, this.textureOffsetY, x, y, z, width, height, depth, delta, delta, delta, mirrorIn, false); + } + + private void addBox(int texOffX, int texOffY, float x, float y, float z, float width, float height, float depth, float deltaX, float deltaY, float deltaZ, boolean mirorIn, boolean p_228305_13_) { + this.cubeList.add(new BasicModelPart.ModelBox(texOffX, texOffY, x, y, z, width, height, depth, deltaX, deltaY, deltaZ, mirorIn, this.textureWidth, this.textureHeight)); + } + + public void setRotationPoint(float rotationPointXIn, float rotationPointYIn, float rotationPointZIn) { + this.rotationPointX = rotationPointXIn; + this.rotationPointY = rotationPointYIn; + this.rotationPointZ = rotationPointZIn; + } + + public void render(PoseStack matrixStackIn, VertexConsumer bufferIn, int packedLightIn, int packedOverlayIn) { + this.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, 1.0F, 1.0F, 1.0F, 1.0F); + } + + public void render(PoseStack matrixStackIn, VertexConsumer bufferIn, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float alpha) { + if (this.showModel) { + if (!this.cubeList.isEmpty() || !this.childModels.isEmpty()) { + matrixStackIn.pushPose(); + this.translateRotate(matrixStackIn); + this.doRender(matrixStackIn.last(), bufferIn, packedLightIn, packedOverlayIn, red, green, blue, alpha); + + for(BasicModelPart BasicModelPart : this.childModels) { + BasicModelPart.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, red, green, blue, alpha); + } + + matrixStackIn.popPose(); + } + } + } + + public void translateRotate(PoseStack matrixStackIn) { + matrixStackIn.translate((double)(this.rotationPointX / 16.0F), (double)(this.rotationPointY / 16.0F), (double)(this.rotationPointZ / 16.0F)); + if (this.rotateAngleZ != 0.0F) { + matrixStackIn.mulPose(Axis.ZP.rotation(this.rotateAngleZ)); + } + + if (this.rotateAngleY != 0.0F) { + matrixStackIn.mulPose(Axis.YP.rotation(this.rotateAngleY)); + } + + if (this.rotateAngleX != 0.0F) { + matrixStackIn.mulPose(Axis.XP.rotation(this.rotateAngleX)); + } + + } + + private void doRender(PoseStack.Pose matrixEntryIn, VertexConsumer bufferIn, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float alpha) { + Matrix4f matrix4f = matrixEntryIn.pose(); + Matrix3f matrix3f = matrixEntryIn.normal(); + + for(BasicModelPart.ModelBox BasicModelPart$modelbox : this.cubeList) { + for(BasicModelPart.TexturedQuad BasicModelPart$texturedquad : BasicModelPart$modelbox.quads) { + Vector3f vector3f = new Vector3f(BasicModelPart$texturedquad.normal); + vector3f.mul(matrix3f); + float f = vector3f.x(); + float f1 = vector3f.y(); + float f2 = vector3f.z(); + + for(int i = 0; i < 4; ++i) { + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex = BasicModelPart$texturedquad.vertexPositions[i]; + float f3 = BasicModelPart$positiontexturevertex.position.x() / 16.0F; + float f4 = BasicModelPart$positiontexturevertex.position.y() / 16.0F; + float f5 = BasicModelPart$positiontexturevertex.position.z() / 16.0F; + Vector4f vector4f = new Vector4f(f3, f4, f5, 1.0F); + vector4f.mul(matrix4f); + bufferIn + .setColor(red, green, blue, alpha) + .addVertex(vector4f.x(), vector4f.y(), vector4f.z()) + .setUv(BasicModelPart$positiontexturevertex.textureU, BasicModelPart$positiontexturevertex.textureV) + .setLight(packedLightIn) + .setOverlay(packedOverlayIn) + .setNormal(f, f1, f2); + } + } + } + + } + + /** + * Returns the model renderer with the new texture parameters. + */ + public BasicModelPart setTextureSize(int textureWidthIn, int textureHeightIn) { + this.textureWidth = (float)textureWidthIn; + this.textureHeight = (float)textureHeightIn; + return this; + } + + public BasicModelPart.ModelBox getRandomCube(Random randomIn) { + return this.cubeList.get(randomIn.nextInt(this.cubeList.size())); + } + + @OnlyIn(Dist.CLIENT) + public static class ModelBox { + private final BasicModelPart.TexturedQuad[] quads; + public final float posX1; + public final float posY1; + public final float posZ1; + public final float posX2; + public final float posY2; + public final float posZ2; + + public ModelBox(int texOffX, int texOffY, float x, float y, float z, float width, float height, float depth, float deltaX, float deltaY, float deltaZ, boolean mirorIn, float texWidth, float texHeight) { + this.posX1 = x; + this.posY1 = y; + this.posZ1 = z; + this.posX2 = x + width; + this.posY2 = y + height; + this.posZ2 = z + depth; + this.quads = new BasicModelPart.TexturedQuad[6]; + float f = x + width; + float f1 = y + height; + float f2 = z + depth; + x = x - deltaX; + y = y - deltaY; + z = z - deltaZ; + f = f + deltaX; + f1 = f1 + deltaY; + f2 = f2 + deltaZ; + if (mirorIn) { + float f3 = f; + f = x; + x = f3; + } + + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex7 = new BasicModelPart.PositionTextureVertex(x, y, z, 0.0F, 0.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex = new BasicModelPart.PositionTextureVertex(f, y, z, 0.0F, 8.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex1 = new BasicModelPart.PositionTextureVertex(f, f1, z, 8.0F, 8.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex2 = new BasicModelPart.PositionTextureVertex(x, f1, z, 8.0F, 0.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex3 = new BasicModelPart.PositionTextureVertex(x, y, f2, 0.0F, 0.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex4 = new BasicModelPart.PositionTextureVertex(f, y, f2, 0.0F, 8.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex5 = new BasicModelPart.PositionTextureVertex(f, f1, f2, 8.0F, 8.0F); + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex6 = new BasicModelPart.PositionTextureVertex(x, f1, f2, 8.0F, 0.0F); + float f4 = (float)texOffX; + float f5 = (float)texOffX + depth; + float f6 = (float)texOffX + depth + width; + float f7 = (float)texOffX + depth + width + width; + float f8 = (float)texOffX + depth + width + depth; + float f9 = (float)texOffX + depth + width + depth + width; + float f10 = (float)texOffY; + float f11 = (float)texOffY + depth; + float f12 = (float)texOffY + depth + height; + this.quads[2] = new BasicModelPart.TexturedQuad(new BasicModelPart.PositionTextureVertex[]{BasicModelPart$positiontexturevertex4, BasicModelPart$positiontexturevertex3, BasicModelPart$positiontexturevertex7, BasicModelPart$positiontexturevertex}, f5, f10, f6, f11, texWidth, texHeight, mirorIn, Direction.DOWN); + this.quads[3] = new BasicModelPart.TexturedQuad(new BasicModelPart.PositionTextureVertex[]{BasicModelPart$positiontexturevertex1, BasicModelPart$positiontexturevertex2, BasicModelPart$positiontexturevertex6, BasicModelPart$positiontexturevertex5}, f6, f11, f7, f10, texWidth, texHeight, mirorIn, Direction.UP); + this.quads[1] = new BasicModelPart.TexturedQuad(new BasicModelPart.PositionTextureVertex[]{BasicModelPart$positiontexturevertex7, BasicModelPart$positiontexturevertex3, BasicModelPart$positiontexturevertex6, BasicModelPart$positiontexturevertex2}, f4, f11, f5, f12, texWidth, texHeight, mirorIn, Direction.WEST); + this.quads[4] = new BasicModelPart.TexturedQuad(new BasicModelPart.PositionTextureVertex[]{BasicModelPart$positiontexturevertex, BasicModelPart$positiontexturevertex7, BasicModelPart$positiontexturevertex2, BasicModelPart$positiontexturevertex1}, f5, f11, f6, f12, texWidth, texHeight, mirorIn, Direction.NORTH); + this.quads[0] = new BasicModelPart.TexturedQuad(new BasicModelPart.PositionTextureVertex[]{BasicModelPart$positiontexturevertex4, BasicModelPart$positiontexturevertex, BasicModelPart$positiontexturevertex1, BasicModelPart$positiontexturevertex5}, f6, f11, f8, f12, texWidth, texHeight, mirorIn, Direction.EAST); + this.quads[5] = new BasicModelPart.TexturedQuad(new BasicModelPart.PositionTextureVertex[]{BasicModelPart$positiontexturevertex3, BasicModelPart$positiontexturevertex4, BasicModelPart$positiontexturevertex5, BasicModelPart$positiontexturevertex6}, f8, f11, f9, f12, texWidth, texHeight, mirorIn, Direction.SOUTH); + } + } + + @OnlyIn(Dist.CLIENT) + static class PositionTextureVertex { + public final Vector3f position; + public final float textureU; + public final float textureV; + + public PositionTextureVertex(float x, float y, float z, float texU, float texV) { + this(new Vector3f(x, y, z), texU, texV); + } + + public BasicModelPart.PositionTextureVertex setTextureUV(float texU, float texV) { + return new BasicModelPart.PositionTextureVertex(this.position, texU, texV); + } + + public PositionTextureVertex(Vector3f posIn, float texU, float texV) { + this.position = posIn; + this.textureU = texU; + this.textureV = texV; + } + } + + @OnlyIn(Dist.CLIENT) + static class TexturedQuad { + public final BasicModelPart.PositionTextureVertex[] vertexPositions; + public final Vector3f normal; + + public TexturedQuad(BasicModelPart.PositionTextureVertex[] positionsIn, float u1, float v1, float u2, float v2, float texWidth, float texHeight, boolean mirrorIn, Direction directionIn) { + this.vertexPositions = positionsIn; + float f = 0.0F / texWidth; + float f1 = 0.0F / texHeight; + positionsIn[0] = positionsIn[0].setTextureUV(u2 / texWidth - f, v1 / texHeight + f1); + positionsIn[1] = positionsIn[1].setTextureUV(u1 / texWidth + f, v1 / texHeight + f1); + positionsIn[2] = positionsIn[2].setTextureUV(u1 / texWidth + f, v2 / texHeight - f1); + positionsIn[3] = positionsIn[3].setTextureUV(u2 / texWidth - f, v2 / texHeight - f1); + if (mirrorIn) { + int i = positionsIn.length; + + for(int j = 0; j < i / 2; ++j) { + BasicModelPart.PositionTextureVertex BasicModelPart$positiontexturevertex = positionsIn[j]; + positionsIn[j] = positionsIn[i - 1 - j]; + positionsIn[i - 1 - j] = BasicModelPart$positiontexturevertex; + } + } + + this.normal = directionIn.step(); + if (mirrorIn) { + this.normal.mul(-1.0F, 1.0F, 1.0F); + } + + } + } +} \ No newline at end of file diff --git a/Deprecated/ChainTieEntity.java b/Deprecated/ChainTieEntity.java new file mode 100644 index 0000000..3a7f511 --- /dev/null +++ b/Deprecated/ChainTieEntity.java @@ -0,0 +1,166 @@ +package com.r3944realms.leashedplayer.content.entities; + +import com.r3944realms.leashedplayer.content.entities.props.ChainLeashable; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerEntity; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.BlockAttachedEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.WallBlock; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ChainTieEntity extends BlockAttachedEntity { + + public ChainTieEntity(EntityType type, Level worldIn, BlockPos hangingPositionIn) { + super(type, worldIn, hangingPositionIn); + this.setPos(hangingPositionIn.getX() + 0.5D, hangingPositionIn.getY(), hangingPositionIn.getZ() + 0.5D); + } + + public ChainTieEntity(EntityType hangingEntityEntityType, Level level) { + super(hangingEntityEntityType, level); + } + + + public void playPlacementSound() { + this.playSound(SoundEvents.ARMOR_EQUIP_CHAIN.value(), 1.0F, 1.0F); + } + public static ChainTieEntity createTie(Level worldIn, BlockPos fence) { + ChainTieEntity entityChainTie = new ChainTieEntity(ModEntityRegister.CHAIN_TIE.get(), worldIn, fence); + worldIn.addFreshEntity(entityChainTie); + entityChainTie.playPlacementSound(); + return entityChainTie; + } + public static ChainTieEntity getOrCreateKnot(Level pLevel, BlockPos pPos) { + int i = pPos.getX(); + int j = pPos.getY(); + int k = pPos.getZ(); + + for (ChainTieEntity chainTieEntity : pLevel.getEntitiesOfClass( + ChainTieEntity.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 (chainTieEntity.getPos().equals(pPos)) { + return chainTieEntity; + } + } + + ChainTieEntity chainTieEntity = createTie(pLevel, pPos); + pLevel.addFreshEntity(chainTieEntity); + return chainTieEntity; + } + + @Override + protected void recalculateBoundingBox() { + this.setPosRaw( + this.pos.getX() + 0.5D, + this.pos.getY() + 0.5D, + this.pos.getZ() + 0.5D + ); + double xSize = 0.3D; + double ySize = 0.875D; + this.setBoundingBox( + new AABB( + this.getX() - xSize, + this.getY() - 0.5, + this.getZ() - xSize, + this.getX() + xSize, + this.getY() + ySize - 0.5, + this.getZ() + xSize + ) + ); + } + @Override + public @NotNull InteractionResult interact(@NotNull Player pPlayer, @NotNull InteractionHand pHand) { + if (this.level().isClientSide) { + return InteractionResult.SUCCESS; + } else { + boolean flag = false; + List list = ChainLeashable.leashableInArea(this.level(), this.getPos(), chainLeashable -> { + Entity entity = chainLeashable.getLeashHolder(); + return entity == pPlayer || entity == this; + }); + + for (ChainLeashable ChainLeashable : list) { + if (ChainLeashable.getLeashHolder() == pPlayer) { + ChainLeashable.setLeashedTo(this, true); + flag = true; + } + } + + boolean flag1 = false; + if (!flag) { + this.discard(); + if (pPlayer.getAbilities().instabuild) { + for (ChainLeashable ChainLeashable : list) { + if (ChainLeashable.isLeashed() && ChainLeashable.getLeashHolder() == this) { + ChainLeashable.dropLeash(true, false); + flag1 = true; + } + } + } + } + + if (flag || flag1) { + this.gameEvent(GameEvent.BLOCK_ATTACH, pPlayer); + } + + return InteractionResult.CONSUME; + } + } + @Override + public boolean shouldRenderAtSqrDistance(double distance) { + return distance < 1024.0D; + } + + @Override + public boolean survives() { + return this.level().getBlockState(this.pos).getBlock() instanceof WallBlock; + } + + @Override + public void dropItem(@Nullable Entity pEntity) { + this.playSound(SoundEvents.ARMOR_EQUIP_CHAIN.value(), 1.0F, 1.0F); + } + + + @Override + protected void defineSynchedData(SynchedEntityData.@NotNull Builder pBuilder) { + + } + + + @Override + public void setPos(double x, double y, double z) { + super.setPos(Mth.floor(x) + 0.5D, Mth.floor(y) + 0.5D, Mth.floor(z) + 0.5D); + } + @Override + public @NotNull Packet getAddEntityPacket(@NotNull ServerEntity pEntity) { + return new ClientboundAddEntityPacket(this, 0, this.getPos()); + } + @Override + public @NotNull Vec3 getRopeHoldPosition(float pPartialTicks) { + return this.getPosition(pPartialTicks).add(0.0, 0.2, 0.0); + } + + @Override + public ItemStack getPickResult() { + return new ItemStack(Items.CHAIN); + } +} diff --git a/Deprecated/ChainTieModel.java b/Deprecated/ChainTieModel.java new file mode 100644 index 0000000..1012ccd --- /dev/null +++ b/Deprecated/ChainTieModel.java @@ -0,0 +1,4 @@ +package com.r3944realms.leashedplayer.client.models; + +public class ChainTieModel extends BasicEnti{ +} diff --git a/Deprecated/props/ChainLeashable.java b/Deprecated/props/ChainLeashable.java new file mode 100644 index 0000000..31834c1 --- /dev/null +++ b/Deprecated/props/ChainLeashable.java @@ -0,0 +1,210 @@ +package com.r3944realms.leashedplayer.content.entities.props; + +import com.mojang.datafixers.util.Either; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.decoration.LeashFenceKnotEntity; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Predicate; + +public interface ChainLeashable { + String LEASH_TAG = "chain_leash"; + @Nullable + ChainLeashable.ChainData getLeashData(); + + void setLeashData(@Nullable ChainLeashable.ChainData pLeashData); + + default boolean isLeashed() { + return this.getLeashData() != null && this.getLeashData().leashHolder != null; + } + + default boolean mayBeLeashed() { + return this.getLeashData() != null; + } + + default boolean canHaveALeashAttachedToIt() { + return this.canBeLeashed() && !this.isLeashed(); + } + + default boolean canBeLeashed() { + return true; + } + + default boolean handleLeashAtDistance(Entity pLeashHolder, float pDistance) { + return true; + } + + default void leashTooFarBehaviour() { + this.dropLeash(true, true); + } + + default void closeRangeLeashBehaviour(Entity pEntity) { + } + + default void elasticRangeLeashBehaviour(Entity pLeashHolder, float pDistance) { + legacyElasticRangeLeashBehaviour((Entity & ChainLeashable)this, pLeashHolder, pDistance); + } + + @Nullable + default Entity getLeashHolder() { + return getLeashHolder((Entity & ChainLeashable)this); + } + + private static void legacyElasticRangeLeashBehaviour(E pEntity, Entity pLeashHolder, float pDistance) { + double d0 = (pLeashHolder.getX() - pEntity.getX()) / (double)pDistance; + double d1 = (pLeashHolder.getY() - pEntity.getY()) / (double)pDistance; + double d2 = (pLeashHolder.getZ() - pEntity.getZ()) / (double)pDistance; + pEntity.setDeltaMovement( + pEntity.getDeltaMovement().add(Math.copySign(d0 * d0 * 0.4, d0), Math.copySign(d1 * d1 * 0.4, d1), Math.copySign(d2 * d2 * 0.4, d2)) + ); + } + @Nullable + private static Entity getLeashHolder(E pEntity) { + ChainLeashable.ChainData chainLeashable$chaindata = pEntity.getLeashData(); + if (chainLeashable$chaindata == null) { + return null; + } else { + if (chainLeashable$chaindata.delayedLeashHolderId != 0 && pEntity.level().isClientSide) { + Entity entity = pEntity.level().getEntity(chainLeashable$chaindata.delayedLeashHolderId); + if (entity instanceof Entity) { + chainLeashable$chaindata.setLeashHolder(entity); + } + } + + return chainLeashable$chaindata.leashHolder; + } + } + default void setLeashedTo(Entity pLeashHolder, boolean pBroadcastPacket) { + setLeashedTo((Entity & ChainLeashable)this, pLeashHolder, pBroadcastPacket); + } + static List leashableInArea(Level pLevel, BlockPos pPos, Predicate pPredicate) { + double d0 = 7.0; + int i = pPos.getX(); + int j = pPos.getY(); + int k = pPos.getZ(); + AABB aabb = new AABB((double)i - 7.0, (double)j - 7.0, (double)k - 7.0, (double)i + 7.0, (double)j + 7.0, (double)k + 7.0); + return pLevel.getEntitiesOfClass(Entity.class, aabb, p_353023_ -> p_353023_ instanceof ChainLeashable chainLeashable && pPredicate.test(chainLeashable)).stream().map(ChainLeashable.class::cast).toList(); + } + + private static void setLeashedTo(E pEntity, Entity pLeashHolder, boolean pBroadcastPacket) { + ChainLeashable.ChainData chainLeashable$chaindata = pEntity.getLeashData(); + if (chainLeashable$chaindata == null) { + chainLeashable$chaindata = new ChainLeashable.ChainData(pLeashHolder); + pEntity.setLeashData(chainLeashable$chaindata); + } else { + chainLeashable$chaindata.setLeashHolder(pLeashHolder); + } + + if (pBroadcastPacket && pEntity.level() instanceof ServerLevel serverlevel) { + //TODO:自写Packet ClientboundSetEntityLinkPacket(pEntity, pLeashHolder) + serverlevel.getChunkSource().broadcast(pEntity, new ClientboundSetEntityLinkPacket(pEntity, pLeashHolder)); + } + + if (pEntity.isPassenger()) { + pEntity.stopRiding(); + } + } + default void dropLeash(boolean pBroadcastPacket, boolean pDropItem) { + dropLeash((Entity & ChainLeashable)this, pBroadcastPacket, pDropItem); + } + + private static void dropLeash(E pEntity, boolean pBroadcastPacket, boolean pDropItem) { + ChainLeashable.ChainData chainLeashable$chaindata = pEntity.getLeashData(); + if (chainLeashable$chaindata != null && chainLeashable$chaindata.leashHolder != null) { + pEntity.setLeashData(null); + if (!pEntity.level().isClientSide && pDropItem) { + pEntity.spawnAtLocation(Items.CHAIN); + } + + if (pBroadcastPacket && pEntity.level() instanceof ServerLevel serverlevel) { + serverlevel.getChunkSource().broadcast(pEntity, new ClientboundSetEntityLinkPacket(pEntity, null)); + } + } + } + static void tickLeash(E pEntity) { + ChainLeashable.ChainData chainLeashable$chaindata = pEntity.getLeashData(); + if (chainLeashable$chaindata != null && chainLeashable$chaindata.delayedLeashInfo != null) { + restoreLeashFromSave(pEntity, chainLeashable$chaindata); + } + + if (chainLeashable$chaindata != null && chainLeashable$chaindata.leashHolder != null) { + if (!pEntity.isAlive() || !chainLeashable$chaindata.leashHolder.isAlive()) { + dropLeash(pEntity, true, true); + } + + Entity entity = pEntity.getLeashHolder(); + if (entity != null && entity.level() == pEntity.level()) { + float f = pEntity.distanceTo(entity); + if (!pEntity.handleLeashAtDistance(entity, f)) { + return; + } + + if ((double)f > 10.0) { + pEntity.leashTooFarBehaviour(); + } else if ((double)f > 6.0) { + pEntity.elasticRangeLeashBehaviour(entity, f); + pEntity.checkSlowFallDistance(); + } else { + pEntity.closeRangeLeashBehaviour(entity); + } + } + } + } + + private static void restoreLeashFromSave(E pEntity, ChainLeashable.ChainData pLeashData) { + if (pLeashData.delayedLeashInfo != null && pEntity.level() instanceof ServerLevel serverlevel) { + Optional optional1 = pLeashData.delayedLeashInfo.left(); + Optional optional = pLeashData.delayedLeashInfo.right(); + if (optional1.isPresent()) { + Entity entity = serverlevel.getEntity(optional1.get()); + if (entity != null) { + setLeashedTo(pEntity, entity, true); + return; + } + } else if (optional.isPresent()) { + setLeashedTo(pEntity, LeashFenceKnotEntity.getOrCreateKnot(serverlevel, optional.get()), true); + return; + } + + if (pEntity.tickCount > 100) { + pEntity.spawnAtLocation(Items.LEAD); + pEntity.setLeashData(null); + } + } + } + + final class ChainData { + public int delayedLeashHolderId; + @Nullable + public Entity leashHolder; + @Nullable + public Either delayedLeashInfo; + + ChainData(@org.jetbrains.annotations.Nullable Either pDelayedLeashInfo) { + this.delayedLeashInfo = pDelayedLeashInfo; + } + + public ChainData(@org.jetbrains.annotations.Nullable Entity pLeashHolder) { + this.leashHolder = pLeashHolder; + } + + ChainData(int pDelayedLeashInfoId) { + this.delayedLeashHolderId = pDelayedLeashInfoId; + } + + public void setLeashHolder(Entity pLeashHolder) { + this.leashHolder = pLeashHolder; + this.delayedLeashInfo = null; + this.delayedLeashHolderId = 0; + } + } +} diff --git a/Resource/spectral_RL_arrow.png b/Resource/spectral_RL_arrow.png new file mode 100644 index 0000000..6cd0bd6 Binary files /dev/null and b/Resource/spectral_RL_arrow.png differ diff --git a/Resource/spectral_leashed_rope_arrow.png b/Resource/spectral_leashed_rope_arrow.png new file mode 100644 index 0000000..5b47f66 Binary files /dev/null and b/Resource/spectral_leashed_rope_arrow.png differ diff --git a/gradle.properties b/gradle.properties index a49fc9f..e04da80 100644 --- a/gradle.properties +++ b/gradle.properties @@ -32,7 +32,7 @@ mod_name=Leashed Player # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=0.0.3.6 +mod_version=0.0.3.7 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c b/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c index 7deb635..a0e565b 100644 --- a/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c +++ b/src/generated/resources/.cache/0aef4464247e697f9a7226f384437b478152c21c @@ -1,7 +1,8 @@ -// 1.21.1 2024-09-11T16:30:11.5982305 Item Models: leashedplayer +// 1.21.1 2024-10-05T22:32:01.8406652 Item Models: leashedplayer 5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json 845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json 5bd1f9f28b91005c587f1c38fb77cd19b59495e3 assets/leashedplayer/models/item/bow_lra_pulling_2.json 83946f4d60d0fb1758d6553c36330506c8e48ada assets/leashedplayer/models/item/crossbow_leash_rope_arrow.json 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 diff --git a/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 b/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 index d47bed8..778555c 100644 --- a/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 +++ b/src/generated/resources/.cache/1749bb0c3e8c52cfb2d8ed2140e4678c71e770f5 @@ -1,2 +1,2 @@ -// 1.21.1 2024-09-05T15:23:52.4523518 Tags for minecraft:item mod id leashedplayer -a8cd7ac5b7e37b7dea044004a42a2f137d4027d6 data/minecraft/tags/item/arrows.json +// 1.21.1 2024-10-05T22:32:01.8406652 Tags for minecraft:item mod id leashedplayer +36c1cccc1dfa448620c4e9cbc4a7d73986ff9e47 data/minecraft/tags/item/arrows.json diff --git a/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff b/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff index 90f2f69..839418e 100644 --- a/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff +++ b/src/generated/resources/.cache/211976637bfb5e111401ad2bfb58570ef2fb3dff @@ -1,2 +1,2 @@ -// 1.21.1 2024-09-11T16:30:11.6002137 Languages: en_us for mod: leashedplayer -c3d8ea4a7d24b56bd6b701c531aab3132cdc6da9 assets/leashedplayer/lang/en_us.json +// 1.21.1 2024-10-05T22:32:01.8406652 Languages: en_us for mod: leashedplayer +27fb1feca9c95470e67902e0a5287fa717f71137 assets/leashedplayer/lang/en_us.json diff --git a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e index 4b40ca5..4ca692a 100644 --- a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e +++ b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e @@ -1,3 +1,7 @@ -// 1.21.1 2024-09-05T13:20:35.9705404 Recipes +// 1.21.1 2024-10-05T22:33:13.2484086 Recipes 1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json 974d74538b3e172946f2e169036b453b6eb6bc0a data/leashedplayer/recipe/leash_rope_arrow.json +c0e05f359296d3e28573fa1b205ac44736376622 data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_glowstone_dust.json +131fcbef603bfde7204d8e1ad15e4544696926bf data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_leash_rope_arrow.json +bb5909aa91d878c8f0ef9999881cfe89532509dd data/minecraft/recipe/spectral_leash_rope_arrow_with_glowstone_dust.json +a1381da885fbedec01243c78afbb0a50ca803ee4 data/minecraft/recipe/spectral_leash_rope_arrow_with_leash_rope_arrow.json diff --git a/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb b/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb index 6db57b4..14bea95 100644 --- a/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb +++ b/src/generated/resources/.cache/a1129211d3ad6d65c101bb152ae8c66c8256bccb @@ -1,2 +1,2 @@ -// 1.21.1 2024-09-11T16:30:11.5982305 Languages: zh_cn for mod: leashedplayer -7e38a6c0cc14d7f6f362f97b2a00ca1ab2626c68 assets/leashedplayer/lang/zh_cn.json +// 1.21.1 2024-10-05T22:32:01.8406652 Languages: zh_cn for mod: leashedplayer +cf1999519d9de039d6a7d3e6f241f67b68c968ed assets/leashedplayer/lang/zh_cn.json diff --git a/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 b/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 index 4103c82..2e0acbf 100644 --- a/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 +++ b/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 @@ -1,4 +1,5 @@ -// 1.21.1 2024-09-09T15:52:23.955795 Advancements +// 1.21.1 2024-10-05T22:48:57.4441437 Advancements +4d97adba079f1966090a52443bb439319f550680 data/leashedplayer/advancement/advancement_leash_arrow.json f16184b81ea35a0fbd8f2c49b085a96c32818c69 data/leashedplayer/advancement/dog_running_player.json bce12ed339b3b0fded263ba039f7a4e6fcfb84ca data/leashedplayer/advancement/follow_arrow.json 29911bbed5a1b7ede2b08d82e6716cd9463bc061 data/leashedplayer/advancement/leashed_friend.json diff --git a/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d b/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d index 3956bf4..222c7a5 100644 --- a/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d +++ b/src/generated/resources/.cache/ed628fd843215c1bf29a07b9cbd1b26a6af0636d @@ -1,2 +1,2 @@ -// 1.21.1 2024-09-11T16:30:11.5962153 Languages: zh_tw for mod: leashedplayer -1b05b79582ac4bce69560b88179dd216490ec0fe assets/leashedplayer/lang/zh_tw.json +// 1.21.1 2024-10-05T22:32:01.8406652 Languages: zh_tw for mod: leashedplayer +8d4b3e4d8f0513352a7ef4e1373be64f4d77f9cd assets/leashedplayer/lang/zh_tw.json diff --git a/src/generated/resources/assets/leashedplayer/lang/en_us.json b/src/generated/resources/assets/leashedplayer/lang/en_us.json index 84d9dda..7788078 100644 --- a/src/generated/resources/assets/leashedplayer/lang/en_us.json +++ b/src/generated/resources/assets/leashedplayer/lang/en_us.json @@ -1,4 +1,6 @@ { + "advancement.leashedplayer.advancement_leash_arrow": "More advanced flash arrow with a Tether?", + "advancement.leashedplayer.advancement_leash_arrow.desc": "Well, apart from glowing, there doesn't seem to be any other difference", "advancement.leashedplayer.dog_running_player": "It's Walking human time.", "advancement.leashedplayer.dog_running_player.desc": "In the park where dogs are not allowed to be walked, the dog decided to walk the human instead", "advancement.leashedplayer.follow_arrow": "Launch!!!", @@ -7,12 +9,13 @@ "advancement.leashedplayer.leash_arrow.desc": "Maybe you can using it to shoot some mob?", "advancement.leashedplayer.leash_start": "The Power of Traction", "advancement.leashedplayer.leash_start.desc": "Journey to becoming a Leash Expert", - "advancement.leashedplayer.leashed_friend": "Bond by Rope", - "advancement.leashedplayer.leashed_friend.desc": "bond player with lead", + "advancement.leashedplayer.leashed_friend": "Be bound by Rope", + "advancement.leashedplayer.leashed_friend.desc": "Be Bond by player with lead", "advancement.leashedplayer.leashed_self": "Stable Connection", "advancement.leashedplayer.leashed_self.desc": "“Restrain oneself with a rope", "creativetab.leashedplayer.leashedplayer_tab": "Leashed Player", "entity.leashedplayer.leash_rope_arrow": "Leash Rope Arrow", + "entity.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence", "gamerule.LP.KeepLeashNotDropTime": "Keep leash alive Time", @@ -22,6 +25,7 @@ "item.leash_rope_arrow.description": "Arrows with ropes attached?", "item.leashedplayer.fabric": "Fabric", "item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow", + "item.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow", "leashedplayer.command.leash.message.leash.data.clear": "%1$s's LeashData(LeashHolderEntity: %2$s) now is clear", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s has no LeashData can be clear", "leashedplayer.command.leash.message.leash.data.null": "%1$s has no LeashDataEntity", diff --git a/src/generated/resources/assets/leashedplayer/lang/zh_cn.json b/src/generated/resources/assets/leashedplayer/lang/zh_cn.json index ddcad42..a7fdc32 100644 --- a/src/generated/resources/assets/leashedplayer/lang/zh_cn.json +++ b/src/generated/resources/assets/leashedplayer/lang/zh_cn.json @@ -1,4 +1,6 @@ { + "advancement.leashedplayer.advancement_leash_arrow": "更闪亮的拴绳箭?", + "advancement.leashedplayer.advancement_leash_arrow.desc": "嗯,除了发光,似乎没有什么其它不同了", "advancement.leashedplayer.dog_running_player": "遛“人”时间", "advancement.leashedplayer.dog_running_player.desc": "公园不能遛狗,于是狗站起来遛人", "advancement.leashedplayer.follow_arrow": "启航!!!", @@ -8,11 +10,12 @@ "advancement.leashedplayer.leash_start": "牵引之力", "advancement.leashedplayer.leash_start.desc": "拴绳大师之路", "advancement.leashedplayer.leashed_friend": "拴绳链接", - "advancement.leashedplayer.leashed_friend.desc": "用拴绳链接玩家", + "advancement.leashedplayer.leashed_friend.desc": "被玩家用拴绳链接", "advancement.leashedplayer.leashed_self": "稳固联结", "advancement.leashedplayer.leashed_self.desc": "用拴绳拴住自己", "creativetab.leashedplayer.leashedplayer_tab": "可拴玩家", "entity.leashedplayer.leash_rope_arrow": "拴绳箭", + "entity.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它", "gamerule.LP.KeepLeashNotDropTime": "保持拴绳不掉落的时间", @@ -22,6 +25,7 @@ "item.leash_rope_arrow.description": "带有拴绳的箭矢?", "item.leashedplayer.fabric": "Fabric", "item.leashedplayer.leash_rope_arrow": "拴绳箭", + "item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭", "leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴绳数据(拴绳持有者实体:%2$s)现在已清除", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴绳数据可清除", "leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴绳数据实体", diff --git a/src/generated/resources/assets/leashedplayer/lang/zh_tw.json b/src/generated/resources/assets/leashedplayer/lang/zh_tw.json index bd495d3..d42976b 100644 --- a/src/generated/resources/assets/leashedplayer/lang/zh_tw.json +++ b/src/generated/resources/assets/leashedplayer/lang/zh_tw.json @@ -1,4 +1,6 @@ { + "advancement.leashedplayer.advancement_leash_arrow": "更閃亮的拴繩箭?", + "advancement.leashedplayer.advancement_leash_arrow.desc": "嗯,除了發光,其它好像沒什麽不同", "advancement.leashedplayer.dog_running_player": "遛“人”時間", "advancement.leashedplayer.dog_running_player.desc": "公園裏不許遛狗,於是狗站起來遛人", "advancement.leashedplayer.follow_arrow": "啓航!!!", @@ -8,11 +10,12 @@ "advancement.leashedplayer.leash_start": "牽引之力", "advancement.leashedplayer.leash_start.desc": "拴繩大師之路", "advancement.leashedplayer.leashed_friend": "拴繩鏈接", - "advancement.leashedplayer.leashed_friend.desc": "用拴繩鏈接玩家", + "advancement.leashedplayer.leashed_friend.desc": "被玩家用拴繩鏈接", "advancement.leashedplayer.leashed_self": "穩固聯結", "advancement.leashedplayer.leashed_self.desc": "用栓繩拴住自己", "creativetab.leashedplayer.leashedplayer_tab": "可拴玩家", "entity.leashedplayer.leash_rope_arrow": "拴繩箭", + "entity.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結", "gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它", "gamerule.LP.KeepLeashNotDropTime": "保持其不掉落的時間", @@ -22,6 +25,7 @@ "item.leash_rope_arrow.description": "帶有拴繩的箭矢?", "item.leashedplayer.fabric": "Fabric", "item.leashedplayer.leash_rope_arrow": "拴繩箭", + "item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭", "leashedplayer.command.leash.message.leash.data.clear": "%1$s的拴繩數據(拴繩持有者實體:%2$s)現在已清除", "leashedplayer.command.leash.message.leash.data.clear.leash.clear.failed.no_data": "%1$s沒有拴繩數據實體可被清除", "leashedplayer.command.leash.message.leash.data.null": "%1$s沒有拴繩數據實體", diff --git a/src/generated/resources/assets/leashedplayer/models/item/spectral_leash_rope_arrow.json b/src/generated/resources/assets/leashedplayer/models/item/spectral_leash_rope_arrow.json new file mode 100644 index 0000000..a0b1ec6 --- /dev/null +++ b/src/generated/resources/assets/leashedplayer/models/item/spectral_leash_rope_arrow.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "leashedplayer:item/spectral_leash_rope_arrow" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/leashedplayer/advancement/advancement_leash_arrow.json b/src/generated/resources/data/leashedplayer/advancement/advancement_leash_arrow.json new file mode 100644 index 0000000..8add993 --- /dev/null +++ b/src/generated/resources/data/leashedplayer/advancement/advancement_leash_arrow.json @@ -0,0 +1,35 @@ +{ + "parent": "leashedplayer:leash_arrow", + "criteria": { + "has_flash_leash_rope_item": { + "conditions": { + "items": [ + { + "items": "leashedplayer:spectral_leash_rope_arrow" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "display": { + "announce_to_chat": false, + "description": { + "translate": "advancement.leashedplayer.advancement_leash_arrow.desc" + }, + "hidden": true, + "icon": { + "count": 1, + "id": "leashedplayer:spectral_leash_rope_arrow" + }, + "title": { + "translate": "advancement.leashedplayer.advancement_leash_arrow" + } + }, + "requirements": [ + [ + "has_flash_leash_rope_item" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_glowstone_dust.json b/src/generated/resources/data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_glowstone_dust.json new file mode 100644 index 0000000..63dfc08 --- /dev/null +++ b/src/generated/resources/data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_glowstone_dust.json @@ -0,0 +1,43 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_glowstone_dust": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_lead": { + "conditions": { + "items": [ + { + "items": "minecraft:lead" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:spectral_leash_rope_arrow_with_glowstone_dust" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_lead", + "has_glowstone_dust" + ] + ], + "rewards": { + "recipes": [ + "minecraft:spectral_leash_rope_arrow_with_glowstone_dust" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_leash_rope_arrow.json b/src/generated/resources/data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_leash_rope_arrow.json new file mode 100644 index 0000000..1c247aa --- /dev/null +++ b/src/generated/resources/data/minecraft/advancement/recipes/misc/spectral_leash_rope_arrow_with_leash_rope_arrow.json @@ -0,0 +1,43 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_lead": { + "conditions": { + "items": [ + { + "items": "minecraft:lead" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_spectral_arrow": { + "conditions": { + "items": [ + { + "items": "minecraft:spectral_arrow" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_lead", + "has_spectral_arrow" + ] + ], + "rewards": { + "recipes": [ + "minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/spectral_leash_rope_arrow_with_glowstone_dust.json b/src/generated/resources/data/minecraft/recipe/spectral_leash_rope_arrow_with_glowstone_dust.json new file mode 100644 index 0000000..8a79e64 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/spectral_leash_rope_arrow_with_glowstone_dust.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "#": { + "item": "leashedplayer:leash_rope_arrow" + }, + "$": { + "item": "minecraft:glowstone_dust" + } + }, + "pattern": [ + " $ ", + "$#$", + " $ " + ], + "result": { + "count": 1, + "id": "leashedplayer:spectral_leash_rope_arrow" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/spectral_leash_rope_arrow_with_leash_rope_arrow.json b/src/generated/resources/data/minecraft/recipe/spectral_leash_rope_arrow_with_leash_rope_arrow.json new file mode 100644 index 0000000..e0b59e4 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/spectral_leash_rope_arrow_with_leash_rope_arrow.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "minecraft:lead" + }, + { + "item": "minecraft:spectral_arrow" + } + ], + "result": { + "count": 1, + "id": "leashedplayer:spectral_leash_rope_arrow" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/item/arrows.json b/src/generated/resources/data/minecraft/tags/item/arrows.json index 4f76999..6f87cfe 100644 --- a/src/generated/resources/data/minecraft/tags/item/arrows.json +++ b/src/generated/resources/data/minecraft/tags/item/arrows.json @@ -1,5 +1,6 @@ { "values": [ - "leashedplayer:leash_rope_arrow" + "leashedplayer:leash_rope_arrow", + "leashedplayer:spectral_leash_rope_arrow" ] } \ No newline at end of file diff --git a/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java b/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java index d52187c..b36ed46 100644 --- a/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/ClientEventHandler.java @@ -1,9 +1,11 @@ package com.r3944realms.leashedplayer; -import com.r3944realms.leashedplayer.client.renders.LeashRopeArrowRenderer; +import com.r3944realms.leashedplayer.client.renders.entities.LeashRopeArrowRenderer; +import com.r3944realms.leashedplayer.client.renders.entities.SpectralLeashRopeArrowRenderer; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.items.ModItemRegister; +import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.core.component.DataComponents; import net.minecraft.resources.ResourceLocation; @@ -23,11 +25,11 @@ public class ClientEventHandler { ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow"), ((pStack, pLevel, pEntity, pSeed) -> { ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES); - return chargedProjectiles != null && chargedProjectiles.contains(ModItemRegister.LEASH_ROPE_ARROW.get()) ? 1.0F : 0.0F; + return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.LEASH_ROPE_ARROW.get()) || chargedProjectiles.contains(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) ? 1.0F : 0.0F; })); ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("leash_rope_arrow_pulling"), ((pStack, pLevel, pEntity, pSeed) -> - (pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && LeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F + (pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F: 0.0F )); }); @@ -35,6 +37,7 @@ public class ClientEventHandler { @SubscribeEvent public static void RegisterRenderer(EntityRenderersEvent.RegisterRenderers event) { event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new); + event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new); } } diff --git a/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java b/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java index 42705cf..87830ff 100644 --- a/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/CommonEventHandler.java @@ -2,7 +2,10 @@ package com.r3944realms.leashedplayer; import com.mojang.brigadier.CommandDispatcher; import com.r3944realms.leashedplayer.content.commands.LeashCommand; +import com.r3944realms.leashedplayer.content.items.ModCreativeTab; +import com.r3944realms.leashedplayer.content.items.ModItemRegister; import net.minecraft.commands.CommandSourceStack; +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; @@ -23,6 +26,8 @@ public class CommonEventHandler { public static class Mod extends CommonEventHandler { @SubscribeEvent public static void onCommonSetup(FMLCommonSetupEvent event) { + DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get()); + DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); // NeoForge.EVENT_BUS.addListener(Mod::onPlayerTick); } // public static void onPlayerTick(PlayerTickEvent.Pre event) { diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRopeArrowRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/LeashRopeArrowRenderer.java similarity index 93% rename from src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRopeArrowRenderer.java rename to src/main/java/com/r3944realms/leashedplayer/client/renders/entities/LeashRopeArrowRenderer.java index 056f447..1640127 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/LeashRopeArrowRenderer.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/LeashRopeArrowRenderer.java @@ -1,4 +1,4 @@ -package com.r3944realms.leashedplayer.client.renders; +package com.r3944realms.leashedplayer.client.renders.entities; import com.r3944realms.leashedplayer.LeashedPlayer; import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow; diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/SpectralLeashRopeArrowRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/SpectralLeashRopeArrowRenderer.java new file mode 100644 index 0000000..47db288 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/entities/SpectralLeashRopeArrowRenderer.java @@ -0,0 +1,23 @@ +package com.r3944realms.leashedplayer.client.renders.entities; + +import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.content.entities.SpectralLeashRopeArrow; +import net.minecraft.client.renderer.entity.ArrowRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import org.jetbrains.annotations.NotNull; + +@OnlyIn(Dist.CLIENT) +public class SpectralLeashRopeArrowRenderer extends ArrowRenderer { + public static final ResourceLocation SPECTRAL_LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/spectral_leash_rope_arrow.png"); + + public SpectralLeashRopeArrowRenderer(EntityRendererProvider.Context pContext) { + super(pContext); + } + @Override + public @NotNull ResourceLocation getTextureLocation(@NotNull SpectralLeashRopeArrow pEntity) { + return SPECTRAL_LEASH_ROPE_ARROW; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/AdaptiveGuiRendererHandler.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/AdaptiveGuiRendererHandler.java similarity index 96% rename from src/main/java/com/r3944realms/leashedplayer/client/renders/AdaptiveGuiRendererHandler.java rename to src/main/java/com/r3944realms/leashedplayer/client/renders/gui/AdaptiveGuiRendererHandler.java index de016f4..7b1e6c5 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/AdaptiveGuiRendererHandler.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/AdaptiveGuiRendererHandler.java @@ -1,4 +1,4 @@ -package com.r3944realms.leashedplayer.client.renders; +package com.r3944realms.leashedplayer.client.renders.gui; import com.google.common.collect.Maps; import com.mojang.blaze3d.vertex.PoseStack; diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/IFadingProcessBarRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/IFadingProcessBarRenderer.java similarity index 97% rename from src/main/java/com/r3944realms/leashedplayer/client/renders/IFadingProcessBarRenderer.java rename to src/main/java/com/r3944realms/leashedplayer/client/renders/gui/IFadingProcessBarRenderer.java index bf0b0cd..2b1fc4c 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/IFadingProcessBarRenderer.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/IFadingProcessBarRenderer.java @@ -1,4 +1,4 @@ -package com.r3944realms.leashedplayer.client.renders; +package com.r3944realms.leashedplayer.client.renders.gui; import com.mojang.blaze3d.vertex.PoseStack; import com.r3944realms.leashedplayer.client.processBar.IProcessBar; diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/IProcessBarRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/IProcessBarRenderer.java similarity index 89% rename from src/main/java/com/r3944realms/leashedplayer/client/renders/IProcessBarRenderer.java rename to src/main/java/com/r3944realms/leashedplayer/client/renders/gui/IProcessBarRenderer.java index 0aa6019..dd905c4 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/IProcessBarRenderer.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/IProcessBarRenderer.java @@ -1,4 +1,4 @@ -package com.r3944realms.leashedplayer.client.renders; +package com.r3944realms.leashedplayer.client.renders.gui; import com.mojang.blaze3d.vertex.PoseStack; import com.r3944realms.leashedplayer.client.processBar.IProcessBar; diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/ProcessBarRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/ProcessBarRenderer.java similarity index 98% rename from src/main/java/com/r3944realms/leashedplayer/client/renders/ProcessBarRenderer.java rename to src/main/java/com/r3944realms/leashedplayer/client/renders/gui/ProcessBarRenderer.java index ad9bab7..72aa90d 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/ProcessBarRenderer.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/ProcessBarRenderer.java @@ -1,4 +1,4 @@ -package com.r3944realms.leashedplayer.client.renders; +package com.r3944realms.leashedplayer.client.renders.gui; import com.mojang.blaze3d.vertex.PoseStack; import com.r3944realms.leashedplayer.LeashedPlayer; diff --git a/src/main/java/com/r3944realms/leashedplayer/client/renders/TestProcessBarRenderer.java b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/TestProcessBarRenderer.java similarity index 98% rename from src/main/java/com/r3944realms/leashedplayer/client/renders/TestProcessBarRenderer.java rename to src/main/java/com/r3944realms/leashedplayer/client/renders/gui/TestProcessBarRenderer.java index a218f44..09a0834 100644 --- a/src/main/java/com/r3944realms/leashedplayer/client/renders/TestProcessBarRenderer.java +++ b/src/main/java/com/r3944realms/leashedplayer/client/renders/gui/TestProcessBarRenderer.java @@ -1,4 +1,4 @@ -package com.r3944realms.leashedplayer.client.renders; +package com.r3944realms.leashedplayer.client.renders.gui; import com.mojang.blaze3d.vertex.PoseStack; import com.r3944realms.leashedplayer.client.processBar.IProcessBar; diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java index d1113d9..ea21bc5 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/LeashRopeArrow.java @@ -3,7 +3,7 @@ package com.r3944realms.leashedplayer.content.entities; import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig; import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry; import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTime; -import com.r3944realms.leashedplayer.content.items.LeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem; import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension; import com.r3944realms.leashedplayer.modInterface.PlayerLeashable; @@ -26,176 +26,176 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class LeashRopeArrow extends AbstractArrow { - private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get(); - protected LeashRopeArrow(EntityType entityType,Level pLevel) { - super(entityType, pLevel); - } - - protected LeashRopeArrow(double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { - super(ModEntityRegister.LEASH_ROPE_ARROW.get(), pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon); - if(serverPlayer != null && !level().isClientSide) { - ((PlayerLeashable)serverPlayer).setLeashedTo(this, true); + private static final int maxLifeTime = LeashPlayerCommonConfig.TheLeashArrowMaxLifeTime.get(); + protected LeashRopeArrow(EntityType entityType,Level pLevel) { + super(entityType, pLevel); } - } - public LeashRopeArrow(LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { - super(ModEntityRegister.LEASH_ROPE_ARROW.get(), pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); - if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { - lPlayer.setLeashedTo(this, true); + public LeashRopeArrow(EntityType entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { + super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon); + if(serverPlayer != null && !level().isClientSide) { + ((PlayerLeashable)serverPlayer).setLeashedTo(this, true); + } } - } - public static boolean isLeashRopeArrow(ItemStack bowStack, LivingEntity entity) { - if (entity instanceof Player player) { - // 获取将要发射的弹药 - ItemStack projectileStack = player.getProjectile(bowStack); - - // 判断该弹药是否为改箭 - return projectileStack.getItem() instanceof LeashRopeArrowItem; + public LeashRopeArrow(EntityType entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { + super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); + if(pOwner instanceof PlayerLeashable lPlayer && !level().isClientSide) { + lPlayer.setLeashedTo(this, true); + } } - return false; - } - @Override - protected @NotNull ItemStack getDefaultPickupItem() { - return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance(); - } - - @Override - public void setOwner(@Nullable Entity pEntity) { - super.setOwner(pEntity); - - this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED; - } - - @Override - protected boolean tryPickup(@NotNull Player pPlayer) { - //时间1.40 禁止 - //时间2.240 - // 如果(非仅创造拾取) - // 如果 (按Shift ) - // 如果(拥有者) -> 拾取到完整箭,取消绑定(super给父类处理) - // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定(当前拥有者的Holder是否为本箭,“是”才重绑定) - // 否则: 禁止 - // 否则: - // 如果 (按Shift ) - // 如果(拥有者) -> 且拾取到完整箭,取消绑定 - // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定 - // 否则: 禁止 - //时间3 - // 如果(拥有者) -> 拾取到完整箭,取消绑定 - // 否则:不能获取完整的箭,重绑定 - - if(life <= 40 ) { - return false; + @Override + protected @NotNull ItemStack getDefaultPickupItem() { + return ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance(); } - else { - PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; - if(life <= 240) { - if(pPlayer.isShiftKeyDown()) { + + @Override + public void setOwner(@Nullable Entity pEntity) { + super.setOwner(pEntity); + + this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED; + } + + @Override + protected boolean tryPickup(@NotNull Player pPlayer) { + //时间1.40 禁止 + //时间2.240 + // 如果(非仅创造拾取) + // 如果 (按Shift ) + // 如果(拥有者) -> 拾取到完整箭,取消绑定(super给父类处理) + // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定(当前拥有者的Holder是否为本箭,“是”才重绑定) + // 否则: 禁止 + // 否则: + // 如果 (按Shift ) + // 如果(拥有者) -> 且拾取到完整箭,取消绑定 + // 否则:时间仍为原需时间 ->不能获取完整的箭,重绑定 + // 否则: 禁止 + //时间3 + // 如果(拥有者) -> 拾取到完整箭,取消绑定 + // 否则:不能获取完整的箭,重绑定 + + if(life <= 40 ) { + return false; + } + else { + PlayerLeashable playerLeashable = (PlayerLeashable) pPlayer; + if(this.getOwner() == null) {//未有Owner始终可检 + return true; + } + if(life <= 240) { + if(pPlayer.isShiftKeyDown()) { + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()); + if(this.ownedBy(pPlayer)) { + this.pickup = Pickup.ALLOWED; + if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false); + } else { + if(life >= 120) { + Entity owner = getOwner(); + if( owner != null ) { + if(this.equals(leashDataEntity)) { + ((PlayerLeashable) owner).setLeashedTo(pPlayer, true); + ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), Items.ARROW.getDefaultInstance()); + level().addFreshEntity(itemEntity); + discard(); + } + } else return true; + } else return false; + } + } else return false; + + } + else { Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()); if(this.ownedBy(pPlayer)) { this.pickup = Pickup.ALLOWED; if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false); } else { - if(life >= 120) { + if(this.equals(leashDataEntity)) { Entity owner = getOwner(); - if( owner != null ) { - if(this.equals(leashDataEntity)) { - ((PlayerLeashable) owner).setLeashedTo(pPlayer, true); - ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), Items.ARROW.getDefaultInstance()); - level().addFreshEntity(itemEntity); - discard(); - } - } else return true; - } else return false; - } - } else return false; + ((PlayerLeashable)owner).setLeashedTo(pPlayer, true); + ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), Items.ARROW.getDefaultInstance()); + level().addFreshEntity(itemEntity); + discard(); + } + } + } } - else { - Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) this.getOwner(), (ServerLevel) level()); - if(this.ownedBy(pPlayer)) { - this.pickup = Pickup.ALLOWED; - if(this.equals(leashDataEntity)) playerLeashable.dropLeash(true, false); - } else { - if(this.equals(leashDataEntity)) { - Entity owner = getOwner(); - ((PlayerLeashable)owner).setLeashedTo(pPlayer, true); - ItemEntity itemEntity = new ItemEntity(level(), getX(), getY(), getZ(), Items.ARROW.getDefaultInstance()); - level().addFreshEntity(itemEntity); + + return super.tryPickup(pPlayer); + } + + + @Override + protected void tickDespawn() { + this.life++; + if (this.life >= maxLifeTime) { + ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance()); + this.level().addFreshEntity(leash_rope_arrow); + this.discard(); + } + } + + @Override + protected void onHitBlock(@NotNull BlockHitResult pResult) { + 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()); + if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); + Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos()); + ILivingEntityExtension pLL = (ILivingEntityExtension) pL; + pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + pL.setLeashedTo(leashKnotFence, true); + ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance()); + this.level().addFreshEntity(arrow); discard(); } - } } + super.onHitBlock(pResult); + } - return super.tryPickup(pPlayer); - } - - - @Override - protected void tickDespawn() { - this.life++; - if (this.life >= maxLifeTime) { - ItemEntity leash_rope_arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, ModItemRegister.LEASH_ROPE_ARROW.get().getDefaultInstance()); - this.level().addFreshEntity(leash_rope_arrow); - this.discard(); - } - } - - @Override - protected void onHitBlock(@NotNull BlockHitResult pResult) { - 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()); - if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); - Entity leashKnotFence = PlayerLeashable.createLeashKnotFence((ServerLevel) this.level(), pResult.getBlockPos()); - ILivingEntityExtension pLL = (ILivingEntityExtension) pL; - pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); - pL.setLeashedTo(leashKnotFence, true); - ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance()); - this.level().addFreshEntity(arrow); - discard(); + @Override + protected void onHitEntity(@NotNull EntityHitResult pResult) { + if(!level().isClientSide()){ + Entity entity = pResult.getEntity(); + if(entity instanceof LivingEntity livingEntity){ + if(livingEntity.equals(this.getOwner())) return; + if(this.getOwner() == null && livingEntity instanceof PlayerLeashable pL) { //发射器发出或命令生成 + setOwner(livingEntity); + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); + if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); + ILivingEntityExtension pLL = (ILivingEntityExtension) pL; + pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + pL.setLeashedTo(this, true); + return; + } else if (this.getOwner() instanceof PlayerLeashable pL) { + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); + if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); + ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance()); + ILivingEntityExtension pLL = (ILivingEntityExtension) pL; + pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + pL.setLeashedTo(pResult.getEntity(), true); + this.level().addFreshEntity(arrow); + discard(); + } + } else if (entity instanceof LeashFenceKnotEntity leashKnotFence) { + if (getOwner() instanceof PlayerLeashable pL) { + Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); + if(leashDataEntity != null) pL.dropLeash(true, true); + ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance()); + ILivingEntityExtension pLL = (ILivingEntityExtension) pL; + pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); + pL.setLeashedTo(leashKnotFence, true); + this.level().addFreshEntity(arrow); + discard(); + return; + } } } + super.onHitEntity(pResult); } - super.onHitBlock(pResult); - - } - - @Override - protected void onHitEntity(@NotNull EntityHitResult pResult) { - if(!level().isClientSide()){ - Entity entity = pResult.getEntity(); - if(entity instanceof LivingEntity){ - if(entity.equals(this.getOwner())) return; - if (getOwner() instanceof PlayerLeashable pL) { - Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); - if(leashDataEntity != null) pL.dropLeash(true, !(leashDataEntity instanceof LeashRopeArrow)); - ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance()); - ILivingEntityExtension pLL = (ILivingEntityExtension) pL; - pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); - pL.setLeashedTo(pResult.getEntity(), true); - this.level().addFreshEntity(arrow); - discard(); - } - } else if (entity instanceof LeashFenceKnotEntity leashKnotFence) { - if (getOwner() instanceof PlayerLeashable pL) { - Entity leashDataEntity = PlayerLeashable.getLeashDataEntity((ServerPlayer) getOwner(), (ServerLevel) level()); - if(leashDataEntity != null) pL.dropLeash(true, true); - ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, Items.ARROW.getDefaultInstance()); - ILivingEntityExtension pLL = (ILivingEntityExtension) pL; - pLL.setKeepLeashTick(GameruleRegistry.getGameruleIntValue(level(), KeepLeashNotDropTime.ID)); - pL.setLeashedTo(leashKnotFence, true); - this.level().addFreshEntity(arrow); - discard(); - return; - } - } - } - super.onHitEntity(pResult); - } } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java index 434bebf..75c067f 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/ModEntityRegister.java @@ -19,6 +19,21 @@ public class ModEntityRegister { .updateInterval(20) .build("leash_rope_arrow") ); + public static final DeferredHolder, EntityType> SPECTRAL_LEASH_ROPE_ARROW = ENTITY_TYPE.register( + "spectral_leash_rope_arrow", + () -> EntityType.Builder.of(SpectralLeashRopeArrow::new, MobCategory.MISC) + .sized(0.5F, 0.5F) + .eyeHeight(0.13F) + .clientTrackingRange(4) + .updateInterval(20) + .build("spectral_leash_rope_arrow") + ); +// public static final DeferredHolder, EntityType> CHAIN_TIE = ENTITY_TYPE.register( +// "chain_tie", +// () -> EntityType.Builder.of(ChainTieEntity::new, MobCategory.MISC) +// .sized(0.8F, 0.9F) +// .build("chain_tie") +// ); public static String getEntityNameKey(String entityName) { return "entity." + LeashedPlayer.MOD_ID + "." + entityName; } diff --git a/src/main/java/com/r3944realms/leashedplayer/content/entities/SpectralLeashRopeArrow.java b/src/main/java/com/r3944realms/leashedplayer/content/entities/SpectralLeashRopeArrow.java new file mode 100644 index 0000000..e5e7414 --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/entities/SpectralLeashRopeArrow.java @@ -0,0 +1,61 @@ +package com.r3944realms.leashedplayer.content.entities; + +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; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SpectralLeashRopeArrow extends LeashRopeArrow { + private int duration = 200; + + public SpectralLeashRopeArrow(EntityType entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) { + super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon, serverPlayer); + } + + protected SpectralLeashRopeArrow(EntityType entityType, Level pLevel) { + super(entityType, pLevel); + } + + public SpectralLeashRopeArrow(EntityType entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) { + super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon); + } + @Override + public void tick() { + super.tick(); + if (this.level().isClientSide && !this.inGround) { + this.level().addParticle(ParticleTypes.INSTANT_EFFECT, this.getX(), this.getY(), this.getZ(), 0.0, 0.0, 0.0); + } + } + @Override + protected void doPostHurtEffects(@NotNull LivingEntity pLiving) { + super.doPostHurtEffects(pLiving); + MobEffectInstance mobeffectinstance = new MobEffectInstance(MobEffects.GLOWING, this.duration, 0); + pLiving.addEffect(mobeffectinstance, this.getEffectSource()); + } + + /** + * (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"); + } + } + + @Override + public void addAdditionalSaveData(@NotNull CompoundTag pCompound) { + super.addAdditionalSaveData(pCompound); + pCompound.putInt("Duration", this.duration); + } + +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java b/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java index ae000c0..18d4111 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/ModCreativeTab.java @@ -4,7 +4,6 @@ import com.r3944realms.leashedplayer.LeashedPlayer; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.Items; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredRegister; @@ -23,7 +22,7 @@ public class ModCreativeTab { .displayItems(((pParameters, pOutput) -> { pOutput.accept(Items.LEAD); pOutput.accept(ModItemRegister.LEASH_ROPE_ARROW.get()); - pOutput.accept(ModItemRegister.FABRIC.get()); + pOutput.accept(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); })).build()); public static String getCreativeMod(@NotNull String tabs) { return LEASHED_PLAYER_TAB_STRING + "." + tabs; diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java b/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java index 6f63505..ccc43fd 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/ModItemRegister.java @@ -1,8 +1,12 @@ package com.r3944realms.leashedplayer.content.items; import com.r3944realms.leashedplayer.LeashedPlayer; +import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.items.type.SpectralLeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.items.type.TestItem; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.item.Item; +import net.minecraft.world.item.SpectralArrowItem; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredRegister; @@ -17,6 +21,8 @@ public class ModItemRegister { public static final Supplier LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow", () -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16)) ); + public static final Supplier SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow", + () -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16))); public static final Supplier FABRIC = ModItemRegister.register("fabric", () -> new TestItem(new Item.Properties().stacksTo(1)) diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/type/ILeashRopeArrow.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/ILeashRopeArrow.java new file mode 100644 index 0000000..71e185a --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/ILeashRopeArrow.java @@ -0,0 +1,19 @@ +package com.r3944realms.leashedplayer.content.items.type; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; + +public interface ILeashRopeArrow { + static boolean isLeashRopeArrow(ItemStack bowStack, LivingEntity entity) { + if (entity instanceof Player player) { + + // 获取将要发射的弹药 + ItemStack projectileStack = player.getProjectile(bowStack); + + // 判断该弹药是否为拴绳箭 + return projectileStack.getItem() instanceof ILeashRopeArrow; + } + return false; + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/LeashRopeArrowItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java similarity index 57% rename from src/main/java/com/r3944realms/leashedplayer/content/items/LeashRopeArrowItem.java rename to src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java index 46db9e9..58b8089 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/LeashRopeArrowItem.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/LeashRopeArrowItem.java @@ -1,9 +1,14 @@ -package com.r3944realms.leashedplayer.content.items; +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; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.item.ArrowItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -14,14 +19,21 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.List; -public class LeashRopeArrowItem extends ArrowItem { +public class LeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ public static final String descKey = "item.leash_rope_arrow.description"; public LeashRopeArrowItem(Item.Properties pProperties) { super(pProperties); } public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) { - return new com.r3944realms.leashedplayer.content.entities.LeashRopeArrow(pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon); + return new com.r3944realms.leashedplayer.content.entities.LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(),pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon); + } + + @Override + public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) { + LeashRopeArrow arrow = new LeashRopeArrow(ModEntityRegister.LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, this.getDefaultInstance(),null, null); + arrow.pickup = AbstractArrow.Pickup.DISALLOWED; + return arrow; } @Override diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java new file mode 100644 index 0000000..e05ab4b --- /dev/null +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/SpectralLeashRopeArrowItem.java @@ -0,0 +1,47 @@ +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; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.item.ArrowItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.List; + +public class SpectralLeashRopeArrowItem extends ArrowItem implements ILeashRopeArrow{ + public static final String descKey = "item.spectral_leash_rope_arrow.description"; + public SpectralLeashRopeArrowItem(Properties pProperties) { + super(pProperties); + } + public @NotNull AbstractArrow createArrow(@NotNull Level pLevel, @NotNull ItemStack pAmmo, @NotNull LivingEntity pShooter, @Nullable ItemStack pWeapon) { + return new SpectralLeashRopeArrow(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), pShooter, pLevel, pAmmo.copyWithCount(1), pWeapon); + } + + @Override + public @NotNull Projectile asProjectile(@NotNull Level pLevel, @NotNull Position pPos, @NotNull ItemStack pStack, @NotNull Direction pDirection) { + LeashRopeArrow arrow = new SpectralLeashRopeArrow(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), pPos.x(), pPos.y(), pPos.z(), pLevel, this.getDefaultInstance(),null, null); + arrow.pickup = AbstractArrow.Pickup.DISALLOWED; + return arrow; + } + + @Override + public @NotNull Component getDescription() { + return Component.translatable(descKey).withStyle(ChatFormatting.GRAY); + } + public void appendHoverText(@NotNull ItemStack pStack, Item.@NotNull TooltipContext pContext, @NotNull List pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) { + //TODO:也许会做 + } +} diff --git a/src/main/java/com/r3944realms/leashedplayer/content/items/TestItem.java b/src/main/java/com/r3944realms/leashedplayer/content/items/type/TestItem.java similarity index 82% rename from src/main/java/com/r3944realms/leashedplayer/content/items/TestItem.java rename to src/main/java/com/r3944realms/leashedplayer/content/items/type/TestItem.java index f68a71d..b5f7f41 100644 --- a/src/main/java/com/r3944realms/leashedplayer/content/items/TestItem.java +++ b/src/main/java/com/r3944realms/leashedplayer/content/items/type/TestItem.java @@ -1,11 +1,11 @@ -package com.r3944realms.leashedplayer.content.items; +package com.r3944realms.leashedplayer.content.items.type; import com.r3944realms.leashedplayer.client.processBar.IProcessBar; import com.r3944realms.leashedplayer.client.processBar.TestProcessBar; -import com.r3944realms.leashedplayer.client.renders.AdaptiveGuiRendererHandler; -import com.r3944realms.leashedplayer.client.renders.IFadingProcessBarRenderer; -import com.r3944realms.leashedplayer.client.renders.IProcessBarRenderer; -import com.r3944realms.leashedplayer.client.renders.TestProcessBarRenderer; +import com.r3944realms.leashedplayer.client.renders.gui.AdaptiveGuiRendererHandler; +import com.r3944realms.leashedplayer.client.renders.gui.IFadingProcessBarRenderer; +import com.r3944realms.leashedplayer.client.renders.gui.IProcessBarRenderer; +import com.r3944realms.leashedplayer.client.renders.gui.TestProcessBarRenderer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.player.Player; diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java index 51a7f16..ea04ba4 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModAdvancementKey.java @@ -11,6 +11,7 @@ public enum ModAdvancementKey { LEASHED_FRIEND("leashed_friend", LEASH_START), LEASHED_SELF("leashed_self", LEASH_START), LEASH_ARROW("leash_arrow", LEASH_START), + ADVANCEMENT_LEASH_ARROW("advancement_leash_arrow", LEASH_ARROW), FOLLOW_LEASH_ARROW("follow_arrow", LEASH_ARROW), DOG_RUNNING_PLAYER("dog_running_player", LEASH_ARROW), ; diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java index 8fba89c..5528186 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/LanguageAndOtherData/ModLangKeyValue.java @@ -5,7 +5,7 @@ import com.r3944realms.leashedplayer.content.entities.ModEntityRegister; import com.r3944realms.leashedplayer.content.gamerules.Server.CreateLeashFenceKnotEntityIfAbsent; import com.r3944realms.leashedplayer.content.gamerules.Server.KeepLeashNotDropTime; import com.r3944realms.leashedplayer.content.gamerules.Server.TeleportWithLeashedPlayers; -import com.r3944realms.leashedplayer.content.items.LeashRopeArrowItem; +import com.r3944realms.leashedplayer.content.items.type.LeashRopeArrowItem; import com.r3944realms.leashedplayer.content.items.ModCreativeTab; import com.r3944realms.leashedplayer.content.items.ModItemRegister; import com.r3944realms.leashedplayer.utils.Enum.LanguageEnum; @@ -22,11 +22,13 @@ import static com.r3944realms.leashedplayer.content.items.ModCreativeTab.LEASHED public enum ModLangKeyValue { //ITEM ITEM_LEASH_ROPE_ARROW(ModItemRegister.LEASH_ROPE_ARROW, ModPartEnum.ITEM, "Leash Rope Arrow", "拴绳箭", "拴繩箭", true), + ITEM_SPECTRAL_LEASH_ROPE_ARROW(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW, ModPartEnum.ITEM, "Spectral Leash Rope Arrow", "拴绳光灵箭", "拴繩光靈箭", true), TEST_FABRIC_ITEM(ModItemRegister.FABRIC, ModPartEnum.ITEM, "Fabric", "Fabric", "Fabric", true), //ITEM_DESC DESC_ITEM_LEASH_ROPE_ARROW(LeashRopeArrowItem.descKey, ModPartEnum.DESCRIPTION, "Arrows with ropes attached?","带有拴绳的箭矢?", "帶有拴繩的箭矢?", false), //ENTITY LEASH_ROPE_ARROW(ModEntityRegister.getEntityNameKey("leash_rope_arrow"), ModPartEnum.ENTITY, "Leash Rope Arrow", "拴绳箭", "拴繩箭", false), + SPECTRAL_LEASH_ROPE_ARROW(ModEntityRegister.getEntityNameKey("spectral_leash_rope_arrow"), ModPartEnum.ENTITY, "Spectral Leash Rope Arrow", "拴绳光灵箭", "拴繩光靈箭", false), //CREATIVE_TAB CREATIVE_TAB_NAME(ModCreativeTab.getCreativeMod(LEASHED_PLAYER_ITEM), ModPartEnum.CREATIVE_TAB, "Leashed Player","可拴玩家", "可拴玩家", false), //COMMAND_MESSAGE @@ -53,15 +55,17 @@ public enum ModLangKeyValue { //ADV_NAME LEASH_START(ModAdvancementKey.LEASH_START.getNameKey(), ModPartEnum.NAME, "The Power of Traction", "牵引之力", "牽引之力", false), LEASH_LR_ARROW(ModAdvancementKey.LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "Arrow with a Tether?" , "拴绳之箭?", "拴繩之箭?", false), + LEASH_SLP_ARROW(ModAdvancementKey.ADVANCEMENT_LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "More advanced flash arrow with a Tether?", "更闪亮的拴绳箭?", "更閃亮的拴繩箭?", false), LEASH_SELF(ModAdvancementKey.LEASHED_SELF.getNameKey(), ModPartEnum.NAME, "Stable Connection", "稳固联结" ,"穩固聯結", false), - LEASH_PLAYER(ModAdvancementKey.LEASHED_FRIEND.getNameKey(),ModPartEnum.NAME, "Bond by Rope", "拴绳链接", "拴繩鏈接" , false), + LEASH_PLAYER(ModAdvancementKey.LEASHED_FRIEND.getNameKey(),ModPartEnum.NAME, "Be bound by Rope", "拴绳链接", "拴繩鏈接" , false), FOLLOW_ARROW(ModAdvancementKey.FOLLOW_LEASH_ARROW.getNameKey(), ModPartEnum.NAME, "Launch!!!", "启航!!!" , "啓航!!!",false), FOLLOW_WOLF(ModAdvancementKey.DOG_RUNNING_PLAYER.getNameKey(), ModPartEnum.NAME, "It's Walking human time.", "遛“人”时间", "遛“人”時間",false), //ADV_DESC LEASH_START_DESC(ModAdvancementKey.LEASH_START.getDescKey(), ModPartEnum.DESCRIPTION, "Journey to becoming a Leash Expert", "拴绳大师之路", "拴繩大師之路", false), LEASH_LR_ARROW_DESC(ModAdvancementKey.LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "Maybe you can using it to shoot some mob?", "也许可以用它来发射生物?", "也許可以用它發射生物?", false), + LEASH_SLP_ARROW_DESC(ModAdvancementKey.ADVANCEMENT_LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "Well, apart from glowing, there doesn't seem to be any other difference", "嗯,除了发光,似乎没有什么其它不同了" ,"嗯,除了發光,其它好像沒什麽不同", false), LEASH_SELF_DESC(ModAdvancementKey.LEASHED_SELF.getDescKey(), ModPartEnum.DESCRIPTION, "“Restrain oneself with a rope", "用拴绳拴住自己" ,"用栓繩拴住自己", false), - LEASH_PLAYER_DESC(ModAdvancementKey.LEASHED_FRIEND.getDescKey(),ModPartEnum.DESCRIPTION, "bond player with lead", "用拴绳链接玩家", "用拴繩鏈接玩家", false), + LEASH_PLAYER_DESC(ModAdvancementKey.LEASHED_FRIEND.getDescKey(),ModPartEnum.DESCRIPTION, "Be Bond by player with lead", "被玩家用拴绳链接", "被玩家用拴繩鏈接", false), FOLLOW_ARROW_DESC(ModAdvancementKey.FOLLOW_LEASH_ARROW.getDescKey(), ModPartEnum.DESCRIPTION, "Mc, what are you talking about in physics?", "抱歉,我的世界不存在物理学" , "抱歉,麦块不講物理學",false), FOLLOW_WOLF_DESC(ModAdvancementKey.DOG_RUNNING_PLAYER.getDescKey(), ModPartEnum.DESCRIPTION, "In the park where dogs are not allowed to be walked, the dog decided to walk the human instead", "公园不能遛狗,于是狗站起来遛人", "公園裏不許遛狗,於是狗站起來遛人",false), ; diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java b/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java index 6129df6..b9579ab 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/generator/ModAdvancementGenerator.java @@ -52,6 +52,19 @@ public class ModAdvancementGenerator implements AdvancementProvider.AdvancementG .parent(hasLeashRopeItem) .save(saver, ModAdvancementKey.LEASH_ARROW.getNameWithNameSpace()); + AdvancementHolder hasFlashLeashRopeArrow = Advancement.Builder.advancement().display( + ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), + Component.translatable(ModAdvancementKey.ADVANCEMENT_LEASH_ARROW.getNameKey()), + Component.translatable(ModAdvancementKey.ADVANCEMENT_LEASH_ARROW.getDescKey()), + null, + AdvancementType.TASK, + true, + false, + true + ).addCriterion("has_flash_leash_rope_item", InventoryChangeTrigger.TriggerInstance.hasItems(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) + .parent(hasLeashRopeArrow) + .save(saver, ModAdvancementKey.ADVANCEMENT_LEASH_ARROW.getNameWithNameSpace()); + AdvancementHolder leashedMySelf = Advancement.Builder.advancement().display( Items.PLAYER_HEAD, Component.translatable(ModAdvancementKey.LEASHED_SELF.getNameKey()), diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java index faecd65..c7230f3 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModItemTagProvider.java @@ -21,6 +21,7 @@ public class ModItemTagProvider extends ItemTagsProvider { @Override protected void addTags(HolderLookup.@NotNull Provider pProvider) { this.tag(ItemTags.ARROWS) - .add(ModItemRegister.LEASH_ROPE_ARROW.get()); + .add(ModItemRegister.LEASH_ROPE_ARROW.get()) + .add(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get()); } } diff --git a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java index dc5998f..0e0a75a 100644 --- a/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java +++ b/src/main/java/com/r3944realms/leashedplayer/datagen/provider/ModRecipeProvider.java @@ -3,10 +3,7 @@ package com.r3944realms.leashedplayer.datagen.provider; import com.r3944realms.leashedplayer.content.items.ModItemRegister; import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; -import net.minecraft.data.recipes.RecipeCategory; -import net.minecraft.data.recipes.RecipeOutput; -import net.minecraft.data.recipes.RecipeProvider; -import net.minecraft.data.recipes.ShapelessRecipeBuilder; +import net.minecraft.data.recipes.*; import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; @@ -25,7 +22,21 @@ public class ModRecipeProvider extends RecipeProvider { .requires(Items.ARROW) .unlockedBy("has_lead",has(Items.LEAD)) .save(pRecipeOutput); - + ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1) + .requires(Items.LEAD) + .requires(Items.SPECTRAL_ARROW) + .unlockedBy("has_lead",has(Items.LEAD)) + .unlockedBy("has_spectral_arrow",has(Items.SPECTRAL_ARROW)) + .save(pRecipeOutput, "spectral_leash_rope_arrow_with_leash_rope_arrow"); + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get(),1) + .pattern(" $ ") + .pattern("$#$") + .pattern(" $ ") + .define('#', ModItemRegister.LEASH_ROPE_ARROW.get()) + .define('$', Items.GLOWSTONE_DUST) + .unlockedBy("has_lead",has(Items.LEAD)) + .unlockedBy("has_glowstone_dust",has(Items.GLOWSTONE_DUST)) + .save(pRecipeOutput,"spectral_leash_rope_arrow_with_glowstone_dust"); } diff --git a/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java b/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java index 12b3049..f48d2a4 100644 --- a/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java +++ b/src/main/java/com/r3944realms/leashedplayer/mixin/both/MixinPlayer.java @@ -5,6 +5,7 @@ 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; @@ -14,6 +15,7 @@ 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; @@ -25,6 +27,7 @@ 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) @@ -82,6 +85,17 @@ public abstract class MixinPlayer extends LivingEntity implements PlayerLeashabl 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 diff --git a/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java b/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java index 3542e7d..efdcad4 100644 --- a/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java +++ b/src/main/java/com/r3944realms/leashedplayer/modInterface/PlayerLeashable.java @@ -41,7 +41,7 @@ public interface PlayerLeashable extends Leashable { */ default void setLeashedTo(@NotNull Entity pLeashHolder, boolean pBroadcastPacket) { setLeashedTo((Entity & Leashable)this, pLeashHolder, pBroadcastPacket); - if(this instanceof ServerPlayer){ + if(this instanceof ServerPlayer) { ModCriteriaTriggers.LEASH_PLAYER_TRIGGER.get().trigger((ServerPlayer) this, pLeashHolder); } } diff --git a/src/main/resources/assets/leashedplayer/textures/entity/projectiles/spectral_leash_rope_arrow.png b/src/main/resources/assets/leashedplayer/textures/entity/projectiles/spectral_leash_rope_arrow.png new file mode 100644 index 0000000..beb3f40 Binary files /dev/null and b/src/main/resources/assets/leashedplayer/textures/entity/projectiles/spectral_leash_rope_arrow.png differ diff --git a/src/main/resources/assets/leashedplayer/textures/item/spectral_leash_rope_arrow.png b/src/main/resources/assets/leashedplayer/textures/item/spectral_leash_rope_arrow.png new file mode 100644 index 0000000..5b47f66 Binary files /dev/null and b/src/main/resources/assets/leashedplayer/textures/item/spectral_leash_rope_arrow.png differ