2024-10-05
修复了 发射器不能发射箭的BUG 修复了 拴绳箭种类单一的BUG
This commit is contained in:
parent
cf74d05b10
commit
1f6e23e2a1
39
Deprecated/BasicEntityModel.java
Normal file
39
Deprecated/BasicEntityModel.java
Normal file
|
|
@ -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<T extends Entity> extends EntityModel<T> {
|
||||
public int textureWidth = 64;
|
||||
public int textureHeight = 32;
|
||||
|
||||
protected BasicEntityModel() {
|
||||
this(RenderType::entityCutoutNoCull);
|
||||
}
|
||||
|
||||
protected BasicEntityModel(Function<ResourceLocation, RenderType> 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<BasicModelPart> 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_) {
|
||||
}
|
||||
}
|
||||
314
Deprecated/BasicModelPart.java
Normal file
314
Deprecated/BasicModelPart.java
Normal file
|
|
@ -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<BasicModelPart.ModelBox> cubeList = new ObjectArrayList<>();
|
||||
private final ObjectList<BasicModelPart> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
166
Deprecated/ChainTieEntity.java
Normal file
166
Deprecated/ChainTieEntity.java
Normal file
|
|
@ -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<? extends BlockAttachedEntity> type, Level worldIn, BlockPos hangingPositionIn) {
|
||||
super(type, worldIn, hangingPositionIn);
|
||||
this.setPos(hangingPositionIn.getX() + 0.5D, hangingPositionIn.getY(), hangingPositionIn.getZ() + 0.5D);
|
||||
}
|
||||
|
||||
public ChainTieEntity(EntityType<? extends BlockAttachedEntity> 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<ChainLeashable> 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<ClientGamePacketListener> 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);
|
||||
}
|
||||
}
|
||||
4
Deprecated/ChainTieModel.java
Normal file
4
Deprecated/ChainTieModel.java
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
package com.r3944realms.leashedplayer.client.models;
|
||||
|
||||
public class ChainTieModel extends BasicEnti{
|
||||
}
|
||||
210
Deprecated/props/ChainLeashable.java
Normal file
210
Deprecated/props/ChainLeashable.java
Normal file
|
|
@ -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 <E extends Entity & ChainLeashable> 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 <E extends Entity & ChainLeashable> 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<ChainLeashable> leashableInArea(Level pLevel, BlockPos pPos, Predicate<ChainLeashable> 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 <E extends Entity & ChainLeashable> 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 <E extends Entity & ChainLeashable> 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 <E extends Entity & ChainLeashable> 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 <E extends Entity & ChainLeashable> void restoreLeashFromSave(E pEntity, ChainLeashable.ChainData pLeashData) {
|
||||
if (pLeashData.delayedLeashInfo != null && pEntity.level() instanceof ServerLevel serverlevel) {
|
||||
Optional<UUID> optional1 = pLeashData.delayedLeashInfo.left();
|
||||
Optional<BlockPos> 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<UUID, BlockPos> delayedLeashInfo;
|
||||
|
||||
ChainData(@org.jetbrains.annotations.Nullable Either<UUID, BlockPos> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Resource/spectral_RL_arrow.png
Normal file
BIN
Resource/spectral_RL_arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 256 B |
BIN
Resource/spectral_leashed_rope_arrow.png
Normal file
BIN
Resource/spectral_leashed_rope_arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 245 B |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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沒有拴绳数据实体",
|
||||
|
|
|
|||
|
|
@ -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沒有拴繩數據實體",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/spectral_leash_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"values": [
|
||||
"leashedplayer:leash_rope_arrow"
|
||||
"leashedplayer:leash_rope_arrow",
|
||||
"leashedplayer:spectral_leash_rope_arrow"
|
||||
]
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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<SpectralLeashRopeArrow> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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<? extends AbstractArrow> 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<? extends AbstractArrow> 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<? extends AbstractArrow> entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) {
|
||||
super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon);
|
||||
if(serverPlayer != null && !level().isClientSide) {
|
||||
((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<? extends AbstractArrow> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,21 @@ public class ModEntityRegister {
|
|||
.updateInterval(20)
|
||||
.build("leash_rope_arrow")
|
||||
);
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<SpectralLeashRopeArrow>> SPECTRAL_LEASH_ROPE_ARROW = ENTITY_TYPE.register(
|
||||
"spectral_leash_rope_arrow",
|
||||
() -> EntityType.Builder.<SpectralLeashRopeArrow>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<?>, EntityType<ChainTieEntity>> CHAIN_TIE = ENTITY_TYPE.register(
|
||||
// "chain_tie",
|
||||
// () -> EntityType.Builder.<ChainTieEntity>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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<? extends AbstractArrow> entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) {
|
||||
super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon, serverPlayer);
|
||||
}
|
||||
|
||||
protected SpectralLeashRopeArrow(EntityType<? extends AbstractArrow> entityType, Level pLevel) {
|
||||
super(entityType, pLevel);
|
||||
}
|
||||
|
||||
public SpectralLeashRopeArrow(EntityType<? extends AbstractArrow> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<Item> LEASH_ROPE_ARROW = ModItemRegister.register("leash_rope_arrow",
|
||||
() -> new LeashRopeArrowItem(new Item.Properties().stacksTo(16))
|
||||
);
|
||||
public static final Supplier<Item> SPECTRAL_LEASH_ROPE_ARROW = ModItemRegister.register("spectral_leash_rope_arrow",
|
||||
() -> new SpectralLeashRopeArrowItem(new Item.Properties().stacksTo(16)));
|
||||
|
||||
public static final Supplier<Item> FABRIC = ModItemRegister.register("fabric",
|
||||
() -> new TestItem(new Item.Properties().stacksTo(1))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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<Component> pTooltipComponents, @NotNull TooltipFlag pTooltipFlag) {
|
||||
//TODO:也许会做
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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),
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 257 B |
Binary file not shown.
|
After Width: | Height: | Size: 245 B |
Loading…
Reference in New Issue
Block a user