Fixed rendering of multi-segment blocks

This commit is contained in:
Sollace 2024-05-23 19:59:56 +01:00
parent 98f612cd13
commit e22f181f41
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
3 changed files with 63 additions and 37 deletions

View file

@ -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<BlockEntity> 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,10 +99,13 @@ class EntityDisguiseRenderer {
r.render(blockEntity, 1, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV);
matrices.pop();
blockEntity.setWorld(null);
BlockRenderType type = blockEntity.getCachedState().getRenderType();
if (type == BlockRenderType.ENTITYBLOCK_ANIMATED) {
return;
}
}
}
BipedEntityModel<?> model = getBipedModel(e);
@ -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) {

View file

@ -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<Float> 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<Entity> attachments = new ArrayList<>();
private transient List<Attachment> attachments = new ArrayList<>();
private Optional<EntityDimensions> 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<Entity> getAttachments() {
public List<Attachment> 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<VoxelShape> output) {
EntityCollisions.getCollissionShapes(getAppearance(), context, output);
getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e, context, output));
getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e.entity(), context, output));
}
}

View file

@ -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<FallingBlockEntity> {
private static final Vec3d UP = Vec3d.of(Direction.UP.getVector());
private static final Optional<EntityDimensions> FULL_BLOCK = Optional.of(EntityDimensions.changing(0.6F, 0.9F));
@Override
@ -70,22 +68,27 @@ public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
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<FallingBlockEntity> {
be.setWorld(null);
}
List<Entity> 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());
}
}
}