From e22f181f4136b724a83919a456b16ccd2616a79b Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 23 May 2024 19:59:56 +0100 Subject: [PATCH] Fixed rendering of multi-segment blocks --- .../client/render/EntityDisguiseRenderer.java | 34 ++++++++++++---- .../entity/behaviour/EntityAppearance.java | 26 +++++++----- .../behaviour/FallingBlockBehaviour.java | 40 ++++++++++--------- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java index 74137b58..142edfc9 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/EntityDisguiseRenderer.java @@ -9,15 +9,18 @@ import com.minelittlepony.unicopia.entity.behaviour.Disguise; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.mixin.MixinBlockEntity; +import net.minecraft.block.BlockRenderType; import net.minecraft.block.entity.BlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderer; +import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; +import net.minecraft.entity.FallingBlockEntity; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -49,11 +52,11 @@ class EntityDisguiseRenderer { } render(ve, e, x, y, z, fireTicks, tickDelta, matrices, vertices, light); - ve.getAttachments().forEach(ee -> { - PehkUtil.copyScale(pony.asEntity(), ee); - Vec3d difference = ee.getPos().subtract(e.getPos()); - render(ve, ee, x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertices, light); - PehkUtil.clearScale(ee); + ve.getAttachments().forEach(attachment -> { + PehkUtil.copyScale(pony.asEntity(), attachment.entity()); + Vec3d difference = attachment.entity().getPos().subtract(e.getPos()); + render(ve, attachment.entity(), x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertices, light); + PehkUtil.clearScale(attachment.entity()); }); matrices.push(); @@ -66,6 +69,7 @@ class EntityDisguiseRenderer { return true; } + @SuppressWarnings("deprecation") private void render(EntityAppearance ve, Entity e, double x, double y, double z, int fireTicks, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { @@ -84,6 +88,9 @@ class EntityDisguiseRenderer { BlockEntityRenderer r = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(blockEntity); if (r != null) { ((MixinBlockEntity)blockEntity).setPos(e.getBlockPos()); + if (e instanceof FallingBlockEntity fbe) { + blockEntity.setCachedState(fbe.getBlockState()); + } blockEntity.setWorld(e.getWorld()); matrices.push(); matrices.translate(x, y, z); @@ -92,8 +99,11 @@ class EntityDisguiseRenderer { r.render(blockEntity, 1, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV); matrices.pop(); - blockEntity.setWorld(null); - return; + + BlockRenderType type = blockEntity.getCachedState().getRenderType(); + if (type == BlockRenderType.ENTITYBLOCK_ANIMATED) { + return; + } } } @@ -104,7 +114,15 @@ class EntityDisguiseRenderer { } e.setFireTicks(fireTicks); - delegate.client.getEntityRenderDispatcher().render(e, x, y, z, e.getYaw(), tickDelta, matrices, vertexConsumers, light); + + EntityRenderDispatcher dispatcher = delegate.client.getEntityRenderDispatcher(); + if (e instanceof FallingBlockEntity) { + dispatcher.setRenderShadows(false); + } + dispatcher.render(e, x, y, z, e.getYaw(), tickDelta, matrices, vertexConsumers, light); + if (e instanceof FallingBlockEntity) { + dispatcher.setRenderShadows(true); + } e.setFireTicks(0); if (model != null) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java index fd70ab27..acba1d32 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java @@ -48,21 +48,22 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.ShulkerBulletEntity; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider, EntityCollisions.ComplexCollidable { private static final Optional BLOCK_HEIGHT = Optional.of(0.5F); @NotNull - private String entityId = ""; + private transient String entityId = ""; @Nullable - private Entity entity; + private transient Entity entity; @Nullable - private BlockEntity blockEntity; + private transient BlockEntity blockEntity; - private List attachments = new ArrayList<>(); + private transient List attachments = new ArrayList<>(); private Optional dimensions = Optional.empty(); @@ -71,7 +72,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi * This is not serialized, so should only be used for server-side data. */ @Nullable - private NbtCompound tag; + private transient NbtCompound tag; @Nullable private NbtCompound entityNbt; @@ -86,16 +87,21 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi return blockEntity; } - public List getAttachments() { + public List getAttachments() { return attachments; } - public void addBlockEntity(BlockEntity blockEntity) { + public record Attachment(Vec3d offset, Entity entity) {} + + public void setBlockEntity(@Nullable BlockEntity blockEntity) { + if (this.blockEntity != null) { + this.blockEntity.markRemoved(); + } this.blockEntity = blockEntity; } - public void attachExtraEntity(Entity entity) { - attachments.add(entity); + public void attachExtraEntity(Vec3d offset, Entity entity) { + attachments.add(new Attachment(offset, entity)); } public void setAppearance(@Nullable Entity entity) { @@ -384,7 +390,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi @Override public void getCollissionShapes(ShapeContext context, Consumer output) { EntityCollisions.getCollissionShapes(getAppearance(), context, output); - getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e, context, output)); + getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e.entity(), context, output)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java index c3f7e05a..1ed88f8f 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/FallingBlockBehaviour.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.entity.behaviour; -import java.util.List; import java.util.Optional; import com.minelittlepony.unicopia.ability.magic.Caster; @@ -11,27 +10,26 @@ import com.minelittlepony.unicopia.mixin.MixinFallingBlock; import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity; import com.minelittlepony.unicopia.util.Tickable; +import net.minecraft.block.BedBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; -import net.minecraft.block.DoorBlock; import net.minecraft.block.FallingBlock; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.ChestBlockEntity; import net.minecraft.block.entity.EnderChestBlockEntity; +import net.minecraft.block.enums.BedPart; +import net.minecraft.block.enums.ChestType; import net.minecraft.block.enums.DoubleBlockHalf; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.state.property.Properties; -import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; public class FallingBlockBehaviour extends EntityBehaviour { - - private static final Vec3d UP = Vec3d.of(Direction.UP.getVector()); - private static final Optional FULL_BLOCK = Optional.of(EntityDimensions.changing(0.6F, 0.9F)); @Override @@ -70,22 +68,27 @@ public class FallingBlockBehaviour extends EntityBehaviour { public FallingBlockEntity onCreate(FallingBlockEntity entity, EntityAppearance context, boolean replaceOld) { super.onCreate(entity, context, replaceOld); - BlockState state = entity.getBlockState(); + BlockState state = entity.getBlockState() + .withIfExists(Properties.CHEST_TYPE, ChestType.SINGLE) + .withIfExists(Properties.BED_PART, BedPart.HEAD) + .withIfExists(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER); Block block = state.getBlock(); + context.setBlockEntity(block instanceof BlockEntityProvider bep ? bep.createBlockEntity(entity.getBlockPos(), state) : null); - if (block instanceof BlockEntityProvider bep) { - context.addBlockEntity(bep.createBlockEntity(entity.getBlockPos(), state)); + if (state.contains(Properties.BED_PART)) { + Vec3i offset = BedBlock.getOppositePartDirection(state).getVector(); + BlockState foot = state.with(Properties.BED_PART, BedPart.FOOT); + context.attachExtraEntity(Vec3d.of(offset), configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX() + offset.getX(), entity.getY() + offset.getY(), entity.getZ() + offset.getZ(), foot), block)); } - if (block instanceof DoorBlock) { - BlockState lowerState = state.with(DoorBlock.HALF, DoubleBlockHalf.LOWER); - BlockState upperState = state.with(DoorBlock.HALF, DoubleBlockHalf.UPPER); - - context.attachExtraEntity(configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY(), entity.getZ(), upperState), block)); - - return configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY() + 1, entity.getZ(), lowerState), block); + if (state.contains(Properties.DOUBLE_BLOCK_HALF)) { + BlockState upperState = state.with(Properties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER); + context.attachExtraEntity(new Vec3d(0, 1, 0), configure(MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY() + 1, entity.getZ(), upperState), block)); } + if (state != entity.getBlockState()) { + entity = MixinFallingBlockEntity.createInstance(entity.getWorld(), entity.getX(), entity.getY(), entity.getZ(), state); + } return configure(entity, block); } @@ -117,9 +120,8 @@ public class FallingBlockBehaviour extends EntityBehaviour { be.setWorld(null); } - List attachments = disguise.getAttachments(); - if (attachments.size() > 0) { - copyBaseAttributes(source.asEntity(), attachments.get(0), UP); + for (var attachment : disguise.getAttachments()) { + copyBaseAttributes(source.asEntity(), attachment.entity(), attachment.offset()); } } }