Compare commits
No commits in common. "1.21" and "9de55bd40d2686536d9eb0dc5715fa421b5c35e4" have entirely different histories.
1.21
...
9de55bd40d
11
.github/workflows/build.yml
vendored
|
|
@ -12,13 +12,14 @@ jobs:
|
|||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Setup JDK 17
|
||||
- name: Setup JDK 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '17'
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
- name: Build with Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
arguments: build
|
||||
run: ./gradlew build
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
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_) {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,314 +0,0 @@
|
|||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.client.models;
|
||||
|
||||
public class ChainTieModel extends BasicEnti{
|
||||
}
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
README.md
|
|
@ -1,70 +1,25 @@
|
|||
# 版本 0.0.4.0.4 提前介绍c[没有BUG的话,TeaCon最终版本将会是0.0.4] 【注意:本解釋簡繁混寫,因爲趕時間,所以並不怎麽規範,請諒解】
|
||||
## 简介
|
||||
现在开始你可以用拴绳拴住玩家,也可以拴住自己了,不如尝试拴住彼此来通关我的世界吧(
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Installation information
|
||||
=======
|
||||
|
||||
This template repository can be directly cloned to get you started with a new
|
||||
mod. Simply create a new repository cloned from this one, by following the
|
||||
instructions provided by [GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template).
|
||||
|
||||
你可以:
|
||||
1. 拴绳可以拴住玩家
|
||||
2. 在无任何拴住实体的情况下用拴绳对准栅栏可以拴住自己
|
||||
3. 可以用指令来获取和调整玩家实体的拴绳的长度和设置拴绳数据实体
|
||||
4. 目前有游戏规则来决定被栓玩家是否在传送时能随拴绳持有者一起传送
|
||||
## 配置文件
|
||||
1. 可改变指令前命名空间和关闭命名空间
|
||||
2. 修改命令拴绳的可设置的长度范围
|
||||
3. 设置拴绳在达到多少倍的拴绳长度后掉落
|
||||
4. 拴绳箭最大存活时间
|
||||
Once you have your clone, simply open the repository in the IDE of your choice. The usual recommendation for an IDE is either IntelliJ IDEA or Eclipse.
|
||||
|
||||
## 新物品 和 实体
|
||||
### 拴绳箭 [有普通和荧光和药水三种箭矢]
|
||||
获得飞一样的感觉(操作不当可能会摔死
|
||||
+ 拴绳箭可以拴其它可拴LivingEntity了(
|
||||
### 紫水晶剪刀
|
||||
剪断拴绳链接,在发射器里可使用,对自己也可使用,但耗费更多耐久
|
||||
#### 射中实体时,会将射击者拴绳绑定在改实体上(该实体父类必须是有LivingEntity类型),同时拴绳箭会以普通的箭矢掉落
|
||||
#### 射中栅栏时,会自动将玩家拴在上面 ,同时拴绳箭会以普通的箭矢掉落
|
||||
#### 在地面上的箭可以通过按Shift靠近来捡起,如果捡起实体为发射箭矢玩家,则直接获取拴绳箭矢,如果捡起者为非发射者则成为发送者的拴绳持有者,并获得普通箭矢
|
||||
If at any point you are missing libraries in your IDE, or you've run into problems you can
|
||||
run `gradlew --refresh-dependencies` to refresh the local cache. `gradlew clean` to reset everything
|
||||
{this does not affect your code} and then start the process again.
|
||||
|
||||
## 新药水和效果
|
||||
### 效果
|
||||
* 禁拴 - 拥有此BUFF的LivingEntity将无法被拴住
|
||||
### 药水
|
||||
* 禁拴药水
|
||||
Mapping Names:
|
||||
============
|
||||
By default, the MDK is configured to use the official mapping names from Mojang for methods and fields
|
||||
in the Minecraft codebase. These names are covered by a specific license. All modders should be aware of this
|
||||
license. For the latest license text, refer to the mapping file itself, or the reference copy here:
|
||||
https://github.com/NeoForged/NeoForm/blob/main/Mojang.md
|
||||
|
||||
## 指令
|
||||
可能会因为配置中差异性导致前缀'lp'变为其它或取消其存在,以模组配置文件为准
|
||||
* `/lp leash length [<玩家>] set <长度> ` - 设置该玩家的拴绳长度 [ 如果<玩家>为空则代表执行对象是自己 ,<长度> 为在 5 ~ 1024之间的浮点数 ]
|
||||
|
||||
* `/lp leash length [<玩家>] [get]` - 顯示该玩家的拴绳长度 [ 如果<玩家>为空则代表执行对象是自己 , [get] 可不写]
|
||||
|
||||
* `/lp leash data [<玩家>] set <實體>/<方塊坐標>` - 設置該玩家的的拴繩數據實體設置為<實體>/位於<方塊坐標>處的柵欄上的拴繩結實體
|
||||
|
||||
* `/lp leash data [<玩家>] [get]` - 顯示该玩家的拴绳數據 [ 如果<玩家>为空则代表执行对象是自己 , [get] 可不写]
|
||||
|
||||
* `/lp leash clear [<玩家[可多个对象]>] ` - 清除該玩家的的拴繩數據實體 [ 如果<玩家>为空则代表执行对象是自己 ]
|
||||
|
||||
* `/lp motion [<实体[可多个对象]>] add/set/multiply <x> <y> <z>` - 给实体添加/设置/倍乘 加速度
|
||||
|
||||
* `/lp talkArea <[<玩家[可多个对象]>]> set/setPreference/unlimited/currentConfig <数值>` - 设置玩家聊天可见半径/设置半径预期/应用预期/取消限制/获取目前配置
|
||||
|
||||
* `/lp tick ...` - 用法同原版Tick,但权限降为2,只用于调试,切勿滥用,后期考虑可能写成区域性的
|
||||
|
||||
* `/lp debug ...` - Debug指令,未来可能会移除
|
||||
|
||||
|
||||
## 游戏规则
|
||||
|
||||
* `LP.TeleportWithLeashedPlayers` - 此規則啓用后, 被栓玩家將會随玩家拴绳持有者一起传送 [默认值: True]
|
||||
|
||||
* `LP.CreateLeashFenceKnotEntityIfAbsent` - 此規則啓用后, 在設置 leashData 時,如果對應方塊坐標上的柵欄沒有拴繩結則會自動創建這個實體並綁定 [默认值: True]
|
||||
|
||||
* `LP.KeepLeashNotDropTime` - 此规则决定,当拴绳关系创建时一段时间里,即是距离已经达到了断裂距离,也保持其不断裂 [默认值: 240ticks ,可设置范围[80, 1200]ticks]
|
||||
|
||||
* `LP.DefaultTalkArea` - 此规则决定,聊天半径最小正值 [默认值: -1]
|
||||
|
||||
* `LP.OpenTOPNeededModeWhenScreenIsNotNull` - 此规则决定,是否在在打开 屏幕{除Top的NoteGui 和 聊天GUI外} 情况下改变Top的显示模式为NEEDED [默认值: true]
|
||||
|
||||
* `LP.CanCommonPlayerChangeSelfTalkArea` - 此规则决定,是否普通玩家可以修改自己的聊天可见区域 [默认值: true]
|
||||
|
||||
## 联动内容
|
||||
# 与Nestle 的 贴贴拴绳箭
|
||||
射中实体生成贴贴拴绳实体并绑定在一起,解除需用到贴贴拴绳(不太好个人觉得)
|
||||
Additional Resources:
|
||||
==========
|
||||
Community Documentation: https://docs.neoforged.net/
|
||||
NeoForged Discord: https://discord.neoforged.net/
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 364 B |
|
Before Width: | Height: | Size: 382 B |
|
Before Width: | Height: | Size: 404 B |
|
Before Width: | Height: | Size: 498 B |
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"1": "leashedplayer:item/neoforge",
|
||||
"particle": "leashedplayer:item/neoforge"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 273 B |
|
Before Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 245 B |
|
|
@ -1,6 +1,9 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 LeashedPlayer Project
|
||||
Copyright (c) 2023 NeoForged project
|
||||
|
||||
This license applies to the template files as supplied by github.com/NeoForged/MDK
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
55
build.gradle
|
|
@ -1,9 +1,7 @@
|
|||
plugins {
|
||||
id 'java-library'
|
||||
id 'eclipse'
|
||||
id 'idea'
|
||||
id 'maven-publish'
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.145'
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.184'
|
||||
}
|
||||
|
||||
tasks.named('wrapper', Wrapper).configure {
|
||||
|
|
@ -19,19 +17,6 @@ version = mod_version
|
|||
group = mod_group_id
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
// location of the maven that hosts JEI files since January 2023
|
||||
name = "Jared's maven"
|
||||
url = "https://maven.blamejared.com/"
|
||||
}
|
||||
maven {
|
||||
// location of a maven mirror for JEI files, as a fallback
|
||||
name = "ModMaven"
|
||||
url = "https://modmaven.dev"
|
||||
}
|
||||
maven { // TOP
|
||||
url "https://maven.k-4u.nl"
|
||||
}
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
|
|
@ -67,26 +52,27 @@ runs {
|
|||
|
||||
client {
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
}
|
||||
|
||||
server {
|
||||
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
argument '--nogui'
|
||||
}
|
||||
|
||||
// This run config launches GameTestServer and runs all registered gametests, then exits.
|
||||
// By default, the server will crash when no gametests are provided.
|
||||
// The gametest system is also enabled by default for other run configs under the /test command.
|
||||
gameTestServer {
|
||||
systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
}
|
||||
|
||||
data {
|
||||
clientData {
|
||||
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
|
||||
// workingDirectory project.file('run-data')
|
||||
systemProperty('gradle.task', 'runData')
|
||||
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
||||
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
|
||||
arguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +86,9 @@ sourceSets.main.resources { srcDir 'src/generated/resources' }
|
|||
configurations {
|
||||
runtimeClasspath.extendsFrom localRuntime
|
||||
}
|
||||
|
||||
minecraft {
|
||||
accessTransformers.file("src/main/resources/META-INF/accesstransformer.cfg")
|
||||
}
|
||||
dependencies {
|
||||
// Specify the version of Minecraft to use.
|
||||
// Depending on the plugin applied there are several options. We will assume you applied the userdev plugin as shown above.
|
||||
|
|
@ -109,14 +97,7 @@ dependencies {
|
|||
// And its provides the option to then use net.minecraft as the group, and one of; client, server or joined as the module name, plus the game version as version.
|
||||
// For all intends and purposes: You can treat this dependency as if it is a normal library you would use.
|
||||
implementation "net.neoforged:neoforge:${neo_version}"
|
||||
compileOnly "mcjty.theoneprobe:theoneprobe:${top_version}"
|
||||
runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
|
||||
// compile against the JEI API but do not include it at runtime
|
||||
compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
|
||||
compileOnly(files("Resource/nestle-0.1.1.jar"))
|
||||
runtimeOnly(files("Resource/nestle-0.1.1.jar"))
|
||||
// at runtime, use the full JEI jar for NeoForge
|
||||
// compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
|
||||
|
||||
// Example optional mod dependency with JEI
|
||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
||||
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
|
||||
|
|
@ -176,25 +157,13 @@ publishing {
|
|||
maven {
|
||||
url "file://${project.projectDir}/repo"
|
||||
}
|
||||
// maven {
|
||||
// // location of the maven that hosts JEI files since January 2023
|
||||
// name = "Jared's maven"
|
||||
// url = "https://maven.blamejared.com/"
|
||||
// }
|
||||
// maven {
|
||||
// // location of a maven mirror for JEI files, as a fallback
|
||||
// name = "ModMaven"
|
||||
// url = "https://modmaven.dev"
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
|
||||
}
|
||||
minecraft {
|
||||
accessTransformers.file("src/main/resources/META-INF/accesstransformer.cfg")
|
||||
}
|
||||
|
||||
// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
|
||||
idea {
|
||||
module {
|
||||
|
|
|
|||
|
|
@ -1,30 +1,29 @@
|
|||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
org.gradle.jvmargs=-Xmx8G
|
||||
org.gradle.daemon=false
|
||||
org.gradle.debug=false
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=false
|
||||
org.gradle.configuration-cache=false
|
||||
|
||||
#read more on this at https://github.com/neoforged/NeoGradle/blob/NG_7.0/README.md#apply-parchment-mappings
|
||||
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
|
||||
neogradle.subsystems.parchment.minecraftVersion=1.21
|
||||
neogradle.subsystems.parchment.mappingsVersion=2024.07.28
|
||||
neogradle.subsystems.parchment.minecraftVersion=1.21.4
|
||||
neogradle.subsystems.parchment.mappingsVersion=2025.03.23
|
||||
# Environment Properties
|
||||
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
|
||||
# The Minecraft version must agree with the Neo version to get a valid artifact
|
||||
minecraft_version=1.21
|
||||
minecraft_version=1.21.5
|
||||
# The Minecraft version range can use any release version of Minecraft as bounds.
|
||||
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
|
||||
# as they do not follow standard versioning conventions.
|
||||
minecraft_version_range=[1.21,1.22)
|
||||
minecraft_version_range=[1.21.5]
|
||||
# The Neo version must agree with the Minecraft version to get a valid artifact
|
||||
neo_version=21.0.157
|
||||
neo_version=21.5.30-beta
|
||||
# The Neo version range can use any version of Neo as bounds
|
||||
neo_version_range=[21.0.0-beta,)
|
||||
neo_version_range=[21.5.30-beta,)
|
||||
# The loader version range can only use the major version of FML as bounds
|
||||
loader_version_range=[4,)
|
||||
top_version = 1.21_neo-12.0.4-6
|
||||
#jei_setting
|
||||
jei_version=19.8.2.99
|
||||
mc_version=1.21
|
||||
loader_version_range=[1,)
|
||||
|
||||
## Mod Properties
|
||||
|
||||
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
|
||||
|
|
@ -35,7 +34,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.4.0.4
|
||||
mod_version=1.21.5_0.0.4.0.4.1
|
||||
# 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
|
||||
|
|
|
|||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.12-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
188
gradlew.bat
vendored
|
|
@ -1,94 +1,94 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
|
|
|||
|
|
@ -7,7 +7,5 @@ pluginManagement {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0'
|
||||
}
|
||||
include 'leashedplayer_1_21_3'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
// 1.21 2024-11-25T23:55:52.7726677 Item Models: leashedplayer
|
||||
766c487fbf0c59e9045eeaf81daf583eb679b0e1 assets/leashedplayer/models/item/amethyst_shears.json
|
||||
5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json
|
||||
845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json
|
||||
5bd1f9f28b91005c587f1c38fb77cd19b59495e3 assets/leashedplayer/models/item/bow_lra_pulling_2.json
|
||||
90909de0fcb2a6b0b9731bb998f8d866841de6d2 assets/leashedplayer/models/item/bow_nra_pulling_0.json
|
||||
de6fed69522a94812c66ba1864ae6df7465aad9c assets/leashedplayer/models/item/bow_nra_pulling_1.json
|
||||
1e34de6579d5c250eff9871e589c584d888c3c6d assets/leashedplayer/models/item/bow_nra_pulling_2.json
|
||||
83946f4d60d0fb1758d6553c36330506c8e48ada assets/leashedplayer/models/item/crossbow_leash_rope_arrow.json
|
||||
7d9d1678faf41b58d2934d0335f700e17c372c10 assets/leashedplayer/models/item/crossbow_nestle_rope_arrow.json
|
||||
bb0d76077719c83c8a8bd4346a24ea1766175125 assets/leashedplayer/models/item/fabric.json
|
||||
63ec6c618a3a23eab4cab9c52d7d3250de9b516e assets/leashedplayer/models/item/kid_spawn_egg.json
|
||||
114d3cc5832ef047403114504483c6f3ea07e77c assets/leashedplayer/models/item/leash_rope_arrow.json
|
||||
f77241714f5233f127eee3c7521b448add1eaad2 assets/leashedplayer/models/item/nestle_rope_arrow.json
|
||||
c4748995a5fe190d20e3bd16f4b2244164ec0f83 assets/leashedplayer/models/item/spectral_leash_rope_arrow.json
|
||||
c4ef06f3162fe85f152c5b4a25ecdb4c2c56f945 assets/leashedplayer/models/item/tipped_leash_rope_arrow.json
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
// 1.21 2024-11-05T23:00:18.5223698 Registries
|
||||
// 1.21.5 2025-03-29T16:40:03.0405054 Registries
|
||||
f2536789df7f06362718a59ba4a96890e2f9b8aa data/leashedplayer/jukebox_song/what_does_the_fox_say.json
|
||||
6f79a674215db9f9d2820b1c7f052c60ce729fee data/leashedplayer/painting_variant/group_photo.json
|
||||
84106976f4f71012fc5bd1784303a0d135623c77 data/leashedplayer/painting_variant/group_photo.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 1.21 2024-11-25T23:24:58.9769291 Tags for minecraft:item mod id leashedplayer
|
||||
// 1.21.5 2025-03-29T16:40:02.9875592 Tags for minecraft:item mod id leashedplayer
|
||||
84707301f1fe2490a899deb51302d413cfff5a89 data/c/tags/item/tools/shear.json
|
||||
a91f0f4956d65c981d76c9f41de5272b2e0b5786 data/minecraft/tags/item/arrows.json
|
||||
bde6ca31173d1f22d5f6fe355dc90c9faa35b239 data/minecraft/tags/item/amethyst_tool_materials.json
|
||||
63e4ad58dc8397171f84264d53dfe4fb503c7b1e data/minecraft/tags/item/arrows.json
|
||||
84707301f1fe2490a899deb51302d413cfff5a89 data/minecraft/tags/item/enchantable/durability.json
|
||||
84707301f1fe2490a899deb51302d413cfff5a89 data/minecraft/tags/item/enchantable/mining.json
|
||||
84707301f1fe2490a899deb51302d413cfff5a89 data/minecraft/tags/item/enchantable/vanishing.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-12-15T17:40:40.0369665 Languages: en_us for mod: leashedplayer
|
||||
d88b57505584fdfde48b00652789cb078b469830 assets/leashedplayer/lang/en_us.json
|
||||
// 1.21.5 2025-03-29T16:40:03.0435015 Languages: en_us for mod: leashedplayer
|
||||
2c7f061dfc276db13135adce15c68cfc145ccf37 assets/leashedplayer/lang/en_us.json
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
// 1.21 2024-10-23T13:15:06.1052755 Tags for minecraft:block mod id leashedplayer
|
||||
// 1.21.5 2025-03-29T16:40:03.0112992 Tags for minecraft:block mod id leashedplayer
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-11-05T22:44:13.1754334 Sound Definitions
|
||||
// 1.21.5 2025-03-29T16:40:03.0510463 Sound Definitions
|
||||
81f1cc9f404c2670bf7cc679107177ffb0b48c77 assets/leashedplayer/sounds.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-10-23T13:15:06.1052755 Tags for minecraft:painting_variant mod id leashedplayer
|
||||
// 1.21.5 2025-03-29T16:40:03.0163693 Tags for minecraft:painting_variant mod id leashedplayer
|
||||
e081a053d7c2f2d3238cf38436185ef23d234505 data/minecraft/tags/painting_variant/placeable.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-11-03T11:56:02.1150382 Languages: lzh for mod: leashedplayer
|
||||
a9b5a3116c6381872e174909553b8dac080dede8 assets/leashedplayer/lang/lzh.json
|
||||
// 1.21.5 2025-03-29T16:40:02.9987109 Languages: lzh for mod: leashedplayer
|
||||
7536eb6d1c69695c06ebb9da5b57a391174b02cb assets/leashedplayer/lang/lzh.json
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
// 1.21 2024-11-26T16:39:25.2156177 Recipes
|
||||
13ebe9a580731296eb10c05d1844657d58e07cc1 data/leashedplayer/advancement/recipes/misc/amethyst_shears.json
|
||||
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
|
||||
a89ec35176f84a580181c5839d6f249e482a65a9 data/leashedplayer/advancement/recipes/misc/nestle_rope_arrow.json
|
||||
04bd2d8a0c7288776da2119eb9a9f9cf694be1b6 data/leashedplayer/recipe/amethyst_shears.json
|
||||
974d74538b3e172946f2e169036b453b6eb6bc0a data/leashedplayer/recipe/leash_rope_arrow.json
|
||||
093bae9d2e24a901ce8450d802ad5d142d1d74ed data/leashedplayer/recipe/nestle_rope_arrow.json
|
||||
8de575d00dcc51fce8ebfa2542e193ffda1bafa8 data/minecraft/advancement/recipes/misc/nestle_rope_arrow_with_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
|
||||
fb35ec6670c3711b7e1d0e96f39ad914cb2419ae data/minecraft/recipe/nestle_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
|
||||
4dffdb7a2a537b409d1ec2630d9b74300649e1d8 data/minecraft/recipe/tipped_leash_rope_arrow_a.json
|
||||
7810cb5e8c165f479fc6cd030bd1cf7bc508993b data/minecraft/recipe/tipped_leash_rope_arrow_b.json
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-12-15T17:48:33.0549249 Languages: zh_cn for mod: leashedplayer
|
||||
72797aa9107025df7d91eaff3ea51745d410261c assets/leashedplayer/lang/zh_cn.json
|
||||
// 1.21.5 2025-03-29T16:40:03.0306291 Languages: zh_cn for mod: leashedplayer
|
||||
f7bcf89907a8ca5f575e4b519d53cd0628bb1e6b assets/leashedplayer/lang/zh_cn.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0040344 LeashedPlayer Recipes
|
||||
13ebe9a580731296eb10c05d1844657d58e07cc1 data/leashedplayer/advancement/recipes/misc/amethyst_shears.json
|
||||
1b45d1ad8dc73f1787c97777ad13d9771c9e0ad1 data/leashedplayer/advancement/recipes/misc/leash_rope_arrow.json
|
||||
a26d63c2360b32df0b636a5dec96dd919139e022 data/leashedplayer/advancement/recipes/misc/spectral_leash_rope_arrow.json
|
||||
af1f65626735f1001426e0984217139e15649725 data/leashedplayer/recipe/amethyst_shears.json
|
||||
db45be6e2bbddc49e60a6c1b12e2ef44afad30d8 data/leashedplayer/recipe/leash_rope_arrow.json
|
||||
db37bd69a700eaae69bff48c77ed49ca55fb9bf1 data/leashedplayer/recipe/spectral_leash_rope_arrow.json
|
||||
935d8732ca65dd73e4668a197cda60480053fbcd data/minecraft/advancement/recipes/misc/leash_rope_arrow_shape.json
|
||||
5811048f18527a45b36b8b927de4e5d7c12a75eb data/minecraft/recipe/leash_rope_arrow_shape.json
|
||||
4dffdb7a2a537b409d1ec2630d9b74300649e1d8 data/minecraft/recipe/tipped_leash_rope_arrow_a.json
|
||||
7810cb5e8c165f479fc6cd030bd1cf7bc508993b data/minecraft/recipe/tipped_leash_rope_arrow_b.json
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 1.21.5 2025-03-29T16:40:03.0481 Model Definitions - leashedplayer
|
||||
d213db38f45b911f2023c83e15b018371a630ae0 assets/leashedplayer/items/amethyst_shears.json
|
||||
bc53c9feb22db83882974d60456bef0d3ef3ef5e assets/leashedplayer/items/fabric.json
|
||||
e4e426067245e93d282a3d953c420fca04c23f3d assets/leashedplayer/items/leash_rope_arrow.json
|
||||
6151e1b11ec884d511b2fd595e39c9f12674e824 assets/leashedplayer/items/spectral_leash_rope_arrow.json
|
||||
1b914911c9077563701e9ac4b7f8c425f6eff4ee assets/leashedplayer/items/tipped_leash_rope_arrow.json
|
||||
766c487fbf0c59e9045eeaf81daf583eb679b0e1 assets/leashedplayer/models/item/amethyst_shears.json
|
||||
5846df9d85726428905701120ef34c9324c20faf assets/leashedplayer/models/item/bow_lra_pulling_0.json
|
||||
845a7316b86e26f88c6932d4ef2656126503727a assets/leashedplayer/models/item/bow_lra_pulling_1.json
|
||||
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
|
||||
ba065b1a88d82f95e10d026bf7bfdac7923de24c assets/leashedplayer/models/item/tipped_leash_rope_arrow.json
|
||||
fe3d4b8fd83f9ba4e2a951ec2e23ea98a347c2cc assets/minecraft/items/bow.json
|
||||
12be767d961ae273ae0968ad06f022b57afbb0b0 assets/minecraft/items/crossbow.json
|
||||
08270cb07bcffbeedc5c5eeb4904c4f852a8741b assets/minecraft/models/item/bow_pulling_0.json
|
||||
ceb850b6b4a0650ee3d1529e67ab8e7447b0319f assets/minecraft/models/item/bow_pulling_1.json
|
||||
65c4490152c9f65bc766d686b38fffdfeb7a0873 assets/minecraft/models/item/bow_pulling_2.json
|
||||
3f5af50f9ebf07f64949415b4d3a3b6ec549f93b assets/minecraft/models/item/crossbow_arrow.json
|
||||
b98e781a6782a959e897e7db93ef9e9bed6ee72f assets/minecraft/models/item/crossbow_firework.json
|
||||
967e2cb3fce436263b91050e448394e460d1596d assets/minecraft/models/item/crossbow_pulling_0.json
|
||||
1b3d6214059e250dda7aba60632cdc5a315a6146 assets/minecraft/models/item/crossbow_pulling_1.json
|
||||
98bcc5449dcc6b30ae1e0558906c2b3ce5d32da0 assets/minecraft/models/item/crossbow_pulling_2.json
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
// 1.21 2024-11-26T16:52:31.259654 Advancements
|
||||
// 1.21.5 2025-03-30T19:34:30.4253532 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
|
||||
25f6b476b194a27c0fe0e75d74ac3a7ff4054789 data/leashedplayer/advancement/leashed_self.json
|
||||
a69a455855fb6dd8a8ac131a55099de5de45d7c4 data/leashedplayer/advancement/leash_arrow.json
|
||||
133f844ffafd37b9ba57cafa96350f035cac57f9 data/leashedplayer/advancement/leash_start.json
|
||||
d109d59adbfa6efdefb4003623c9fb4950f2956b data/leashedplayer/advancement/leash_start.json
|
||||
2d8bce7fd078f9cc6b73b77f2fbab30e6cc197f4 data/leashedplayer/advancement/leash_terminator.json
|
||||
4e567c22e18462ad367fe1817140d1ffa13a6294 data/leashedplayer/advancement/neo_fox.json
|
||||
95486932f200c278f23444adca2e328a82e7f863 data/leashedplayer/advancement/nestle_arrow.json
|
||||
4b0bcf6b372f52e954edcef37a6b04435ec2b4e8 data/leashedplayer/advancement/no_leash.json
|
||||
72f40eb5816d1e8c296bdf4df6b599c15ba7e7e9 data/leashedplayer/advancement/tipped_leash_arrow.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.21 2024-12-15T17:48:33.0539432 Languages: zh_tw for mod: leashedplayer
|
||||
a01c64ca969974766c47baadd465b24b6fb5803b assets/leashedplayer/lang/zh_tw.json
|
||||
// 1.21.5 2025-03-29T16:40:03.0241113 Languages: zh_tw for mod: leashedplayer
|
||||
c23825af72a73bc54b72ad3817acb5a03d299375 assets/leashedplayer/lang/zh_tw.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/amethyst_shears"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/fabric"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/leash_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/spectral_leash_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/tipped_leash_rope_arrow",
|
||||
"tints": [
|
||||
{
|
||||
"type": "minecraft:potion",
|
||||
"default": -13083194
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,6 @@
|
|||
"advancement.leashedplayer.leashed_self.desc": "“Restrain oneself with a rope",
|
||||
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
|
||||
"advancement.leashedplayer.neo_fox.desc": "It seems can be equipped.",
|
||||
"advancement.leashedplayer.nestle_arrow": "Arrow with the Power of Nestle!",
|
||||
"advancement.leashedplayer.nestle_arrow.desc": "The Power of Nestle!!!",
|
||||
"advancement.leashedplayer.no_leash": "Don't tie me up",
|
||||
"advancement.leashedplayer.no_leash.desc": "You cannot be leashed by ANY",
|
||||
"advancement.leashedplayer.tipped_leash_arrow": "God said there should be more arrows",
|
||||
|
|
@ -29,16 +27,10 @@
|
|||
"entity.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
|
||||
"entity.leashedplayer.nestle_rope_arrow": "Nestle Rope Arrow",
|
||||
"entity.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow",
|
||||
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea": "Should Non-OP Player can change their TalkArea",
|
||||
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea.description": "Above on its Name",
|
||||
"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.DefaultTalkArea": "Default Area Talk",
|
||||
"gamerule.LP.DefaultTalkArea.description": "When the global setting is non-negative, it limits the chat range for all players. If a player's configured chat range is smaller than this value, this rule applies. Otherwise, the player's custom value is used.",
|
||||
"gamerule.LP.KeepLeashNotDropTime": "Keep leash alive Time",
|
||||
"gamerule.LP.KeepLeashNotDropTime.description": "The time of Keep new leash which has far distance alive (Tick)",
|
||||
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull": "Open TOP NEEDED Mode When Screen isn't null",
|
||||
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull.description": "The One Probe will automatic to be in the Needed Mode when Gui Screen is not NULL",
|
||||
"gamerule.LP.TeleportWithLeashedPlayers": "Teleport leashed player with player holder",
|
||||
"gamerule.LP.TeleportWithLeashedPlayers.description": "Holder will teleport with their leashed players ",
|
||||
"item.leash_rope_arrow.desc.1": "§7This arrow will carry the owner along with its flight:",
|
||||
|
|
@ -49,43 +41,23 @@
|
|||
"item.leash_rope_arrow.description": "Arrows with ropes attached?",
|
||||
"item.leashedplayer.amethyst_shears": "Amethyst Shears",
|
||||
"item.leashedplayer.fabric": "Fabric",
|
||||
"item.leashedplayer.kid_spawn_egg": "Kid Spawn Egg",
|
||||
"item.leashedplayer.leash_rope_arrow": "Leash Rope Arrow",
|
||||
"item.leashedplayer.neoforge": "NeoForge",
|
||||
"item.leashedplayer.nestle_rope_arrow": "Nestle Rope Arrow",
|
||||
"item.leashedplayer.spectral_leash_rope_arrow": "Spectral Leash Rope Arrow",
|
||||
"item.minecraft.lingering_potion.effect.no_leash": "Splash No Leash Potion",
|
||||
"item.minecraft.potion.effect.no_leash": "No Leash Potion",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "Splash No Leash Potion",
|
||||
"item.minecraft.tipped_arrow.effect.no_leash": "Arrow of No Leash",
|
||||
"item.nestle_rope_arrow.desc.1": "§7This arrow will carry the owner along with its flight:",
|
||||
"item.nestle_rope_arrow.desc.2": "§c1.§r If it hits an entity, it will leash the owner with the entity and drop as a normal arrow;",
|
||||
"item.nestle_rope_arrow.desc.3": "§c2.§r When fired from its launcher, the first player hit will become the arrow's owner and will fly along with it.",
|
||||
"item.nestle_rope_arrow.desc.4": "",
|
||||
"item.nestle_rope_arrow.desc.5": "",
|
||||
"item.spectral_leash_rope_arrow.desc": "§c2.§r Strike the entity to give it a §e§lGlowing§r effect.",
|
||||
"item.tipped_leash_rope_arrow.desc": "§c2.§rStrike the entity to give it a Potion effect.",
|
||||
"item.tipped_leash_rope_arrow.name": "Tipped Leash Rope Arrow Soaked By %1$s",
|
||||
"item.variant.leash_rope_arrow.desc.1": "§7A variant of Leash Rope Arrow",
|
||||
"item.variant.leash_rope_arrow.desc.2": "§c1.§r The function is the same as its original one。",
|
||||
"jukebox_song.leashedplayer.what_does_the_fox_say": "What does the fox say?",
|
||||
"key.leashedplayer.apply_talkarea_preference": "Apply TalkArea Preference",
|
||||
"key.leashedplayer.category": "Leashed Player",
|
||||
"key.leashedplayer.leash_length.add": "Increase the Length of Leash Rope",
|
||||
"key.leashedplayer.leash_length.not_support_to_not_player_entity": "Only work on Players",
|
||||
"key.leashedplayer.leash_length.sub": "Decrease the Length of Leash Rope",
|
||||
"leashedplayer.chat.none_heard_you": "Nobody heard your message",
|
||||
"leashedplayer.command.chat.message.no_right": "You haven't the right to do that!",
|
||||
"leashedplayer.command.chat.message.talkarea.current_config": "%s 's §6TalkArea Current§7:§e %d §6blocks §f(§aPrefence§7:§e %d §ablocks§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference.set": "%s 's §atalk area preference set to §e%d§a blocks!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s 's talk area preference is not set!",
|
||||
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6TalkArea Current§7:§e %d §6blocks §f(§aPrefence§7:§e %d §ablocks§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§aTalk area preference set to §e%d§a blocks!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "Your talk area preference is not set!",
|
||||
"leashedplayer.command.chat.message.talkarea.self.set": "§aTalk area set to §e%d§a blocks!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§aTalk area unlimited!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.set": "%s 's §atalk area set to §e%d§a blocks!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.unlimited": "%s 's §atalk area unlimited!§r",
|
||||
"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",
|
||||
|
|
@ -110,7 +82,6 @@
|
|||
"leashedplayer.leash_rope.length.increase": "§aIncrease the §f%s §aLength of Leash Rope§7(§bLength§7:§e%d§7)",
|
||||
"leashedplayer.leash_rope.length.increase.self": "§aIncrease the Length of Leash Rope§7(§bLength§7:§e%d§7)",
|
||||
"leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§aPush §f§lShift§a to pick up quickly",
|
||||
"multiplayer.disconnect.addiction": "You've triggered the anti-addiction mechanic, and you'll come back when you rest!",
|
||||
"painting.leashedplayer.group_photo.author": "§9Leisure §4Time §eDock§r",
|
||||
"painting.leashedplayer.group_photo.title": "§dGroup Photo §7[§6memorable§7]§r",
|
||||
"sound.leashedplayer.subtitle.what_does_the_fox_say": "Great Chu will rise again! Chen She will be king!"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
{
|
||||
"entity.leashedplayer.kid_player": "幼",
|
||||
"gamerule.LP.DefaultTalkArea.description": "阖局初置非负数,则限一顾之日下,若立聊城小在直则用其常,若用玩义直上跻之地",
|
||||
"leashedplayer.chat.none_heard_you": "无人受子问",
|
||||
"leashedplayer.command.chat.message.talkarea.current_config": "%s§6今聊城可知半径置§e %d§6格§f(§a默§7:§e%d格§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference.set": "%s§6默置§e %d§6格§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s未置默视之",
|
||||
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6今聊城可知半径置§e %d§6格§f(§a默§7:§e%d格§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§6默置§e %d§6格§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "未置默视之",
|
||||
"leashedplayer.command.chat.message.talkarea.self.set": "§6今聊城可知半径置§e%d §6格§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§a语矢无限§r",
|
||||
"leashedplayer.command.chat.message.talkarea.set": "%s§6今聊城可知半径置§e%d §6格§r",
|
||||
"leashedplayer.command.chat.message.talkarea.unlimited": "%s§a语矢无限§r"
|
||||
"entity.leashedplayer.kid_player": "幼"
|
||||
}
|
||||
|
|
@ -17,8 +17,6 @@
|
|||
"advancement.leashedplayer.leashed_self.desc": "用拴绳拴住自己",
|
||||
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
|
||||
"advancement.leashedplayer.neo_fox.desc": "似乎可以戴头上",
|
||||
"advancement.leashedplayer.nestle_arrow": "贴贴之箭!",
|
||||
"advancement.leashedplayer.nestle_arrow.desc": "贴贴之力!!!",
|
||||
"advancement.leashedplayer.no_leash": "勿拴我",
|
||||
"advancement.leashedplayer.no_leash.desc": "你不会被任何东西拴住",
|
||||
"advancement.leashedplayer.tipped_leash_arrow": "神说要有更多箭矢",
|
||||
|
|
@ -29,16 +27,10 @@
|
|||
"entity.leashedplayer.leash_rope_arrow": "拴绳箭",
|
||||
"entity.leashedplayer.nestle_rope_arrow": "贴贴拴绳箭",
|
||||
"entity.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
|
||||
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea": "非OP应该可以修改自己的聊天可见半径吗?",
|
||||
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea.description": "同名",
|
||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失则创建拴绳结",
|
||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在栅栏处缺失拴绳结,则创建它",
|
||||
"gamerule.LP.DefaultTalkArea": "默认聊天区域可见半径",
|
||||
"gamerule.LP.DefaultTalkArea.description": "全局区域设置为非负数时,则限制全体玩家的聊天区域。若玩家设置的聊天区域小于该值则采用该规则,反之则采用玩家自定义值",
|
||||
"gamerule.LP.KeepLeashNotDropTime": "保持拴绳不掉落的时间",
|
||||
"gamerule.LP.KeepLeashNotDropTime.description": "当距离过远时,保持新建拴绳不掉落的时间 (刻)",
|
||||
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull": "当屏幕不为空时自动打开探测器的Needed模式",
|
||||
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull.description": "当屏幕不为空时自动打开探测器的Needed模式",
|
||||
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者传送",
|
||||
"gamerule.LP.TeleportWithLeashedPlayers.description": "传送时将被拴玩家与持有者一起传送",
|
||||
"item.leash_rope_arrow.desc.1": "§7该箭将会携带拥有者随其飞行",
|
||||
|
|
@ -49,43 +41,23 @@
|
|||
"item.leash_rope_arrow.description": "带有拴绳的箭矢?",
|
||||
"item.leashedplayer.amethyst_shears": "紫水晶剪刀",
|
||||
"item.leashedplayer.fabric": "Fabric",
|
||||
"item.leashedplayer.kid_spawn_egg": "小孩生成蛋",
|
||||
"item.leashedplayer.leash_rope_arrow": "拴绳箭",
|
||||
"item.leashedplayer.neoforge": "NeoForge",
|
||||
"item.leashedplayer.nestle_rope_arrow": "贴贴拴绳箭",
|
||||
"item.leashedplayer.spectral_leash_rope_arrow": "拴绳光灵箭",
|
||||
"item.minecraft.lingering_potion.effect.no_leash": "滞留型禁拴药水",
|
||||
"item.minecraft.potion.effect.no_leash": "禁拴药水",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "喷溅型禁拴药水",
|
||||
"item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭",
|
||||
"item.nestle_rope_arrow.desc.1": "§7该箭将会携带拥有者随其飞行",
|
||||
"item.nestle_rope_arrow.desc.2": "§c1.§r 若击中生物时,将持有者与其拴在一起并已普通箭形式掉落;",
|
||||
"item.nestle_rope_arrow.desc.3": "§c2.§r 当前其发射器里发射,第一个射中的玩家将成为此箭的持有者并随箭飞行.",
|
||||
"item.nestle_rope_arrow.desc.4": "",
|
||||
"item.nestle_rope_arrow.desc.5": "",
|
||||
"item.spectral_leash_rope_arrow.desc": "§c2.§r 击中实体给与其§e§l发光§7(§e§lGlowing§7)§r效果",
|
||||
"item.tipped_leash_rope_arrow.desc": "§c2.§r 击中实体给与其药水效果",
|
||||
"item.tipped_leash_rope_arrow.name": "用%1$s浸泡过的拴绳箭",
|
||||
"item.variant.leash_rope_arrow.desc.1": "§7拴绳箭的一个变种",
|
||||
"item.variant.leash_rope_arrow.desc.2": "§c1.§r 功能同其本体;",
|
||||
"jukebox_song.leashedplayer.what_does_the_fox_say": "狐狸是怎么叫的?",
|
||||
"key.leashedplayer.apply_talkarea_preference": "应用可见区域预设",
|
||||
"key.leashedplayer.category": "可拴玩家",
|
||||
"key.leashedplayer.leash_length.add": "增加拴绳长度",
|
||||
"key.leashedplayer.leash_length.not_support_to_not_player_entity": "只在玩家身上有效",
|
||||
"key.leashedplayer.leash_length.sub": "减小拴绳长度",
|
||||
"leashedplayer.chat.none_heard_you": "沒有人接收到你的消息",
|
||||
"leashedplayer.command.chat.message.no_right": "你无权这样做!",
|
||||
"leashedplayer.command.chat.message.talkarea.current_config": "%s§6目前聊天区域可见半径设置§7:§e %d §6格 §f(§a默认值§7:§e %d §a格§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference.set": "%s§a默认聊天区域可见消息半径设置为 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s未设置默认可见消息聊天区域半径",
|
||||
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6目前聊天区域可见半径设置§7:§e %d §6格 §f(§a默认值§7:§e %d §a格§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§a默认聊天区域可见消息半径设置为 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "未设置默认可见消息聊天区域半径",
|
||||
"leashedplayer.command.chat.message.talkarea.self.set": "§a聊天区域可见消息半径设置为 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§a聊天区域半径无限制§r",
|
||||
"leashedplayer.command.chat.message.talkarea.set": "%s§a聊天区域可见消息半径设置为 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.unlimited": "%s§a聊天区域半径无限制§r",
|
||||
"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沒有拴绳数据实体",
|
||||
|
|
@ -110,7 +82,6 @@
|
|||
"leashedplayer.leash_rope.length.increase": "§a增加§f%s的拴绳长度§a§7(§b长度§7:§e%d§7)",
|
||||
"leashedplayer.leash_rope.length.increase.self": "§a增加拴绳长度§a§7(§b长度§7:§e%d§7)",
|
||||
"leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§a按下§f§lShift键§a以加快拾取",
|
||||
"multiplayer.disconnect.addiction": "你触发了防沉迷机制,休息会再来吧!",
|
||||
"painting.leashedplayer.group_photo.author": "§9闲趣§4时§e坞§r",
|
||||
"painting.leashedplayer.group_photo.title": "§d集体照 §7[§6纪念§7]§r",
|
||||
"sound.leashedplayer.subtitle.what_does_the_fox_say": "大楚兴~ 陈胜王~~"
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@
|
|||
"advancement.leashedplayer.leashed_self.desc": "用栓繩拴住自己",
|
||||
"advancement.leashedplayer.neo_fox": "NEOFORGE!",
|
||||
"advancement.leashedplayer.neo_fox.desc": "似乎可以戴著",
|
||||
"advancement.leashedplayer.nestle_arrow": "貼貼之箭!",
|
||||
"advancement.leashedplayer.nestle_arrow.desc": "貼貼之力!!!",
|
||||
"advancement.leashedplayer.no_leash": "請恁勿拴唔",
|
||||
"advancement.leashedplayer.no_leash.desc": "恁不會被任何拴住",
|
||||
"advancement.leashedplayer.tipped_leash_arrow": "神說要有更多箭矢",
|
||||
|
|
@ -29,16 +27,10 @@
|
|||
"entity.leashedplayer.leash_rope_arrow": "拴繩箭",
|
||||
"entity.leashedplayer.nestle_rope_arrow": "貼貼拴繩箭",
|
||||
"entity.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
|
||||
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea": "非OP應該可以修改自己的聊天可見半徑嗎?",
|
||||
"gamerule.LP.CanCommonPlayerChangeSelfTalkArea.description": "同名",
|
||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent": "如果缺失則創建拴繩結",
|
||||
"gamerule.LP.CreateLeashFenceKnotEntityIfAbsent.description": "如果在柵欄処缺失拴繩結,則創建它",
|
||||
"gamerule.LP.DefaultTalkArea": "默認聊天區域可見半徑",
|
||||
"gamerule.LP.DefaultTalkArea.description": "儅全局區域為非負時,則限制全服玩家聊天區域。若玩家自定義值小於該規則則采用,反之則用玩家自定義值",
|
||||
"gamerule.LP.KeepLeashNotDropTime": "保持其不掉落的時間",
|
||||
"gamerule.LP.KeepLeashNotDropTime.description": "儅距離過遠時,保持其不掉落的時間(刻)",
|
||||
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull": "避免糠測器糠屏幕",
|
||||
"gamerule.LP.OpenTOPNeededModeWhenScreenIsNotNull.description": "避免糠測器糠屏幕",
|
||||
"gamerule.LP.TeleportWithLeashedPlayers": "被拴玩家随玩家持有者傳送",
|
||||
"gamerule.LP.TeleportWithLeashedPlayers.description": "將被拴玩家將隨持有者一起傳送",
|
||||
"item.leash_rope_arrow.desc.1": "§7該箭將會攜帶擁有者隨其飛行:",
|
||||
|
|
@ -49,43 +41,23 @@
|
|||
"item.leash_rope_arrow.description": "帶有拴繩的箭矢?",
|
||||
"item.leashedplayer.amethyst_shears": "紫水晶剪刀",
|
||||
"item.leashedplayer.fabric": "Fabric",
|
||||
"item.leashedplayer.kid_spawn_egg": "小孩生成蛋",
|
||||
"item.leashedplayer.leash_rope_arrow": "拴繩箭",
|
||||
"item.leashedplayer.neoforge": "NeoForge",
|
||||
"item.leashedplayer.nestle_rope_arrow": "貼貼拴繩箭",
|
||||
"item.leashedplayer.spectral_leash_rope_arrow": "拴繩光靈箭",
|
||||
"item.minecraft.lingering_potion.effect.no_leash": "滯留型禁拴藥水",
|
||||
"item.minecraft.potion.effect.no_leash": "禁拴藥水",
|
||||
"item.minecraft.splash_potion.effect.no_leash": "噴濺型禁拴藥水",
|
||||
"item.minecraft.tipped_arrow.effect.no_leash": "禁拴之箭",
|
||||
"item.nestle_rope_arrow.desc.1": "§7該箭將會攜帶擁有者隨其飛行:",
|
||||
"item.nestle_rope_arrow.desc.2": "§c1.§r 若擊中生物時,將持有者與其拴在一起其上並以普通箭的形式掉落;",
|
||||
"item.nestle_rope_arrow.desc.3": "§c2.§r 當箭從發射器發射時,第一個射中的玩家將成為此箭的持有者並隨箭飛行;",
|
||||
"item.nestle_rope_arrow.desc.4": "",
|
||||
"item.nestle_rope_arrow.desc.5": "",
|
||||
"item.spectral_leash_rope_arrow.desc": "擊中實體給予其§e§l發光§7(§e§lGlowing§7)§r效果",
|
||||
"item.tipped_leash_rope_arrow.desc": "擊中實體給予其药水效果",
|
||||
"item.tipped_leash_rope_arrow.name": "蘸有%1$s的拴繩箭",
|
||||
"item.variant.leash_rope_arrow.desc.1": "§7拴繩箭矢的一個變種",
|
||||
"item.variant.leash_rope_arrow.desc.2": "§c1.§r 功能與本體一致;",
|
||||
"jukebox_song.leashedplayer.what_does_the_fox_say": "狐狸是怎麽叫的?",
|
||||
"key.leashedplayer.apply_talkarea_preference": "應用設置可見區域預設",
|
||||
"key.leashedplayer.category": "可拴玩家",
|
||||
"key.leashedplayer.leash_length.add": "增加拴繩長度",
|
||||
"key.leashedplayer.leash_length.not_support_to_not_player_entity": "僅對玩家有效",
|
||||
"key.leashedplayer.leash_length.sub": "減小拴繩長度",
|
||||
"leashedplayer.chat.none_heard_you": "無人接收到你的訊息",
|
||||
"leashedplayer.command.chat.message.no_right": "你無權這麽做!",
|
||||
"leashedplayer.command.chat.message.talkarea.current_config": "%s§6目前可見訊息聊天半徑設置§7:§e%d §6格 §f(§a默認值§7:§e%d §a格§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference.set": "%s§a默認聊天區域可見訊息半徑設置為 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.preference_not_set": "%s未設置可見訊息聊天半徑",
|
||||
"leashedplayer.command.chat.message.talkarea.self.current_config": "§6目前可見訊息聊天半徑設置§7:§e%d §6格 §f(§a默認值§7:§e%d §a格§f)§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference.set": "§a默認聊天區域可見訊息半徑設置為 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.preference_not_set": "未設置可見訊息聊天半徑",
|
||||
"leashedplayer.command.chat.message.talkarea.self.set": "§a聊天區域可見半徑為 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.self.unlimited": "§a聊天區域半徑無限制§r",
|
||||
"leashedplayer.command.chat.message.talkarea.set": "%s§a聊天區域可見半徑為 §e%d §a格!§r",
|
||||
"leashedplayer.command.chat.message.talkarea.unlimited": "%s§a聊天區域半徑無限制§r",
|
||||
"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沒有拴繩數據實體",
|
||||
|
|
@ -110,7 +82,6 @@
|
|||
"leashedplayer.leash_rope.length.increase": "§a增加§f%s§a的拴繩長度§7(§長度§7:§e%d§7)",
|
||||
"leashedplayer.leash_rope.length.increase.self": "§a增加拴繩長度§7(§長度§7:§e%d§7)",
|
||||
"leashedplayer.leash_rope_arrow.try_to_pickup.push_shift_tip": "§a按下§f§lShift鍵§a以加速拾取",
|
||||
"multiplayer.disconnect.addiction": "你觸發了防沉迷機制,休息會再來吧!",
|
||||
"painting.leashedplayer.group_photo.author": "§9閑趣§4時§e塢§r",
|
||||
"painting.leashedplayer.group_photo.title": "§d集體照 §7[§6紀念§7]§r",
|
||||
"sound.leashedplayer.subtitle.what_does_the_fox_say": "大楚興~ 陳勝王~~"
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:item/crossbow",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/crossbow_nestle_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:item/template_spawn_egg"
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/nestle_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/tipped_arrow_head",
|
||||
"layer0": "leashedplayer:item/tipped_leash_rope_arrow_head",
|
||||
"layer1": "leashedplayer:item/tipped_leash_rope_arrow_base"
|
||||
}
|
||||
}
|
||||
65
src/generated/resources/assets/minecraft/items/bow.json
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:condition",
|
||||
"on_false": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/bow"
|
||||
},
|
||||
"on_true": {
|
||||
"type": "leashedplayer:conditional_range",
|
||||
"fallback": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/bow_pulling_0"
|
||||
},
|
||||
"falseModels": [
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/bow_pulling_0"
|
||||
},
|
||||
"threshold": 0.0
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/bow_pulling_1"
|
||||
},
|
||||
"threshold": 0.65
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/bow_pulling_2"
|
||||
},
|
||||
"threshold": 0.9
|
||||
}
|
||||
],
|
||||
"property": "leashedplayer:bow_pull",
|
||||
"scale": 0.05,
|
||||
"trueModels": [
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/bow_lra_pulling_0"
|
||||
},
|
||||
"threshold": 0.0
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/bow_lra_pulling_1"
|
||||
},
|
||||
"threshold": 0.65
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/bow_lra_pulling_2"
|
||||
},
|
||||
"threshold": 0.9
|
||||
}
|
||||
]
|
||||
},
|
||||
"property": "minecraft:using_item"
|
||||
}
|
||||
}
|
||||
61
src/generated/resources/assets/minecraft/items/crossbow.json
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:condition",
|
||||
"on_false": {
|
||||
"type": "minecraft:select",
|
||||
"cases": [
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/crossbow_arrow"
|
||||
},
|
||||
"when": "arrow"
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/crossbow_firework"
|
||||
},
|
||||
"when": "rocket"
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "leashedplayer:item/crossbow_leash_rope_arrow"
|
||||
},
|
||||
"when": "leash_rope_arrow"
|
||||
}
|
||||
],
|
||||
"fallback": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/crossbow"
|
||||
},
|
||||
"property": "leashedplayer:charge_extend_type"
|
||||
},
|
||||
"on_true": {
|
||||
"type": "minecraft:range_dispatch",
|
||||
"entries": [
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/crossbow_pulling_1"
|
||||
},
|
||||
"threshold": 0.58
|
||||
},
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/crossbow_pulling_2"
|
||||
},
|
||||
"threshold": 1.0
|
||||
}
|
||||
],
|
||||
"fallback": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/crossbow_pulling_0"
|
||||
},
|
||||
"property": "minecraft:crossbow/pull"
|
||||
},
|
||||
"property": "minecraft:using_item"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/bow",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/bow_nra_pulling_0"
|
||||
"layer0": "minecraft:item/bow_pulling_0"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/bow",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/bow_nra_pulling_1"
|
||||
"layer0": "minecraft:item/bow_pulling_1"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/bow",
|
||||
"textures": {
|
||||
"layer0": "leashedplayer:item/bow_nra_pulling_2"
|
||||
"layer0": "minecraft:item/bow_pulling_2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/crossbow",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/crossbow_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/crossbow",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/crossbow_firework"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/crossbow",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/crossbow_pulling_0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/crossbow",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/crossbow_pulling_1"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/crossbow",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/crossbow_pulling_2"
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
},
|
||||
"display": {
|
||||
"announce_to_chat": false,
|
||||
"background": "leashedplayer:textures/gui/advancements/backgrounds/leashed_player.png",
|
||||
"background": "leashedplayer:textures/gui/advancements/backgrounds/leashed_player",
|
||||
"description": {
|
||||
"translate": "advancement.leashedplayer.leash_start.desc"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"parent": "leashedplayer:leash_arrow",
|
||||
"criteria": {
|
||||
"has_nestle_rope_arrow": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "leashedplayer:nestle_rope_arrow"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"description": {
|
||||
"translate": "advancement.leashedplayer.nestle_arrow.desc"
|
||||
},
|
||||
"frame": "goal",
|
||||
"hidden": true,
|
||||
"icon": {
|
||||
"count": 1,
|
||||
"id": "leashedplayer:nestle_rope_arrow"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancement.leashedplayer.nestle_arrow"
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_nestle_rope_arrow"
|
||||
]
|
||||
],
|
||||
"sends_telemetry_event": true
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"criteria": {
|
||||
"has_nestle_rope": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "nestle:nestle_lead"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"conditions": {
|
||||
"recipe": "leashedplayer:nestle_rope_arrow"
|
||||
},
|
||||
"trigger": "minecraft:recipe_unlocked"
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_the_recipe",
|
||||
"has_nestle_rope"
|
||||
]
|
||||
],
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"leashedplayer:nestle_rope_arrow"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"has_the_recipe": {
|
||||
"conditions": {
|
||||
"recipe": "minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow"
|
||||
"recipe": "leashedplayer:spectral_leash_rope_arrow"
|
||||
},
|
||||
"trigger": "minecraft:recipe_unlocked"
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
],
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"minecraft:spectral_leash_rope_arrow_with_leash_rope_arrow"
|
||||
"leashedplayer:spectral_leash_rope_arrow"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
{
|
||||
"asset_id": "leashedplayer:group_photo",
|
||||
"author": {
|
||||
"translate": "painting.leashedplayer.group_photo.author"
|
||||
},
|
||||
"height": 3,
|
||||
"title": {
|
||||
"translate": "painting.leashedplayer.group_photo.title"
|
||||
},
|
||||
"width": 4
|
||||
}
|
||||
|
|
@ -2,12 +2,8 @@
|
|||
"type": "minecraft:crafting_shaped",
|
||||
"category": "misc",
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "minecraft:amethyst_shard"
|
||||
},
|
||||
"%": {
|
||||
"item": "minecraft:stick"
|
||||
}
|
||||
"#": "minecraft:amethyst_shard",
|
||||
"%": "minecraft:stick"
|
||||
},
|
||||
"pattern": [
|
||||
"#%",
|
||||
|
|
|
|||
|
|
@ -2,12 +2,8 @@
|
|||
"type": "minecraft:crafting_shapeless",
|
||||
"category": "misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:lead"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:arrow"
|
||||
}
|
||||
"minecraft:lead",
|
||||
"minecraft:arrow"
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"category": "misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "nestle:nestle_lead"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:arrow"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
"id": "leashedplayer:nestle_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,8 @@
|
|||
"type": "minecraft:crafting_shapeless",
|
||||
"category": "misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:lead"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:spectral_arrow"
|
||||
}
|
||||
"minecraft:lead",
|
||||
"minecraft:spectral_arrow"
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"has_the_recipe": {
|
||||
"conditions": {
|
||||
"recipe": "minecraft:spectral_leash_rope_arrow_with_glowstone_dust"
|
||||
"recipe": "minecraft:leash_rope_arrow_shape"
|
||||
},
|
||||
"trigger": "minecraft:recipe_unlocked"
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
],
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"minecraft:spectral_leash_rope_arrow_with_glowstone_dust"
|
||||
"minecraft:leash_rope_arrow_shape"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"criteria": {
|
||||
"has_nestle": {
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": "nestle:nestle"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trigger": "minecraft:inventory_changed"
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"conditions": {
|
||||
"recipe": "minecraft:nestle_rope_arrow_with_leash_rope_arrow"
|
||||
},
|
||||
"trigger": "minecraft:recipe_unlocked"
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"has_the_recipe",
|
||||
"has_nestle"
|
||||
]
|
||||
],
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"minecraft:nestle_rope_arrow_with_leash_rope_arrow"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,8 @@
|
|||
"type": "minecraft:crafting_shaped",
|
||||
"category": "misc",
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "leashedplayer:leash_rope_arrow"
|
||||
},
|
||||
"$": {
|
||||
"item": "minecraft:glowstone_dust"
|
||||
}
|
||||
"#": "leashedplayer:leash_rope_arrow",
|
||||
"$": "minecraft:glowstone_dust"
|
||||
},
|
||||
"pattern": [
|
||||
" $ ",
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"category": "misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "nestle:nestle"
|
||||
},
|
||||
{
|
||||
"item": "leashedplayer:leash_rope_arrow"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"count": 1,
|
||||
"id": "leashedplayer:nestle_rope_arrow"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"values": [
|
||||
"minecraft:amethyst_shard"
|
||||
]
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
"values": [
|
||||
"leashedplayer:leash_rope_arrow",
|
||||
"leashedplayer:spectral_leash_rope_arrow",
|
||||
"leashedplayer:tipped_leash_rope_arrow",
|
||||
"leashedplayer:nestle_rope_arrow"
|
||||
"leashedplayer:tipped_leash_rope_arrow"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,93 +1,51 @@
|
|||
package com.r3944realms.leashedplayer;
|
||||
|
||||
import com.r3944realms.leashedplayer.client.renders.entities.*;
|
||||
import com.r3944realms.leashedplayer.client.renderer.LeashRendererUtil;
|
||||
import com.r3944realms.leashedplayer.client.renderer.PlayerLeashState;
|
||||
import com.r3944realms.leashedplayer.client.renderer.entities.ChestItemLayerRenderer;
|
||||
import com.r3944realms.leashedplayer.client.renderer.entities.LeashRopeArrowRenderer;
|
||||
import com.r3944realms.leashedplayer.client.renderer.entities.SpectralLeashRopeArrowRenderer;
|
||||
import com.r3944realms.leashedplayer.client.renderer.item.ConditionalRangeItemModel;
|
||||
import com.r3944realms.leashedplayer.client.renderer.item.properties.conditional.ChargeExtend;
|
||||
import com.r3944realms.leashedplayer.content.ModKeyMapping;
|
||||
import com.r3944realms.leashedplayer.content.commands.Command;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.content.items.type.INestleRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import com.r3944realms.leashedplayer.network.server.Code;
|
||||
import com.r3944realms.leashedplayer.network.server.DecreaseLeashRopeLength;
|
||||
import com.r3944realms.leashedplayer.network.server.IncreaseLeashRopeLength;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
import mcjty.theoneprobe.config.Config;
|
||||
import mcjty.theoneprobe.gui.GuiNote;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.ChatScreen;
|
||||
import net.minecraft.client.gui.screens.DisconnectedScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import net.minecraft.client.resources.PlayerSkin;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.DisconnectionDetails;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.minecraft.world.item.component.ChargedProjectiles;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.*;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public abstract class ClientEventHandler {
|
||||
public static final String ADDICTION = "multiplayer.disconnect.addiction";
|
||||
public class ClientEventHandler {
|
||||
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME, modid = LeashedPlayer.MOD_ID)
|
||||
public static class Game extends ClientEventHandler {
|
||||
private static int oldSelect;
|
||||
private static boolean configSaved = false;
|
||||
private static final boolean IS_TOP_LOADED = ModList.get().isLoaded("theoneprobe");
|
||||
public static class Game {
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(ClientTickEvent.Pre event) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.level == null) return;
|
||||
if (GameruleRegistry.getGameruleBoolValue(mc.level, OpenTOPNeededModeWhenScreenIsNotNull.ID)){
|
||||
Screen currentScreen = mc.screen;
|
||||
if (IS_TOP_LOADED) {
|
||||
if (currentScreen != null) {
|
||||
if (currentScreen instanceof GuiNote || currentScreen instanceof ChatScreen) {
|
||||
configSaved = false;
|
||||
oldSelect = Config.needsProbe.get();
|
||||
} else {
|
||||
if (!configSaved) {
|
||||
oldSelect = Config.needsProbe.get();
|
||||
Config.setProbeNeeded(Config.PROBE_NEEDED);
|
||||
configSaved = true;
|
||||
} else {
|
||||
Config.setProbeNeeded(Config.PROBE_NEEDED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Config.setProbeNeeded(oldSelect);
|
||||
configSaved = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void onScreenOpen(ScreenEvent.Opening opening) {
|
||||
if(opening.getNewScreen() instanceof DisconnectedScreen screen) {
|
||||
if (screen.details.reason().getString().equals("You are already connected to this proxy!")) {
|
||||
screen.details = new DisconnectionDetails(Component.translatable(ADDICTION).withStyle(ChatFormatting.RED));
|
||||
}
|
||||
public static void onPlayerRendererEventPre(RenderPlayerEvent.Post event) {
|
||||
PlayerRenderState renderState = event.getRenderState();
|
||||
PlayerLeashState playerLeashState = ((IPlayerRenderStateExtension) renderState).getPlayerLeashState();
|
||||
if(playerLeashState != null) {
|
||||
if (playerLeashState.vanilaLeashState != null)
|
||||
LeashRendererUtil.renderLeash(event.getPoseStack(), event.getMultiBufferSource(), playerLeashState.vanilaLeashState);
|
||||
else
|
||||
LeashRendererUtil.renderLeash(event.getPoseStack(), event.getMultiBufferSource(), renderState);
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
|
|
@ -95,10 +53,6 @@ public abstract class ClientEventHandler {
|
|||
Minecraft minecraft = Minecraft.getInstance();
|
||||
LocalPlayer player = minecraft.player;
|
||||
assert player != null;
|
||||
if (ModKeyMapping.KEY_APPLY_TALKAREA_PREFERENCE.isDown()) {
|
||||
String prefix = (Command.SHOULD_USE_PREFIX ? Command.PREFIX : "") + " ";
|
||||
player.connection.sendCommand(prefix + "talkArea usePreference");
|
||||
}
|
||||
if (ModKeyMapping.KEY_ADD_LEASH_LENGTH.isDown()) {
|
||||
PlayerLeashable playerLeashable = (PlayerLeashable) player;
|
||||
if (playerLeashable.getLeashDataFromEntityData() == null) {
|
||||
|
|
@ -135,70 +89,37 @@ public abstract class ClientEventHandler {
|
|||
}
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD, modid = LeashedPlayer.MOD_ID)
|
||||
public static class Mod extends ClientEventHandler {
|
||||
public static class Mod {
|
||||
@SubscribeEvent
|
||||
public static void onRegisterItemProperties (FMLClientSetupEvent event){
|
||||
event.enqueueWork(() -> {
|
||||
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()) || chargedProjectiles.contains(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get())) ? 1.0F : 0.0F;}
|
||||
));
|
||||
ItemProperties.register(Items.CROSSBOW, ResourceLocation.withDefaultNamespace("nestle_rope_arrow"),
|
||||
((pStack, pLevel, pEntity, pSeed) -> {
|
||||
ChargedProjectiles chargedProjectiles = pStack.get(DataComponents.CHARGED_PROJECTILES);
|
||||
return chargedProjectiles != null && (chargedProjectiles.contains(ModItemRegister.NESTLE_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 && ILeashRopeArrow.isLeashRopeArrow(pStack, pEntity)) ? 1.0F : 0.0F
|
||||
));
|
||||
ItemProperties.register(Items.BOW, ResourceLocation.withDefaultNamespace("nestle_rope_arrow_pulling"),
|
||||
((pStack, pLevel, pEntity, pSeed) ->
|
||||
(pEntity != null && pEntity.isUsingItem() && pEntity.getUseItem() == pStack && INestleRopeArrow.isNestleRopeArrow(pStack, pEntity)) ? 1.0F : 0.0F
|
||||
));
|
||||
});
|
||||
|
||||
public static void onRegisterItemModels(RegisterItemModelsEvent event) {
|
||||
event.register(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "conditional_range"), ConditionalRangeItemModel.Unbaked.MAP_CODEC);
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void registrySelectItemModelProperty(RegisterSelectItemModelPropertyEvent event) {
|
||||
event.register(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "charge_extend_type"), ChargeExtend.TYPE);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerKeyMapping(RegisterKeyMappingsEvent event) {
|
||||
event.register(ModKeyMapping.KEY_APPLY_TALKAREA_PREFERENCE);
|
||||
event.register(ModKeyMapping.KEY_ADD_LEASH_LENGTH);
|
||||
event.register(ModKeyMapping.KEY_SUB_LEASH_LENGTH);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRegisterRenderer (EntityRenderersEvent.RegisterRenderers event) {
|
||||
event.registerEntityRenderer(ModEntityRegister.NESTLE_ROPE_ARROW.get(), NestleRopeArrowRenderer::new);
|
||||
event.registerEntityRenderer(ModEntityRegister.LEASH_ROPE_ARROW.get(), LeashRopeArrowRenderer::new);
|
||||
event.registerEntityRenderer(ModEntityRegister.SPECTRAL_LEASH_ROPE_ARROW.get(), SpectralLeashRopeArrowRenderer::new);
|
||||
event.registerEntityRenderer(ModEntityRegister.KID.get(), KidPlayerRenderer::create);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onAddLayers (EntityRenderersEvent.AddLayers event){
|
||||
|
||||
PlayerRenderer renderer = event.getSkin(PlayerSkin.Model.WIDE);
|
||||
if (renderer instanceof PlayerRenderer playerRenderer) {
|
||||
playerRenderer.addLayer(new ChestItemLayerRenderer<>(playerRenderer, event.getContext().getItemInHandRenderer()));
|
||||
playerRenderer.addLayer(new ChestItemLayerRenderer<>(playerRenderer, event.getContext().getEntityRenderDispatcher().getItemInHandRenderer()));
|
||||
}
|
||||
|
||||
PlayerRenderer slimRenderer = event.getSkin(PlayerSkin.Model.SLIM);
|
||||
if (slimRenderer instanceof PlayerRenderer slimPlayerRenderer) {
|
||||
slimPlayerRenderer.addLayer(new ChestItemLayerRenderer<>(slimPlayerRenderer, event.getContext().getItemInHandRenderer()));
|
||||
slimPlayerRenderer.addLayer(new ChestItemLayerRenderer<>(slimPlayerRenderer, event.getContext().getEntityRenderDispatcher().getItemInHandRenderer()));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRegisterItemColorHandlers (RegisterColorHandlersEvent.Item event){
|
||||
event.register(
|
||||
(color, i) -> i > 0
|
||||
? -1
|
||||
: FastColor.ARGB32.opaque(color.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).getColor()),
|
||||
ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get()
|
||||
);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,22 @@
|
|||
package com.r3944realms.leashedplayer;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.r3944realms.leashedplayer.content.commands.*;
|
||||
import com.r3944realms.leashedplayer.content.commands.LeashCommand;
|
||||
import com.r3944realms.leashedplayer.content.commands.MotionCommand;
|
||||
import com.r3944realms.leashedplayer.content.commands.TickCommand;
|
||||
import com.r3944realms.leashedplayer.content.effects.ModPotionRegister;
|
||||
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.ModEntityRegister;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.GameruleRegistry;
|
||||
import com.r3944realms.leashedplayer.content.gamerules.Server.OpenTOPNeededModeWhenScreenIsNotNull;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import com.r3944realms.leashedplayer.content.misc.LeadBreakItemBehavior;
|
||||
import com.r3944realms.leashedplayer.network.client.BooleanGameRuleValueChangeData;
|
||||
import com.r3944realms.leashedplayer.utils.Logger;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
import io.github.kunosayo.nestle.init.ModCreativeTab;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.animal.Fox;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.alchemy.PotionBrewing;
|
||||
|
|
@ -33,13 +27,9 @@ import net.neoforged.bus.api.SubscribeEvent;
|
|||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.neoforged.neoforge.event.AnvilUpdateEvent;
|
||||
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
|
||||
import net.neoforged.neoforge.event.RegisterCommandsEvent;
|
||||
import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent;
|
||||
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.tick.EntityTickEvent;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
|
||||
public class CommonEventHandler {
|
||||
|
|
@ -50,45 +40,13 @@ public class CommonEventHandler {
|
|||
CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
|
||||
LeashCommand.register(dispatcher);
|
||||
MotionCommand.register(dispatcher);
|
||||
ChatCommand.register(dispatcher);
|
||||
TickCommand.register(dispatcher);
|
||||
DebugCommand.register(dispatcher);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onJoinServer(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
PacketDistributor.sendToPlayer((ServerPlayer) event.getEntity(),
|
||||
new BooleanGameRuleValueChangeData(
|
||||
OpenTOPNeededModeWhenScreenIsNotNull.ID,
|
||||
GameruleRegistry.getGameruleBoolValue(
|
||||
event.getEntity().level(),
|
||||
OpenTOPNeededModeWhenScreenIsNotNull.ID)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public static void OnRegisterPotionBrewing(RegisterBrewingRecipesEvent event) {
|
||||
PotionBrewing.Builder builder = event.getBuilder();
|
||||
builder.addMix(Potions.WATER, Items.SLIME_BALL, ModPotionRegister.NO_LEASH);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void OnAnvilUpdated(AnvilUpdateEvent event) {
|
||||
String name = event.getName();
|
||||
ItemStack left = event.getLeft();
|
||||
if (left.is(Items.ANVIL) && name != null && name.equals("NeoForge")) {
|
||||
event.setCost(1);
|
||||
event.setOutput(ModItemRegister.NEOFORGE.get().getDefaultInstance());
|
||||
} else if (left.is(ModItemRegister.NEOFORGE.get().asItem()) && name != null && name.equals("Forge")) {
|
||||
ItemStack instance = Items.ANVIL.getDefaultInstance();
|
||||
instance.set(DataComponents.CUSTOM_NAME, Component.literal("Forge").withStyle(ChatFormatting.BOLD).withStyle(ChatFormatting.AQUA));
|
||||
event.setOutput(instance);
|
||||
event.setCost(1);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void OnLivingTickEvent(EntityTickEvent.Post event) {
|
||||
Entity entity = event.getEntity();
|
||||
|
|
@ -96,62 +54,55 @@ public class CommonEventHandler {
|
|||
if (level.isClientSide()) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Fox fox) {
|
||||
if (fox.getMainHandItem().is(ItemTags.ANVIL)) {
|
||||
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
Util.throwItemTowardsLook(fox, ModItemRegister.NEOFORGE.get(), 0.3f, 0.1f);
|
||||
fox.playSound(fox.getEatingSound(ItemStack.EMPTY));
|
||||
} else if (fox.getMainHandItem().is(ModItemRegister.NEOFORGE.get())) {
|
||||
// 繞圈參數
|
||||
float rotationSpeed = 10.0f; // 每 tick 旋轉的角度
|
||||
// 計算新的旋轉角度
|
||||
fox.yBodyRot += rotationSpeed; // 身體旋轉
|
||||
fox.yHeadRot += rotationSpeed; // 頭部旋轉
|
||||
fox.yRotO += rotationSpeed; // 當前旋轉角度
|
||||
fox.yHeadRotO += rotationSpeed; // 頭部的當前旋轉角度
|
||||
if (entity instanceof Fox fox) {
|
||||
if (fox.getMainHandItem().is(ItemTags.ANVIL)) {
|
||||
fox.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
Util.throwItemTowardsLook(fox, ModItemRegister.NEOFORGE.get(), 0.3f, 0.1f);
|
||||
fox.playSound(SoundEvents.FOX_EAT);
|
||||
} else if (fox.getMainHandItem().is(ModItemRegister.NEOFORGE.get())) {
|
||||
// 繞圈參數
|
||||
float rotationSpeed = 10.0f; // 每 tick 旋轉的角度
|
||||
// 計算新的旋轉角度
|
||||
fox.yBodyRot += rotationSpeed; // 身體旋轉
|
||||
fox.yHeadRot += rotationSpeed; // 頭部旋轉
|
||||
fox.yRotO += rotationSpeed; // 當前旋轉角度
|
||||
fox.yHeadRotO += rotationSpeed; // 頭部的當前旋轉角度
|
||||
|
||||
// 確保旋轉角度不超出 360 度,重置為 0 以便持續旋轉
|
||||
if (fox.yBodyRot >= 360) fox.yBodyRot -= 360;
|
||||
if (fox.yHeadRot >= 360) fox.yHeadRot -= 360;
|
||||
// 確保旋轉角度不超出 360 度,重置為 0 以便持續旋轉
|
||||
if (fox.yBodyRot >= 360) fox.yBodyRot -= 360;
|
||||
if (fox.yHeadRot >= 360) fox.yHeadRot -= 360;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
|
||||
public static class Mod extends CommonEventHandler {
|
||||
@SubscribeEvent
|
||||
public static void onCommonSetup(FMLCommonSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
if (LeashedPlayer.IS_NESTLE_LOADED) {
|
||||
Logger.logger.info("[LeashedPlayer] Hello, Nestle");
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.NESTLE_ROPE_ARROW.get());
|
||||
}
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get());
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get());
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get());
|
||||
DispenserBlock.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior());
|
||||
});
|
||||
@SubscribeEvent
|
||||
public static void OnAnvilUpdated(AnvilUpdateEvent event) {
|
||||
String name = event.getName();
|
||||
ItemStack left = event.getLeft();
|
||||
if (left.is(Items.ANVIL) && name != null && name.equals("NeoForge")) {
|
||||
event.setCost(1);
|
||||
event.setOutput(ModItemRegister.NEOFORGE.get().getDefaultInstance());
|
||||
} else if (left.is(ModItemRegister.NEOFORGE.get().asItem()) && name != null && name.equals("Forge")) {
|
||||
ItemStack instance = Items.ANVIL.getDefaultInstance();
|
||||
instance.set(DataComponents.CUSTOM_NAME, Component.literal("Forge").withStyle(ChatFormatting.BOLD).withStyle(ChatFormatting.AQUA));
|
||||
event.setOutput(instance);
|
||||
event.setCost(1);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityAttributeEvent(EntityAttributeCreationEvent event) {
|
||||
event.put(ModEntityRegister.KID.get(), LittlePlayer.createAttributes().build());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onBuiltCreativeModeTabContents(BuildCreativeModeTabContentsEvent event) {
|
||||
if (LeashedPlayer.IS_NESTLE_LOADED){
|
||||
CreativeModeTab tab = event.getTab();
|
||||
if (tab == ModCreativeTab.MAIN_TABS.get()) {
|
||||
event.accept(ModItemRegister.NESTLE_ROPE_ARROW.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@EventBusSubscriber(modid = LeashedPlayer.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
|
||||
public static class Mod extends CommonEventHandler {
|
||||
@SubscribeEvent
|
||||
public static void onCommonSetup(FMLCommonSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.LEASH_ROPE_ARROW.get());
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get());
|
||||
DispenserBlock.registerProjectileBehavior(ModItemRegister.SPECTRAL_LEASH_ROPE_ARROW.get());
|
||||
DispenserBlock.registerBehavior(ModItemRegister.AMETHYST_SHEARS.get(), new LeadBreakItemBehavior());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.r3944realms.leashedplayer.content.paintings.ModPaintingsRegister;
|
|||
import com.r3944realms.leashedplayer.content.sounds.ModSoundRegister;
|
||||
import com.r3944realms.leashedplayer.utils.Util;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.ModLoadingContext;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.config.ModConfig;
|
||||
|
|
@ -21,27 +20,24 @@ import static com.r3944realms.leashedplayer.utils.Logger.logger;
|
|||
@Mod(LeashedPlayer.MOD_ID)
|
||||
public class LeashedPlayer {
|
||||
public static final String MOD_ID = "leashedplayer";
|
||||
public static boolean IS_NESTLE_LOADED;
|
||||
|
||||
private static Double M1;//拴繩掉落距離倍基數
|
||||
private static Double M2;//繩箭拴繩掉落距離倍基數
|
||||
private static Integer M3; //拴绳最小长度
|
||||
private static Integer M4; //拴绳最大长度
|
||||
public LeashedPlayer(IEventBus event) {
|
||||
ModItemRegister.register(event);
|
||||
ModPaintingsRegister.register(event);
|
||||
ModRecipeRegister.register(event);
|
||||
ModSoundRegister.register(event);
|
||||
ModPaintingsRegister.register(event);
|
||||
ModEffectRegister.register(event);
|
||||
ModPotionRegister.register(event);
|
||||
ModEntityRegister.register(event);
|
||||
ModCreativeTab.register(event);
|
||||
ModCriteriaTriggers.register(event);
|
||||
ModRecipeRegister.register(event);
|
||||
initiation();
|
||||
}
|
||||
private void initiation() {
|
||||
logger.info("Initializing LeashedPlayer Mod");
|
||||
IS_NESTLE_LOADED = ModList.get().isLoaded("nestle");
|
||||
String leashedPlayerCommonConfig = "LeashedPlayerCommonConfig";
|
||||
Util.configFileCreate(new String[]{leashedPlayerCommonConfig});
|
||||
ModLoadingContext.get().getActiveContainer().registerConfig(ModConfig.Type.COMMON, LeashPlayerCommonConfig.SPEC, MOD_ID + "/" + leashedPlayerCommonConfig + "/LeashPlayer.toml");
|
||||
|
|
@ -71,5 +67,4 @@ public class LeashedPlayer {
|
|||
return M4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,540 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.modInterface.ILivingEntityExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.entity.state.EntityRenderState;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.entity.vehicle.NewMinecartBehavior;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class LeashRendererUtil {
|
||||
public static void renderLeash(PoseStack poseStack, MultiBufferSource buffer, EntityRenderState.LeashState leashState) {
|
||||
float f = 0.025F;
|
||||
|
||||
float f1 = (float)(leashState.end.x - leashState.start.x);
|
||||
float f2 = (float)(leashState.end.y - leashState.start.y + 0.2);
|
||||
float f3 = (float)(leashState.end.z - leashState.start.z);
|
||||
float f4 = Mth.invSqrt(f1 * f1 + f3 * f3) * 0.025F / 2.0F;
|
||||
float f5 = f3 * f4;
|
||||
float f6 = f1 * f4;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(leashState.offset.add(0, -0.2, -0.2));
|
||||
VertexConsumer vertexconsumer = buffer.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix4f = poseStack.last().pose();
|
||||
|
||||
for (int i = 0; i <= 24; i++) {
|
||||
addVertexPair(
|
||||
vertexconsumer,
|
||||
matrix4f,
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
leashState.startBlockLight,
|
||||
leashState.endBlockLight,
|
||||
leashState.startSkyLight,
|
||||
leashState.endSkyLight,
|
||||
0.025F,
|
||||
0.025F,
|
||||
f5,
|
||||
f6,
|
||||
i,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
for (int j = 24; j >= 0; j--) {
|
||||
addVertexPair(
|
||||
vertexconsumer,
|
||||
matrix4f,
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
leashState.startBlockLight,
|
||||
leashState.endBlockLight,
|
||||
leashState.startSkyLight,
|
||||
leashState.endSkyLight,
|
||||
0.025F,
|
||||
0.0F,
|
||||
f5,
|
||||
f6,
|
||||
j,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
/**
|
||||
* <h1>1. 角度与弧度转换</h1>
|
||||
* {@snippet lang=java :
|
||||
* double d0 = (double)(pEntity.getPreciseBodyRotation(pPartialTick) * (float)(Math.PI / 180.0)) + (Math.PI / 2);
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>pEntity.getPreciseBodyRotation(pPartialTick)</code> 返回实体的旋转角度(通常是以度为单位)。/li>
|
||||
* <li> <code>(Math.PI / 180.0)</code> 是将度数转换为弧度的乘数,因为大多数三角函数(如 <code>cos</code> 和 <code>sin</code>)都需要弧度值。</li>
|
||||
* <li><code>+ (Math.PI / 2)</code> 用于将结果平移90度(四分之一圆),可能是为了校正方向或设置起始方向。 </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* <h1> 2. 三角函数计算位移</h1>
|
||||
* {@snippet lang=java :
|
||||
* double d1 = Math.cos(d0) * vec31.z + Math.sin(d0) * vec31.x;
|
||||
* double d2 = Math.sin(d0) * vec31.z - Math.cos(d0) * vec31.x;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>d1</code> 和 <code>d2</code> 是利用三角函数 <code>cos</code> 和 <code>sin</code> 计算出来的位移量,用于确定实体相对于其旋转的实际位置。</li>
|
||||
* <li><code>Math.cos(d0) * vec31.z</code> 和 <code>Math.sin(d0) * vec31.x</code> 分别计算沿 X 和 Z 轴的位移分量,这种计算通常用于旋转一个点或向量。</li>
|
||||
* <li>两个公式结合起来用于旋转平面内的一个点 <code>(vec31.x, vec31.z)</code>,从而得到旋转后的新坐标。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 3. 线性插值 (Lerp) </h1>
|
||||
* {@snippet lang=java :
|
||||
* double d3 = Mth.lerp(pPartialTick, pEntity.xo, pEntity.getX()) + d1;
|
||||
* double d4 = Mth.lerp(pPartialTick, pEntity.yo, pEntity.getY()) + vec31.y;
|
||||
* double d5 = Mth.lerp(pPartialTick, pEntity.zo, pEntity.getZ()) + d2;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>Mth.lerp</code> 是线性插值函数,通常用于在两个值之间平滑过渡。</li>
|
||||
* <li><code>pEntity.xo</code>, <code>pEntity.yo</code>, <code>pEntity.zo</code> 是实体在上一个刻度(tick)中的位置,而 <code>pEntity.getX()</code>, <code>pEntity.getY()</code>, <code>pEntity.getZ()</code> 是当前刻度的位置。</li>
|
||||
* <li><code>pPartialTick</code> 介于 <code>0</code> 和 <code>1</code> 之间,用来平滑过渡,使得动画更加流畅。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 4. 向量差值 </h1>
|
||||
* {@snippet lang=java :
|
||||
* float f = (float)(vec3.x - d3);
|
||||
* float f1 = (float)(vec3.y - d4);
|
||||
* float f2 = (float)(vec3.z - d5);
|
||||
* }
|
||||
* <ul>
|
||||
* <li>计算两个点(<code>vec3</code> 和 <code>(d3, d4, d5)</code>)之间的差值,得到的 <code>f</code>,<code>f1</code>,<code>f2</code> 是向量差,用于后续的渲染计算。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 5. 逆平方根与比例因子 </h1>
|
||||
* {@snippet lang=java :
|
||||
* float f4 = Mth.invSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
|
||||
* }
|
||||
* <ul>
|
||||
* <li><code>Mth.invSqrt</code> 计算的是逆平方根(通常用于归一化向量或调整比例)。</li>
|
||||
* <li><code>f * f + f2 * f2</code> 是计算向量 <code>(f, f2)</code> 的平方和,用于得到其长度的平方。</li>
|
||||
* <li>乘以 <code>0.025F / 2.0F</code> 用于缩放结果,使得线条在渲染时具有合适的比例。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 6. 循环绘制 </h1>
|
||||
* {@snippet lang=java :
|
||||
* for (int i1 = 0; i1 <= 24; i1++) {
|
||||
* addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.025F, 0.025F, f5, f6, i1, false);
|
||||
* }
|
||||
* }
|
||||
* <ul>
|
||||
* <li>循环从 <code>0</code> 到 <code>24</code>,用于创建24个顶点对,形成一个链状结构(或绳索)的外观。</li>
|
||||
* <li>每个循环迭代都会更新顶点的位置、颜色、光照等属性,使得链状结构被绘制出来。</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* <h1> 总结 </h1>
|
||||
* 这些数学运算主要用于计算实体在三维空间中的位置和方向,以确保在渲染链状结构(如拴住的绳索)时,链条能够跟随实体的移动和旋转并正确显示。在图形编程中,这些计算非常常见,尤其是在处理旋转、插值和光照效果时。
|
||||
*/
|
||||
|
||||
public static void renderLeash(
|
||||
PoseStack poseStack,
|
||||
MultiBufferSource bufferSource,
|
||||
PlayerRenderState playerRenderState
|
||||
) {
|
||||
float f = 0.025F;
|
||||
// 获得绳索持有者的位置
|
||||
PlayerLeashState leashState = ((IPlayerRenderStateExtension)playerRenderState).getPlayerLeashState();
|
||||
if (leashState == null)
|
||||
return;
|
||||
Vec3 Holder = leashState.pos;//TODO:问题修复
|
||||
Vec3 o = leashState.o;
|
||||
// 计算实体的朝向角度(弧度)
|
||||
float partialTick = playerRenderState.partialTick;
|
||||
double entityRotationAngleRadians = (double)(leashState.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
// 计算实体的绳索偏移,此处add偏移让渲染拴绳显示在玩家头部下(大约在脖子处
|
||||
// Logger.logger.info("eyeHeight:{}",playerRenderState.eyeHeight);
|
||||
Vec3 cameraEntityLeashOffset = new Vec3(0.0, leashState.eyeHeight , playerRenderState.boundingBoxWidth * 0.4F).add(0, -0.2, -0.2);
|
||||
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
// 计算实体当前的实际位置
|
||||
double entityPosX = Mth.lerp(partialTick, o.x, playerRenderState.x) + leashOffsetX;
|
||||
double entityPosY = Mth.lerp(partialTick, o.y, playerRenderState.y) + cameraEntityLeashOffset.y;
|
||||
double entityPosZ = Mth.lerp(partialTick, o.z, playerRenderState.z) + leashOffsetZ;
|
||||
|
||||
// 计算绳索的相对位置差
|
||||
float deltaX = (float)(Holder.x - entityPosX);
|
||||
float deltaY = (float)(Holder.y - entityPosY);
|
||||
float deltaZ = (float)(Holder.z - entityPosZ);
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashXZScaleX = deltaZ * leashLengthRatio;
|
||||
float leashXZScaleZ = deltaX * leashLengthRatio;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y,leashOffsetZ);
|
||||
VertexConsumer vertexconsumer = bufferSource.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix4f = poseStack.last().pose();
|
||||
|
||||
for (int i = 0; i <= 24; i++) {
|
||||
addVertexPair(
|
||||
vertexconsumer,
|
||||
matrix4f,
|
||||
deltaX,
|
||||
deltaY,
|
||||
deltaZ,
|
||||
leashState.startBlockLight,
|
||||
leashState.endBlockLight,
|
||||
leashState.startSkyLight,
|
||||
leashState.endSkyLight,
|
||||
0.025F,
|
||||
0.025F,
|
||||
leashXZScaleX,
|
||||
leashXZScaleZ,
|
||||
i,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
for (int j = 24; j >= 0; j--) {
|
||||
addVertexPair(
|
||||
vertexconsumer,
|
||||
matrix4f,
|
||||
deltaX,
|
||||
deltaY,
|
||||
deltaZ,
|
||||
leashState.startBlockLight,
|
||||
leashState.endBlockLight,
|
||||
leashState.startSkyLight,
|
||||
leashState.endSkyLight,
|
||||
0.025F,
|
||||
0.0F,
|
||||
leashXZScaleX,
|
||||
leashXZScaleZ,
|
||||
j,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
protected static void addVertexPair(
|
||||
VertexConsumer buffer,
|
||||
Matrix4f pose,
|
||||
float startX,
|
||||
float startY,
|
||||
float startZ,
|
||||
int entityBlockLight,
|
||||
int holderBlockLight,
|
||||
int entitySkyLight,
|
||||
int holderSkyLight,
|
||||
float yOffset,
|
||||
float dy,
|
||||
float dx,
|
||||
float dz,
|
||||
int index,
|
||||
boolean reverse
|
||||
) {
|
||||
float f = (float)index / 24.0F;
|
||||
int i = (int)Mth.lerp(f, (float)entityBlockLight, (float)holderBlockLight);
|
||||
int j = (int)Mth.lerp(f, (float)entitySkyLight, (float)holderSkyLight);
|
||||
int k = LightTexture.pack(i, j);
|
||||
float f1 = index % 2 == (reverse ? 1 : 0) ? 0.7F : 1.0F;
|
||||
float f2 = 0.5F * f1;
|
||||
float f3 = 0.4F * f1;
|
||||
float f4 = 0.3F * f1;
|
||||
float f5 = startX * f;
|
||||
float f6 = startY > 0.0F ? startY * f * f : startY - startY * (1.0F - f) * (1.0F - f);
|
||||
float f7 = startZ * f;
|
||||
buffer.addVertex(pose, f5 - dx, f6 + dy, f7 + dz).setColor(f2, f3, f4, 1.0F).setLight(k);
|
||||
buffer.addVertex(pose, f5 + dx, f6 + yOffset - dy, f7 - dz).setColor(f2, f3, f4, 1.0F).setLight(k);
|
||||
}
|
||||
public static <E extends Entity> void renderLeashForCamera(
|
||||
Camera camera,
|
||||
float partialTick,
|
||||
PoseStack poseStack,
|
||||
MultiBufferSource bufferSource,
|
||||
E leashHolder,
|
||||
Vec3 holderOffset
|
||||
) {
|
||||
|
||||
poseStack.pushPose();
|
||||
// Logger.logger.info("eyeHeight{}", camera.getEntity().getEyeHeight());
|
||||
// 获得绳索持有者的位置
|
||||
Vec3 leashHolderPosition = leashHolder.getRopeHoldPosition(partialTick).add(holderOffset);
|
||||
|
||||
// 获取当前观察的实体
|
||||
Entity cameraEntity = camera.getEntity();
|
||||
|
||||
// 计算实体的朝向角度(弧度)
|
||||
double entityRotationAngleRadians = (double)(cameraEntity.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0)) + (Math.PI / 2);
|
||||
|
||||
// 计算实体的绳索偏移,此处add偏移让渲染拴绳显示在玩家头部下(大约在脖子处
|
||||
Vec3 cameraEntityLeashOffset = cameraEntity.getLeashOffset(partialTick).add(0, -0.2, -0.5);
|
||||
double leashOffsetX = Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.z + Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
double leashOffsetZ = Math.sin(entityRotationAngleRadians) * cameraEntityLeashOffset.z - Math.cos(entityRotationAngleRadians) * cameraEntityLeashOffset.x;
|
||||
|
||||
// 计算实体当前的实际位置
|
||||
double entityPosX = Mth.lerp(partialTick, cameraEntity.xo, cameraEntity.getX()) + leashOffsetX;
|
||||
double entityPosY = Mth.lerp(partialTick, cameraEntity.yo, cameraEntity.getY()) + cameraEntityLeashOffset.y;
|
||||
double entityPosZ = Mth.lerp(partialTick, cameraEntity.zo, cameraEntity.getZ()) + leashOffsetZ;
|
||||
|
||||
// 在当前变换矩阵上应用偏移
|
||||
poseStack.translate(leashOffsetX, cameraEntityLeashOffset.y , leashOffsetZ);
|
||||
|
||||
// 计算绳索的相对位置差
|
||||
float deltaX = (float)(leashHolderPosition.x - entityPosX);
|
||||
float deltaY = (float)(leashHolderPosition.y - entityPosY);
|
||||
float deltaZ = (float)(leashHolderPosition.z - entityPosZ);
|
||||
|
||||
// 获取顶点消费者,用于绘制绳索
|
||||
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.leash());
|
||||
Matrix4f matrix = poseStack.last().pose();
|
||||
|
||||
// 计算比例因子,用于调节绳索的粗细
|
||||
float leashLengthRatio = Mth.invSqrt(deltaX * deltaX + deltaZ * deltaZ) * 0.025F / 2.0F;
|
||||
float leashXZScaleX = deltaZ * leashLengthRatio;
|
||||
float leashXZScaleZ = deltaX * leashLengthRatio;
|
||||
|
||||
// 获取光照信息
|
||||
BlockPos cameraEntityBlockPos = BlockPos.containing(cameraEntity.getEyePosition(partialTick));
|
||||
BlockPos leashHolderBlockPos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
|
||||
int cameraEntityBlockLightLevel = getBlockLightLevel(cameraEntity, cameraEntityBlockPos);
|
||||
int leashHolderBlockLightLevel = getBlockLightLevel(leashHolder, leashHolderBlockPos); //getBlockLightLevel(leashHolder, leashHolderBlockPos);
|
||||
int cameraEntitySkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, cameraEntityBlockPos);
|
||||
int leashHolderSkyLightLevel = cameraEntity.level().getBrightness(LightLayer.SKY, leashHolderBlockPos);
|
||||
|
||||
// 绘制绳索的上半部分
|
||||
for (int segment = 0; segment <= 24; segment++) {
|
||||
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.025F, leashXZScaleX, leashXZScaleZ, segment, false);
|
||||
}
|
||||
|
||||
// 绘制绳索的下半部分
|
||||
for (int segment = 24; segment >= 0; segment--) {
|
||||
addVertexPair(vertexConsumer, matrix, deltaX, deltaY, deltaZ, cameraEntityBlockLightLevel, leashHolderBlockLightLevel, cameraEntitySkyLightLevel, leashHolderSkyLightLevel, 0.025F, 0.0F, leashXZScaleX, leashXZScaleZ, segment, true);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
public static void levelRenderLeash(ClientLevel level, Camera pCamera, PoseStack poseStack, MultiBufferSource.BufferSource multibuffersource$buffersource) {
|
||||
for(Entity entity : level.entitiesForRendering()) {
|
||||
//对于玩家实体拴绳渲染(从第一人称视角)
|
||||
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
|
||||
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.options.getCameraType().isFirstPerson()) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
if(leashDataFromEntityData == null) continue;
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
if(delayedLeashInfo != null) {
|
||||
float partialTickTime = pCamera.getPartialTickTime();
|
||||
Vec3 position = pCamera.getPosition();
|
||||
double dX = Mth.lerp(partialTickTime, abstractClientPlayer.xOld, abstractClientPlayer.getX()) - position.x;
|
||||
double dY = Mth.lerp(partialTickTime, abstractClientPlayer.yOld, abstractClientPlayer.getY()) - position.y;
|
||||
double dZ = Mth.lerp(partialTickTime, abstractClientPlayer.zOld, abstractClientPlayer.getZ()) - position.z;
|
||||
Vec3 vec3 = getRenderOffset(entity, partialTickTime);
|
||||
double dX_ = dX + vec3.x();
|
||||
double dY_ = dY + vec3.y();
|
||||
double dZ_ = dZ + vec3.z();
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(dX_, dY_, dZ_);
|
||||
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()), Vec3.ZERO);
|
||||
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
||||
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
||||
if (playerByUUID != null) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID, Vec3.ZERO);
|
||||
} else {
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * LeashedPlayer.M1() * LeashedPlayer.M2();
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
abstractClientPlayer.getX() - MaxLeashLength,
|
||||
abstractClientPlayer.getY() - MaxLeashLength,
|
||||
abstractClientPlayer.getZ() - MaxLeashLength,
|
||||
abstractClientPlayer.getX() + MaxLeashLength,
|
||||
abstractClientPlayer.getY() + MaxLeashLength,
|
||||
abstractClientPlayer.getZ() + MaxLeashLength
|
||||
)
|
||||
);
|
||||
Entity holder = null;
|
||||
for (Entity entity_ : entities) {
|
||||
if(entity_.getUUID().equals(delayedLeashInfo.left().get())) {
|
||||
holder = entity_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (holder != null) {
|
||||
if(holder instanceof LeashRopeArrow) {
|
||||
renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3吗?
|
||||
}
|
||||
else renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, Vec3.ZERO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static Vec3 getRenderOffset(Entity entity, float partialTickTime) {
|
||||
Vec3 ret = Vec3.ZERO;
|
||||
if(entity.isPassenger()
|
||||
&& entity.getVehicle() instanceof AbstractMinecart abstractminecart
|
||||
&& abstractminecart.getBehavior() instanceof NewMinecartBehavior newminecartbehavior
|
||||
&& newminecartbehavior.cartHasPosRotLerp()
|
||||
) {
|
||||
double d2 = Mth.lerp(partialTickTime, abstractminecart.xOld, abstractminecart.getX());
|
||||
double d0 = Mth.lerp(partialTickTime, abstractminecart.yOld, abstractminecart.getY());
|
||||
double d1 = Mth.lerp(partialTickTime, abstractminecart.zOld, abstractminecart.getZ());
|
||||
ret = newminecartbehavior.getCartLerpPosition(partialTickTime).subtract(new Vec3(d2, d0, d1));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void createPlayerLeashState(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, float partialTick) {
|
||||
Leashable.LeashData leashDataFromEntityData = ((PlayerLeashable) abstractClientPlayer).getLeashDataFromEntityData();
|
||||
Leashable.LeashData leashData = ((PlayerLeashable) abstractClientPlayer).getLeashData();
|
||||
PlayerRenderState playerRs = (PlayerRenderState)playerRenderState;
|
||||
if (leashDataFromEntityData != null) {
|
||||
Entity leashHolder = leashDataFromEntityData.leashHolder;
|
||||
Either<UUID, BlockPos> delayedLeashInfo = leashDataFromEntityData.delayedLeashInfo;
|
||||
PlayerLeashState playerLeashState = new PlayerLeashState();
|
||||
if (delayedLeashInfo != null) {
|
||||
createPlayerLeashState_(abstractClientPlayer, playerRenderState, leashDataFromEntityData, delayedLeashInfo, playerLeashState, partialTick);
|
||||
BlockPos blockpos1 = BlockPos.containing(abstractClientPlayer.getEyePosition(partialTick));
|
||||
playerLeashState.startBlockLight = getBlockLightLevel(abstractClientPlayer, blockpos1);
|
||||
playerLeashState.startSkyLight = abstractClientPlayer.level().getBrightness(LightLayer.SKY, blockpos1);
|
||||
} else if(leashHolder != null) {
|
||||
createPlayerLeashState__(abstractClientPlayer, playerRenderState, leashHolder, playerLeashState, partialTick);
|
||||
} else {
|
||||
playerRenderState.setPlayerLeashState(null);
|
||||
}
|
||||
} else if(leashData != null) {
|
||||
playerRs.leashState = null;
|
||||
Entity leashHolder = ((PlayerLeashable) abstractClientPlayer).getLeashHolder();
|
||||
PlayerLeashState playerLeashState = playerRenderState.getPlayerLeashState();
|
||||
if (leashHolder != null & playerLeashState != null) {
|
||||
float f = leashHolder.getPreciseBodyRotation(partialTick) * (float) (Math.PI / 180.0);
|
||||
Vec3 vec3 = abstractClientPlayer.getLeashOffset(partialTick).yRot(-f);
|
||||
BlockPos blockpos1 = BlockPos.containing(abstractClientPlayer.getEyePosition(partialTick));
|
||||
BlockPos blockpos = BlockPos.containing(leashHolder.getEyePosition(partialTick));
|
||||
playerLeashState.vanilaLeashState = new EntityRenderState.LeashState();
|
||||
|
||||
EntityRenderState.LeashState entityrenderstate$leashstate = playerLeashState.vanilaLeashState;
|
||||
entityrenderstate$leashstate.offset = vec3;
|
||||
entityrenderstate$leashstate.start = abstractClientPlayer.getPosition(partialTick).add(vec3);
|
||||
entityrenderstate$leashstate.end = leashHolder.getRopeHoldPosition(partialTick);
|
||||
entityrenderstate$leashstate.startBlockLight = getBlockLightLevel(abstractClientPlayer, blockpos1);
|
||||
entityrenderstate$leashstate.endBlockLight = getBlockLightLevel(leashHolder, blockpos);
|
||||
entityrenderstate$leashstate.startSkyLight = abstractClientPlayer.level().getBrightness(LightLayer.SKY, blockpos1);
|
||||
entityrenderstate$leashstate.endSkyLight = abstractClientPlayer.level().getBrightness(LightLayer.SKY, blockpos);
|
||||
} else {
|
||||
playerRenderState.setPlayerLeashState(null);
|
||||
}
|
||||
} else {
|
||||
playerRenderState.setPlayerLeashState(null);
|
||||
}
|
||||
}
|
||||
private static <T extends Entity> int getBlockLightLevel(T entity, BlockPos pos) {
|
||||
return entity.isOnFire() ? 15 : entity.level().getBrightness(LightLayer.BLOCK, pos);
|
||||
}
|
||||
private static int getBlockLightLevel(Level level, BlockPos pos) {
|
||||
return level.getBrightness(LightLayer.BLOCK, pos);
|
||||
}
|
||||
|
||||
|
||||
private static void createPlayerLeashState__(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, Entity leashHolder, PlayerLeashState playerLeashState, float partialTick) {
|
||||
playerLeashState.pos = leashHolder.position().add(0.0, leashHolder.getEyeHeight() * 0.6, -0.2);
|
||||
playerLeashState.o = abstractClientPlayer.getPosition(partialTick);
|
||||
playerLeashState.yRotO = abstractClientPlayer.yRotO;
|
||||
playerLeashState.yRot = abstractClientPlayer.getYRot();
|
||||
playerLeashState.eyeHeight = abstractClientPlayer.getEyeHeight();
|
||||
playerRenderState.setPlayerLeashState(playerLeashState);
|
||||
}
|
||||
|
||||
private static void createPlayerLeashState_(AbstractClientPlayer abstractClientPlayer, IPlayerRenderStateExtension playerRenderState, Leashable.LeashData leashDataFromEntityData, Either<UUID, BlockPos> delayedLeashInfo, PlayerLeashState playerLeashState, float partialTick) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ClientLevel level = mc.level;
|
||||
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
||||
assert level != null;
|
||||
playerLeashState.pos = delayedLeashInfo.right().get().getCenter();
|
||||
playerLeashState.endBlockLight = getBlockLightLevel(level, delayedLeashInfo.right().get());
|
||||
playerLeashState.endSkyLight = level.getBrightness(LightLayer.SKY, delayedLeashInfo.right().get());
|
||||
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
||||
assert level != null;
|
||||
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
||||
if (playerByUUID != null) {
|
||||
playerLeashState.pos = playerByUUID.position().add(0.0, playerByUUID.getEyeHeight() * 0.6, 0);
|
||||
} else {
|
||||
double breakDistanceTime = (leashDataFromEntityData.leashHolder instanceof LeashRopeArrow) ? LeashedPlayer.M1() * LeashedPlayer.M2() : LeashedPlayer.M1();
|
||||
double MaxLeashLength = ((ILivingEntityExtension) abstractClientPlayer).getLeashLength() * breakDistanceTime;
|
||||
List<Entity> entities = level.getEntities(
|
||||
null,
|
||||
new AABB(
|
||||
abstractClientPlayer.getX() - MaxLeashLength * LeashedPlayer.M2(),
|
||||
abstractClientPlayer.getY() - MaxLeashLength * LeashedPlayer.M2(),
|
||||
abstractClientPlayer.getZ() - MaxLeashLength * LeashedPlayer.M2(),
|
||||
abstractClientPlayer.getX() + MaxLeashLength * LeashedPlayer.M2(),
|
||||
abstractClientPlayer.getY() + MaxLeashLength * LeashedPlayer.M2(),
|
||||
abstractClientPlayer.getZ() + MaxLeashLength * LeashedPlayer.M2()
|
||||
)
|
||||
);
|
||||
Entity holder = null;
|
||||
for (Entity entity_ : entities) {
|
||||
if (entity_.getUUID().equals(delayedLeashInfo.left().get())) {
|
||||
holder = entity_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (holder != null) {
|
||||
playerLeashState.pos = holder.position().add(0.0, holder.getEyeHeight() * 0.6, 0);//TODO: 待擴展Vec3
|
||||
playerLeashState.endBlockLight = getBlockLightLevel(level, holder.getOnPos());
|
||||
playerLeashState.endSkyLight = level.getBrightness(LightLayer.SKY, holder.getOnPos());
|
||||
} else {
|
||||
playerLeashState.pos = abstractClientPlayer.position();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
playerLeashState.o = abstractClientPlayer.getPosition(partialTick);
|
||||
playerLeashState.yRotO = abstractClientPlayer.yRotO;
|
||||
playerLeashState.yRot = abstractClientPlayer.getYRot();
|
||||
playerLeashState.eyeHeight = abstractClientPlayer.getEyeHeight();
|
||||
|
||||
playerRenderState.setPlayerLeashState(playerLeashState);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer;
|
||||
|
||||
import net.minecraft.client.renderer.entity.state.EntityRenderState;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PlayerLeashState {
|
||||
public Vec3 o, pos, offset;
|
||||
public float yRotO, yRot;
|
||||
public float eyeHeight;
|
||||
public int startBlockLight;
|
||||
public int endBlockLight;
|
||||
public int startSkyLight;
|
||||
public int endSkyLight;
|
||||
@Nullable
|
||||
public EntityRenderState.LeashState vanilaLeashState;
|
||||
|
||||
public float getPreciseBodyRotation(float pPartialTick) {
|
||||
return Mth.lerp(pPartialTick, this.yRotO, this.yRot);
|
||||
}
|
||||
|
||||
|
||||
public PlayerLeashState() {
|
||||
this.offset = Vec3.ZERO;
|
||||
this.o = Vec3.ZERO;
|
||||
this.pos = Vec3.ZERO;
|
||||
this.yRot = 0.0f;
|
||||
this.yRotO = 0.0f;
|
||||
this.eyeHeight = 0.0f;
|
||||
this.startBlockLight = 0;
|
||||
this.endBlockLight = 0;
|
||||
this.startSkyLight = 15;
|
||||
this.endSkyLight = 15;
|
||||
this.vanilaLeashState = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer;
|
||||
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PlayerSlotItemLayerState {
|
||||
public LivingEntity entity;
|
||||
public PlayerSlotItemLayerState(LivingEntity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.entities;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import com.r3944realms.leashedplayer.modInterface.IPlayerRenderStateExtension;
|
||||
import net.minecraft.client.model.EntityModel;
|
||||
import net.minecraft.client.model.PlayerModel;
|
||||
import net.minecraft.client.renderer.ItemInHandRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.RenderLayerParent;
|
||||
import net.minecraft.client.renderer.entity.layers.RenderLayer;
|
||||
import net.minecraft.client.renderer.entity.state.PlayerRenderState;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChestItemLayerRenderer<S extends PlayerRenderState, M extends EntityModel<S>> extends RenderLayer<S, M> {
|
||||
|
||||
private final ItemInHandRenderer heldItemRenderer;
|
||||
|
||||
public ChestItemLayerRenderer(RenderLayerParent<S, M> context, ItemInHandRenderer heldItemRenderer) {
|
||||
super(context);
|
||||
this.heldItemRenderer = heldItemRenderer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(@NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, @NotNull S renderState, float yRot, float xRot) {
|
||||
ItemDisplayContext mode = ItemDisplayContext.FIXED;
|
||||
IPlayerRenderStateExtension rs = (IPlayerRenderStateExtension) renderState;
|
||||
LivingEntity entity = rs.getPlayerSlotItemLayerState().entity;
|
||||
ItemStack chestStack = entity.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (!chestStack.isEmpty()) {
|
||||
if (!(entity.getEquipmentSlotForItem(chestStack).equals(EquipmentSlot.CHEST))) {
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).body.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.translate(0, -0.24f, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.scale(1.01f, 1.01f, 1.01f);
|
||||
poseStack.translate(0, -1 / 4f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).rightArm.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.scale(2/3f, 2/3f, 2/3f);
|
||||
poseStack.translate(-1/12f, 0, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.scale(0.99f, 0.99f, 0.99f);
|
||||
poseStack.translate(0, -1/2f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).leftArm.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.scale(2/3f, 2/3f, 2/3f);
|
||||
poseStack.translate(1/12f, 0, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.scale(0.99f, 0.99f, 0.99f);
|
||||
poseStack.translate(0, -1/2f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
ItemStack legsStack = entity.getItemBySlot(EquipmentSlot.LEGS);
|
||||
if (!legsStack.isEmpty()) {
|
||||
if (!(entity.getEquipmentSlotForItem(legsStack).equals(EquipmentSlot.LEGS))) {
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).rightLeg.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.scale(2/3f, 2/3f, 2/3f);
|
||||
poseStack.translate(0, -1/6f, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.scale(1.01f, 1.01f, 1.01f);
|
||||
poseStack.translate(0, -1/3f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).leftLeg.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.scale(2/3f, 2/3f, 2/3f);
|
||||
poseStack.translate(0, -1/6f, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.scale(1.01f, 1.01f, 1.01f);
|
||||
poseStack.translate(0, -1/3f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
ItemStack feetStack = entity.getItemBySlot(EquipmentSlot.FEET);
|
||||
if (!feetStack.isEmpty()) {
|
||||
if (!(entity.getEquipmentSlotForItem(feetStack).equals(EquipmentSlot.FEET))) {
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).rightLeg.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.scale(0.75f, 0.75f, 0.75f);
|
||||
poseStack.translate(0, -0.8f, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, feetStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
poseStack.pushPose();
|
||||
((PlayerModel) this.getParentModel()).leftLeg.translateAndRotate(poseStack);
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180));
|
||||
poseStack.scale(0.75f, 0.75f, 0.75f);
|
||||
poseStack.translate(0, -0.8f, 0);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, feetStack, mode, poseStack, bufferSource, packedLight);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,30 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.entities;
|
||||
package com.r3944realms.leashedplayer.client.renderer.entities;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.LeashRopeArrow;
|
||||
import net.minecraft.client.renderer.entity.ArrowRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.client.renderer.entity.state.ArrowRenderState;
|
||||
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 LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow> {
|
||||
public class LeashRopeArrowRenderer extends ArrowRenderer<LeashRopeArrow, ArrowRenderState> {
|
||||
public static final ResourceLocation LEASH_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/leash_rope_arrow.png");
|
||||
public LeashRopeArrowRenderer(EntityRendererProvider.Context pContext) {
|
||||
super(pContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ResourceLocation getTextureLocation(@NotNull LeashRopeArrow pEntity) {
|
||||
public @NotNull ArrowRenderState createRenderState() {
|
||||
return new ArrowRenderState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ResourceLocation getTextureLocation(@NotNull ArrowRenderState arrowRenderState) {
|
||||
return LEASH_ROPE_ARROW;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,23 +1,31 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.entities;
|
||||
package com.r3944realms.leashedplayer.client.renderer.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.client.renderer.entity.state.ArrowRenderState;
|
||||
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 class SpectralLeashRopeArrowRenderer extends ArrowRenderer<SpectralLeashRopeArrow, ArrowRenderState> {
|
||||
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) {
|
||||
public @NotNull ArrowRenderState createRenderState() {
|
||||
return new ArrowRenderState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ResourceLocation getTextureLocation(@NotNull ArrowRenderState arrowRenderState) {
|
||||
return SPECTRAL_LEASH_ROPE_ARROW;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.gui;
|
||||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.gui;
|
||||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.gui;
|
||||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.gui;
|
||||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.gui;
|
||||
package com.r3944realms.leashedplayer.client.renderer.gui;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.client.processBar.IProcessBar;
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.item;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import com.r3944realms.leashedplayer.client.renderer.item.properties.conditionalRange.ConditionalRangeItemModelProperties;
|
||||
import com.r3944realms.leashedplayer.client.renderer.item.properties.conditionalRange.ConditionalRangeItemModelProperty;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.item.ItemModel;
|
||||
import net.minecraft.client.renderer.item.ItemModelResolver;
|
||||
import net.minecraft.client.renderer.item.ItemModels;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ConditionalRangeItemModel implements ItemModel {
|
||||
private final ConditionalRangeItemModelProperty property;
|
||||
private final float scale;
|
||||
private final float[] onTrueThresholds;
|
||||
private final float[] onFalseThresholds;
|
||||
private final ItemModel[] onTrueModels;
|
||||
private final ItemModel[] onFalseModels;
|
||||
private final ItemModel fallback;
|
||||
public ConditionalRangeItemModel(ConditionalRangeItemModelProperty property, float scale, float[] onTrueThresholds, float[] onFalseThresholds, ItemModel[] onTrueModels, ItemModel[] onFalseModels, ItemModel fallback) {
|
||||
this.property = property;
|
||||
this.scale = scale;
|
||||
this.onTrueThresholds = onTrueThresholds;
|
||||
this.onFalseThresholds = onFalseThresholds;
|
||||
this.onTrueModels = onTrueModels;
|
||||
this.onFalseModels = onFalseModels;
|
||||
this.fallback = fallback;
|
||||
}
|
||||
private static int lastIndexLessOrEqual(float[] thresholds, float value) {
|
||||
if (thresholds.length < 16) {
|
||||
for (int k = 0; k < thresholds.length; k++) {
|
||||
if (thresholds[k] > value) {
|
||||
return k - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return thresholds.length - 1;
|
||||
} else {
|
||||
int i = Arrays.binarySearch(thresholds, value);
|
||||
if (i < 0) {
|
||||
int j = ~i;
|
||||
return j - 1;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void update(@NotNull ItemStackRenderState renderState, @NotNull ItemStack stack, @NotNull ItemModelResolver itemModelResolver, @NotNull ItemDisplayContext displayContext, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) {
|
||||
ConditionalRangeItemModelProperty.ConditionalRangeData conditionalRangeData = this.property.get(stack, level, entity, seed, displayContext);
|
||||
float f = conditionalRangeData.floatValue() * this.scale;
|
||||
boolean b = conditionalRangeData.boolValue();
|
||||
ItemModel itemModel;
|
||||
if(Float.isNaN(f)) {
|
||||
itemModel = this.fallback; ;
|
||||
} else {
|
||||
int i;
|
||||
if (b) {
|
||||
i = lastIndexLessOrEqual(this.onTrueThresholds, f);
|
||||
}
|
||||
else {
|
||||
i = lastIndexLessOrEqual(this.onFalseThresholds, f);
|
||||
}
|
||||
itemModel = i == -1 ? this.fallback : b ? onTrueModels[i] : onFalseModels[i];
|
||||
|
||||
}
|
||||
itemModel.update(renderState, stack, itemModelResolver, displayContext, level, entity, seed);
|
||||
}
|
||||
public record Entry(float threshold, ItemModel.Unbaked model) {
|
||||
public static final Codec<Entry> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(
|
||||
Codec.FLOAT.fieldOf("threshold").forGetter(Entry::threshold),
|
||||
ItemModels.CODEC.fieldOf("model").forGetter(Entry::model)
|
||||
).apply(instance, Entry::new)
|
||||
);
|
||||
public static final Comparator<Entry> BY_THRESHOLD = Comparator.comparingDouble(Entry::threshold);
|
||||
}
|
||||
public record Unbaked(
|
||||
ConditionalRangeItemModelProperty property, float scale, List<Entry> trueModels, List<Entry> falseModels, Optional<ItemModel.Unbaked> fallback
|
||||
) implements ItemModel.Unbaked {
|
||||
public static final MapCodec<Unbaked> MAP_CODEC = RecordCodecBuilder.mapCodec(
|
||||
instance -> instance.group(
|
||||
ConditionalRangeItemModelProperties.MAP_CODEC.forGetter(Unbaked::property),
|
||||
Codec.FLOAT.optionalFieldOf("scale", 1.0F).forGetter(Unbaked::scale),
|
||||
Entry.CODEC.listOf().fieldOf("trueModels").forGetter(Unbaked::trueModels),
|
||||
Entry.CODEC.listOf().fieldOf("falseModels").forGetter(Unbaked::falseModels),
|
||||
ItemModels.CODEC.optionalFieldOf("fallback").forGetter(Unbaked::fallback)
|
||||
).apply(instance, Unbaked::new)
|
||||
);
|
||||
@Override
|
||||
public @NotNull MapCodec<? extends ItemModel.Unbaked> type() {
|
||||
return MAP_CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemModel bake(@NotNull BakingContext context) {
|
||||
float[] floatArrA = new float[this.trueModels.size()];
|
||||
float[] floatArrB = new float[this.falseModels.size()];
|
||||
ItemModel[] itemModelArrA = new ItemModel[this.trueModels.size()];
|
||||
ItemModel[] itemModelArrB = new ItemModel[this.falseModels.size()];
|
||||
List<Entry> trueModelList = new ArrayList<>(this.trueModels);
|
||||
List<Entry> falseModelList = new ArrayList<>(this.falseModels);
|
||||
trueModelList.sort(Entry.BY_THRESHOLD);
|
||||
falseModelList.sort(Entry.BY_THRESHOLD);
|
||||
for (int i = 0; i < trueModelList.size(); i++) {
|
||||
Entry rangeselectitemmodel$entry = trueModelList.get(i);
|
||||
floatArrA[i] = rangeselectitemmodel$entry.threshold;
|
||||
itemModelArrA[i] = rangeselectitemmodel$entry.model.bake(context);
|
||||
}
|
||||
for (int i = 0; i < falseModels.size(); i++) {
|
||||
Entry rangeselectitemmodel$entry = falseModelList.get(i);
|
||||
floatArrB[i] = rangeselectitemmodel$entry.threshold;
|
||||
itemModelArrB[i] = rangeselectitemmodel$entry.model.bake(context);
|
||||
}
|
||||
ItemModel itemmodel = this.fallback.map(p_387030_ -> p_387030_.bake(context)).orElse(context.missingItemModel());
|
||||
return new ConditionalRangeItemModel(this.property, this.scale, floatArrA, floatArrB, itemModelArrA, itemModelArrB, itemmodel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveDependencies(@NotNull Resolver resolver) {
|
||||
this.fallback.ifPresent(itemModel -> itemModel.resolveDependencies(resolver));
|
||||
this.trueModels.forEach(entry -> entry.model.resolveDependencies(resolver));
|
||||
this.falseModels.forEach(entry -> entry.model.resolveDependencies(resolver));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.item.properties.conditional;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow;
|
||||
import com.r3944realms.leashedplayer.extend.CrossbowItem$ChargeTypeExtend;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.item.properties.select.SelectItemModelProperty;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.component.ChargedProjectiles;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public record ChargeExtend() implements SelectItemModelProperty<CrossbowItem$ChargeTypeExtend> {
|
||||
public static Codec<CrossbowItem$ChargeTypeExtend> CODEC = CrossbowItem$ChargeTypeExtend.CODEC;
|
||||
public static Type<ChargeExtend, CrossbowItem$ChargeTypeExtend> TYPE = Type.create(
|
||||
MapCodec.unit(new ChargeExtend()), CODEC
|
||||
);
|
||||
@Override
|
||||
public @NotNull CrossbowItem$ChargeTypeExtend get(@NotNull ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, @NotNull ItemDisplayContext displayContext) {
|
||||
ChargedProjectiles chargedprojectiles = stack.get(DataComponents.CHARGED_PROJECTILES);
|
||||
if(chargedprojectiles == null || chargedprojectiles.isEmpty()) {
|
||||
return CrossbowItem$ChargeTypeExtend.NONE;
|
||||
} else {
|
||||
return ILeashRopeArrow.isLeashRopeArrow(stack, entity) ? CrossbowItem$ChargeTypeExtend.LEASH_ROPE_ARROW :
|
||||
chargedprojectiles.contains(Items.FIREWORK_ROCKET) ? CrossbowItem$ChargeTypeExtend.ROCKET : CrossbowItem$ChargeTypeExtend.ARROW;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Codec<CrossbowItem$ChargeTypeExtend> valueCodec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends SelectItemModelProperty<CrossbowItem$ChargeTypeExtend>, CrossbowItem$ChargeTypeExtend> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.item.properties.conditionalRange;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.r3944realms.leashedplayer.content.items.type.ILeashRopeArrow;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.item.properties.numeric.UseDuration;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record BowPull() implements ConditionalRangeItemModelProperty {
|
||||
public static final MapCodec<BowPull> MAP_CODEC = MapCodec.unit(new BowPull());
|
||||
@Override
|
||||
public ConditionalRangeData get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext displayContext) {
|
||||
|
||||
if (entity != null && entity.getUseItem() == stack) {
|
||||
return ConditionalRangeData.create(ILeashRopeArrow.isLeashRopeArrow(stack, entity), (float)UseDuration.useDuration(stack, entity));
|
||||
}
|
||||
else return ConditionalRangeData.create(false, 0.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapCodec<? extends ConditionalRangeItemModelProperty> type() {
|
||||
return MAP_CODEC;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.item.properties.conditionalRange;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ConditionalRangeItemModelProperties {
|
||||
private static final ExtraCodecs.LateBoundIdMapper<ResourceLocation, MapCodec<? extends ConditionalRangeItemModelProperty>> ID_MAPPER = new ExtraCodecs.LateBoundIdMapper<>();
|
||||
public static final MapCodec<ConditionalRangeItemModelProperty> MAP_CODEC = ID_MAPPER.codec(ResourceLocation.CODEC)
|
||||
.dispatchMap("property", ConditionalRangeItemModelProperty::type, mapCodec -> mapCodec);
|
||||
public static void bootstrap() {
|
||||
ID_MAPPER.put(ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "bow_pull"), BowPull.MAP_CODEC);
|
||||
net.neoforged.fml.ModLoader.postEvent(new com.r3944realms.leashedplayer.content.events.RegisterConditionalRangeItemPropertyEvent(ID_MAPPER));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.r3944realms.leashedplayer.client.renderer.item.properties.conditionalRange;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ConditionalRangeItemModelProperty {
|
||||
ConditionalRangeData get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext displayContext);
|
||||
|
||||
MapCodec<? extends ConditionalRangeItemModelProperty> type();
|
||||
record ConditionalRangeData(boolean boolValue, float floatValue) {
|
||||
public static ConditionalRangeData create(boolean boolValue, float floatValue) {
|
||||
return new ConditionalRangeData(boolValue, floatValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.entities;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import net.minecraft.client.model.EntityModel;
|
||||
import net.minecraft.client.model.PlayerModel;
|
||||
import net.minecraft.client.renderer.ItemInHandRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.RenderLayerParent;
|
||||
import net.minecraft.client.renderer.entity.layers.RenderLayer;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChestItemLayerRenderer<T extends LivingEntity, M extends EntityModel<T>> extends RenderLayer<T, M> {
|
||||
|
||||
private final ItemInHandRenderer heldItemRenderer;
|
||||
|
||||
public ChestItemLayerRenderer(RenderLayerParent<T, M> context, ItemInHandRenderer heldItemRenderer) {
|
||||
super(context);
|
||||
this.heldItemRenderer = heldItemRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(@NotNull PoseStack matrices, @NotNull MultiBufferSource vertexConsumers, int light, @NotNull T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
ItemDisplayContext mode = ItemDisplayContext.FIXED;
|
||||
ItemStack chestStack = entity.getItemBySlot(EquipmentSlot.CHEST);
|
||||
if (!chestStack.isEmpty()) {
|
||||
if (!(entity.getEquipmentSlotForItem(chestStack).equals(EquipmentSlot.CHEST))) {
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).body.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.translate(0, -1 / 4f, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.scale(1.01f, 1.01f, 1.01f);
|
||||
matrices.translate(0, -1 / 4f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).rightArm.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.scale(2/3f, 2/3f, 2/3f);
|
||||
matrices.translate(-1/12f, 0, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.scale(0.99f, 0.99f, 0.99f);
|
||||
matrices.translate(0, -1/2f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).leftArm.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.scale(2/3f, 2/3f, 2/3f);
|
||||
matrices.translate(1/12f, 0, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.scale(0.99f, 0.99f, 0.99f);
|
||||
matrices.translate(0, -1/2f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, chestStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
}
|
||||
}
|
||||
ItemStack legsStack = entity.getItemBySlot(EquipmentSlot.LEGS);
|
||||
if (!legsStack.isEmpty()) {
|
||||
if (!(entity.getEquipmentSlotForItem(legsStack).equals(EquipmentSlot.LEGS))) {
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).rightLeg.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.scale(2/3f, 2/3f, 2/3f);
|
||||
matrices.translate(0, -1/6f, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.scale(1.01f, 1.01f, 1.01f);
|
||||
matrices.translate(0, -1/3f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).leftLeg.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.scale(2/3f, 2/3f, 2/3f);
|
||||
matrices.translate(0, -1/6f, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.scale(1.01f, 1.01f, 1.01f);
|
||||
matrices.translate(0, -1/3f, 0);
|
||||
this.heldItemRenderer.renderItem(entity, legsStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
}
|
||||
}
|
||||
ItemStack feetStack = entity.getItemBySlot(EquipmentSlot.FEET);
|
||||
if (!feetStack.isEmpty()) {
|
||||
if (!(entity.getEquipmentSlotForItem(feetStack).equals(EquipmentSlot.FEET))) {
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).rightLeg.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.scale(0.75f, 0.75f, 0.75f);
|
||||
matrices.translate(0, -0.8f, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, feetStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
matrices.pushPose();
|
||||
((PlayerModel<?>) this.getParentModel()).leftLeg.translateAndRotate(matrices);
|
||||
matrices.mulPose(Axis.XP.rotationDegrees(180));
|
||||
matrices.scale(0.75f, 0.75f, 0.75f);
|
||||
matrices.translate(0, -0.8f, 0);
|
||||
matrices.mulPose(Axis.YP.rotationDegrees(180));
|
||||
this.heldItemRenderer.renderItem(entity, feetStack, mode, false, matrices, vertexConsumers, light);
|
||||
matrices.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.entities;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.r3944realms.leashedplayer.content.entities.LittlePlayer;
|
||||
import net.minecraft.client.model.HumanoidModel;
|
||||
import net.minecraft.client.model.PlayerModel;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.client.renderer.entity.HumanoidMobRenderer;
|
||||
import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.item.CrossbowItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.UseAnim;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class KidPlayerRenderer extends HumanoidMobRenderer<LittlePlayer, PlayerModel<LittlePlayer>> {
|
||||
|
||||
|
||||
public static @NotNull KidPlayerRenderer create(@NotNull EntityRendererProvider.Context pContext) {
|
||||
if (pContext instanceof PlayerContext pc) {
|
||||
return new KidPlayerRenderer(pc);
|
||||
}
|
||||
return new KidPlayerRenderer(new PlayerContext(pContext, true));
|
||||
}
|
||||
|
||||
public static class PlayerContext extends EntityRendererProvider.Context {
|
||||
boolean isUseSlimModel;
|
||||
public PlayerContext(EntityRendererProvider.Context pContext, boolean pIsSlimModel) {
|
||||
super(pContext.getEntityRenderDispatcher(), pContext.getItemRenderer(), pContext.getBlockRenderDispatcher(), pContext.getItemInHandRenderer(), pContext.getResourceManager(), pContext.getModelSet(), pContext.getFont());
|
||||
this.isUseSlimModel = pIsSlimModel;
|
||||
}
|
||||
|
||||
public boolean isUseSlimModel() {
|
||||
return isUseSlimModel;
|
||||
}
|
||||
|
||||
}
|
||||
public KidPlayerRenderer(PlayerContext pContext) {
|
||||
super(pContext, new PlayerModel<>(pContext.bakeLayer(pContext.isUseSlimModel() ? ModelLayers.PLAYER_SLIM : ModelLayers.PLAYER), pContext.isUseSlimModel()), 0.5F);
|
||||
this.addLayer(new HumanoidArmorLayer<>(this,
|
||||
new HumanoidModel<>(pContext.bakeLayer(ModelLayers.PLAYER_INNER_ARMOR)),
|
||||
new HumanoidModel<>(pContext.bakeLayer(ModelLayers.PLAYER_OUTER_ARMOR)),
|
||||
pContext.getModelManager()
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull ResourceLocation getTextureLocation(@NotNull LittlePlayer pEntity) {
|
||||
return pEntity.getSkin().texture();
|
||||
}
|
||||
public void render(@NotNull LittlePlayer companion, float companionYaw, float pPartialTicks, @NotNull PoseStack pMatrixStack,
|
||||
@NotNull MultiBufferSource pBuffer, int pPackedLight) {
|
||||
this.setModelProperties(companion);
|
||||
|
||||
super.render(companion, companionYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight);
|
||||
}
|
||||
private void setModelProperties(LittlePlayer companion) {
|
||||
PlayerModel<LittlePlayer> companionModel = this.getModel();
|
||||
|
||||
HumanoidModel.ArmPose humanoidmodel$armpose = getArmPose(companion, InteractionHand.MAIN_HAND);
|
||||
HumanoidModel.ArmPose humanoidmodel$armpose1 = getArmPose(companion, InteractionHand.OFF_HAND);
|
||||
|
||||
if (companion.getMainArm() == HumanoidArm.RIGHT) {
|
||||
companionModel.rightArmPose = humanoidmodel$armpose;
|
||||
companionModel.leftArmPose = humanoidmodel$armpose1;
|
||||
} else {
|
||||
companionModel.rightArmPose = humanoidmodel$armpose1;
|
||||
companionModel.leftArmPose = humanoidmodel$armpose;
|
||||
}
|
||||
}
|
||||
private static HumanoidModel.ArmPose getArmPose(LittlePlayer companion, InteractionHand hand) {
|
||||
ItemStack itemstack = companion.getItemInHand(hand);
|
||||
if (itemstack.isEmpty()) {
|
||||
return HumanoidModel.ArmPose.EMPTY;
|
||||
} else {
|
||||
if (companion.getUsedItemHand() == hand && companion.getUseItemRemainingTicks() > 0) {
|
||||
UseAnim useanim = itemstack.getUseAnimation();
|
||||
|
||||
if (useanim == UseAnim.BOW) {
|
||||
return HumanoidModel.ArmPose.BOW_AND_ARROW;
|
||||
}
|
||||
|
||||
if (useanim == UseAnim.CROSSBOW && hand == companion.getUsedItemHand()) {
|
||||
return HumanoidModel.ArmPose.CROSSBOW_CHARGE;
|
||||
}
|
||||
} else if (!companion.swinging && itemstack.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemstack)) {
|
||||
return HumanoidModel.ArmPose.CROSSBOW_HOLD;
|
||||
}
|
||||
|
||||
return HumanoidModel.ArmPose.ITEM;
|
||||
}
|
||||
}
|
||||
protected void scale(@NotNull LittlePlayer player, PoseStack pPoseStack, float pPartialTickTime) {
|
||||
float f = 0.9375F;
|
||||
pPoseStack.scale(f, f, f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.client.renders.entities;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.content.entities.NestleRopeArrow;
|
||||
import net.minecraft.client.renderer.entity.ArrowRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class NestleRopeArrowRenderer extends ArrowRenderer<NestleRopeArrow> {
|
||||
public static final ResourceLocation NESTLE_ROPE_ARROW = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "textures/entity/projectiles/nestle_rope_arrow.png");
|
||||
|
||||
public NestleRopeArrowRenderer(EntityRendererProvider.Context pContext) {
|
||||
super(pContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ResourceLocation getTextureLocation(@NotNull NestleRopeArrow pEntity) {
|
||||
return NESTLE_ROPE_ARROW;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.compat.jei;
|
||||
|
||||
import com.r3944realms.leashedplayer.LeashedPlayer;
|
||||
import com.r3944realms.leashedplayer.compat.jei.common.PotionSubtypeInterpreter;
|
||||
import com.r3944realms.leashedplayer.compat.jei.crafting.TippedLeashArrowRecipeMaker;
|
||||
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.constants.RecipeTypes;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import mezz.jei.api.registration.ISubtypeRegistration;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@JeiPlugin
|
||||
public class JEIPlugin implements IModPlugin {
|
||||
private static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(LeashedPlayer.MOD_ID, "jei_plugin");
|
||||
@Override
|
||||
public @NotNull ResourceLocation getPluginUid() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerItemSubtypes(ISubtypeRegistration registration) {
|
||||
registration.registerSubtypeInterpreter(ModItemRegister.TIPPED_LEASH_ROPE_ARROW.get(), PotionSubtypeInterpreter.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(@NotNull IRecipeRegistration registration) {
|
||||
registration.addRecipes(RecipeTypes.CRAFTING, TippedLeashArrowRecipeMaker.createRecipes());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package com.r3944realms.leashedplayer.compat.jei.common;
|
||||
|
||||
import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter;
|
||||
import mezz.jei.api.ingredients.subtypes.UidContext;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PotionSubtypeInterpreter implements IIngredientSubtypeInterpreter<ItemStack> {
|
||||
public static final PotionSubtypeInterpreter INSTANCE = new PotionSubtypeInterpreter();
|
||||
|
||||
private PotionSubtypeInterpreter() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String apply(ItemStack itemStack, @NotNull UidContext context) {
|
||||
if (itemStack.getComponentsPatch().isEmpty()) {
|
||||
return IIngredientSubtypeInterpreter.NONE;
|
||||
}
|
||||
PotionContents contents = itemStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
||||
String itemDescriptionId = itemStack.getItem().getDescriptionId();
|
||||
String potionEffectId = contents.potion().map(Holder::getRegisteredName).orElse("none");
|
||||
return itemDescriptionId + ".effect_id." + potionEffectId;
|
||||
}
|
||||
}
|
||||