版本0.0.3.0-Beta.0.1 增加: 1. 增加了新的指令 data clear 2. 添加了配置文件,方便修改本模组的部分行为 3. 增加新的内容,如拴绳箭(但是有点BUG 修改与调整: 1.调整了原语言部分错别字 2.更改了之前的逻辑【栓绳运动逻辑】 具體新内容請見 README.md 介紹
132 lines
7.6 KiB
Java
132 lines
7.6 KiB
Java
package com.r3944realms.leashedplayer.mixin.client;
|
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
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.IPlayerRendererExtension;
|
|
import com.r3944realms.leashedplayer.modInterface.PlayerLeashable;
|
|
import net.minecraft.client.Camera;
|
|
import net.minecraft.client.DeltaTracker;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.multiplayer.ClientLevel;
|
|
import net.minecraft.client.player.AbstractClientPlayer;
|
|
import net.minecraft.client.renderer.*;
|
|
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Holder;
|
|
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.phys.AABB;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.joml.Matrix4f;
|
|
import org.spongepowered.asm.mixin.Final;
|
|
import org.spongepowered.asm.mixin.Mixin;
|
|
import org.spongepowered.asm.mixin.Shadow;
|
|
import org.spongepowered.asm.mixin.injection.At;
|
|
import org.spongepowered.asm.mixin.injection.Inject;
|
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
|
|
import javax.annotation.Nullable;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
@Mixin(LevelRenderer.class)
|
|
public abstract class MixinLevelRenderer {
|
|
@Shadow
|
|
@Nullable
|
|
private ClientLevel level;
|
|
|
|
@Shadow protected abstract void renderEntity(Entity pEntity, double pCamX, double pCamY, double pCamZ, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource);
|
|
|
|
@Shadow @Final
|
|
private Minecraft minecraft;
|
|
|
|
@Shadow @Final private RenderBuffers renderBuffers;
|
|
|
|
@Inject(
|
|
method = {"renderLevel"},
|
|
at = @At(
|
|
value = "INVOKE",
|
|
target = "Lnet/minecraft/client/renderer/RenderBuffers;bufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;",
|
|
shift = At.Shift.AFTER
|
|
)
|
|
)
|
|
private void renderLevel(DeltaTracker pDeltaTracker, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pFrustumMatrix, Matrix4f pProjectionMatrix, CallbackInfo ci) {
|
|
assert this.level != null;
|
|
PoseStack poseStack = new PoseStack();
|
|
MultiBufferSource.BufferSource multibuffersource$buffersource = this.renderBuffers.bufferSource();
|
|
for(Entity entity : this.level.entitiesForRendering()) {
|
|
//对于玩家实体拴绳渲染(从第一人称视角)
|
|
if (entity instanceof AbstractClientPlayer abstractClientPlayer) {
|
|
if(!(pCamera.getEntity() instanceof AbstractClientPlayer)) continue;
|
|
Minecraft mc = Minecraft.getInstance();
|
|
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(abstractClientPlayer);
|
|
IPlayerRendererExtension playerRendererExtension = (IPlayerRendererExtension) playerRenderer;
|
|
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 = playerRenderer.getRenderOffset(abstractClientPlayer, partialTickTime);
|
|
double dX_ = dX + vec3.x();
|
|
double dY_ = dY + vec3.y();
|
|
double dZ_ = dZ + vec3.z();
|
|
poseStack.pushPose();
|
|
poseStack.translate(dX_, dY_, dZ_);
|
|
ClientLevel level = mc.level;
|
|
if (delayedLeashInfo.right().isPresent() && delayedLeashInfo.left().isEmpty()) {
|
|
assert level != null;
|
|
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, LeashFenceKnotEntity.getOrCreateKnot(level, delayedLeashInfo.right().get()));
|
|
} else if (delayedLeashInfo.right().isEmpty() && delayedLeashInfo.left().isPresent()) {
|
|
assert level != null;
|
|
|
|
Player playerByUUID = level.getPlayerByUUID(delayedLeashInfo.left().get());
|
|
if (playerByUUID != null) {
|
|
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, playerByUUID);
|
|
} else {
|
|
float 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) {
|
|
playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder, new Vec3(0.,-0.09, 0));//TODO: 待擴展Vec3
|
|
}
|
|
else playerRendererExtension.renderLeashForCamera(pCamera, partialTickTime, poseStack, multibuffersource$buffersource, holder);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|