mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-13 15:56:38 +01:00
Mind the gap
- Fixed trapdoors and doors causing a contraption to flicker when activated - Hastily added a few ticks of extra time before a contraption is discarded on the client to close the time gap between entity and chunk render
This commit is contained in:
parent
d1570736c5
commit
56ec2f127c
7 changed files with 44 additions and 25 deletions
|
@ -90,6 +90,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
protected boolean prevPosInvalid;
|
protected boolean prevPosInvalid;
|
||||||
private boolean skipActorStop;
|
private boolean skipActorStop;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* staleTicks are a band-aid to prevent a frame or two of missing blocks between
|
||||||
|
* contraption discard and off-thread block placement on disassembly
|
||||||
|
*
|
||||||
|
* FIXME this timeout should be longer but then also cancelled early based on a
|
||||||
|
* chunk rebuild listener
|
||||||
|
*/
|
||||||
|
public int staleTicks = 3;
|
||||||
|
|
||||||
public AbstractContraptionEntity(EntityType<?> entityTypeIn, Level worldIn) {
|
public AbstractContraptionEntity(EntityType<?> entityTypeIn, Level worldIn) {
|
||||||
super(entityTypeIn, worldIn);
|
super(entityTypeIn, worldIn);
|
||||||
prevPosInvalid = true;
|
prevPosInvalid = true;
|
||||||
|
@ -168,7 +177,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
callback.accept(passenger, transformedVector.x,
|
callback.accept(passenger, transformedVector.x,
|
||||||
transformedVector.y + SeatEntity.getCustomEntitySeatOffset(passenger) - 1 / 8f, transformedVector.z);
|
transformedVector.y + SeatEntity.getCustomEntitySeatOffset(passenger) - 1 / 8f, transformedVector.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Vec3 getPassengerPosition(Entity passenger, float partialTicks) {
|
protected Vec3 getPassengerPosition(Entity passenger, float partialTicks) {
|
||||||
UUID id = passenger.getUUID();
|
UUID id = passenger.getUUID();
|
||||||
if (passenger instanceof OrientedContraptionEntity) {
|
if (passenger instanceof OrientedContraptionEntity) {
|
||||||
|
@ -309,6 +318,14 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
tickContraption();
|
tickContraption();
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
|
if (level.isClientSide())
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
if (!contraption.deferInvalidate)
|
||||||
|
return;
|
||||||
|
contraption.deferInvalidate = false;
|
||||||
|
ContraptionRenderDispatcher.invalidate(contraption);
|
||||||
|
});
|
||||||
|
|
||||||
if (!(level instanceof ServerLevelAccessor sl))
|
if (!(level instanceof ServerLevelAccessor sl))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -695,7 +712,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
StructureBlockInfo info = contraption.blocks.get(localPos);
|
StructureBlockInfo info = contraption.blocks.get(localPos);
|
||||||
contraption.blocks.put(localPos, new StructureBlockInfo(info.pos, newState, info.nbt));
|
contraption.blocks.put(localPos, new StructureBlockInfo(info.pos, newState, info.nbt));
|
||||||
if (info.state != newState && !(newState.getBlock() instanceof SlidingDoorBlock))
|
if (info.state != newState && !(newState.getBlock() instanceof SlidingDoorBlock))
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ContraptionRenderDispatcher.invalidate(contraption));
|
contraption.deferInvalidate = true;
|
||||||
contraption.invalidateColliders();
|
contraption.invalidateColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,4 +868,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
return initialized;
|
return initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAliveOrStale() {
|
||||||
|
return isAlive() || level.isClientSide() ? staleTicks > 0 : false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,7 @@ public abstract class Contraption {
|
||||||
public List<BlockEntity> specialRenderedTileEntities;
|
public List<BlockEntity> specialRenderedTileEntities;
|
||||||
|
|
||||||
protected ContraptionWorld world;
|
protected ContraptionWorld world;
|
||||||
|
public boolean deferInvalidate;
|
||||||
|
|
||||||
public Contraption() {
|
public Contraption() {
|
||||||
blocks = new HashMap<>();
|
blocks = new HashMap<>();
|
||||||
|
|
|
@ -45,10 +45,15 @@ public class ContraptionHandler {
|
||||||
for (Iterator<WeakReference<AbstractContraptionEntity>> iterator = values.iterator(); iterator.hasNext();) {
|
for (Iterator<WeakReference<AbstractContraptionEntity>> iterator = values.iterator(); iterator.hasNext();) {
|
||||||
WeakReference<AbstractContraptionEntity> weakReference = iterator.next();
|
WeakReference<AbstractContraptionEntity> weakReference = iterator.next();
|
||||||
AbstractContraptionEntity contraptionEntity = weakReference.get();
|
AbstractContraptionEntity contraptionEntity = weakReference.get();
|
||||||
if (contraptionEntity == null || !contraptionEntity.isAlive()) {
|
if (contraptionEntity == null || !contraptionEntity.isAliveOrStale()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!contraptionEntity.isAlive()) {
|
||||||
|
contraptionEntity.staleTicks--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ContraptionCollider.collideEntities(contraptionEntity);
|
ContraptionCollider.collideEntities(contraptionEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,11 @@ package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
|
||||||
|
|
||||||
public abstract class MovingInteractionBehaviour {
|
public abstract class MovingInteractionBehaviour {
|
||||||
|
|
||||||
|
@ -22,7 +17,7 @@ public abstract class MovingInteractionBehaviour {
|
||||||
contraptionEntity.contraption.actors.remove(index);
|
contraptionEntity.contraption.actors.remove(index);
|
||||||
contraptionEntity.contraption.actors.add(index, MutablePair.of(info, ctx));
|
contraptionEntity.contraption.actors.add(index, MutablePair.of(info, ctx));
|
||||||
if (contraptionEntity.level.isClientSide)
|
if (contraptionEntity.level.isClientSide)
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> invalidate(contraptionEntity.contraption));
|
contraptionEntity.contraption.deferInvalidate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setContraptionBlockData(AbstractContraptionEntity contraptionEntity, BlockPos pos,
|
protected void setContraptionBlockData(AbstractContraptionEntity contraptionEntity, BlockPos pos,
|
||||||
|
@ -32,11 +27,6 @@ public abstract class MovingInteractionBehaviour {
|
||||||
contraptionEntity.setBlock(pos, info);
|
contraptionEntity.setBlock(pos, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
|
||||||
protected void invalidate(Contraption contraption) {
|
|
||||||
ContraptionRenderDispatcher.invalidate(contraption);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||||
AbstractContraptionEntity contraptionEntity) {
|
AbstractContraptionEntity contraptionEntity) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
|
||||||
double cameraZ) {
|
double cameraZ) {
|
||||||
if (entity.getContraption() == null)
|
if (entity.getContraption() == null)
|
||||||
return false;
|
return false;
|
||||||
if (!entity.isAlive())
|
if (!entity.isAliveOrStale())
|
||||||
return false;
|
return false;
|
||||||
if (!entity.isReadyForRender())
|
if (!entity.isReadyForRender())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,24 +21,26 @@ public class ContraptionRenderInfo {
|
||||||
this.renderWorld = renderWorld;
|
this.renderWorld = renderWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEntityId() {
|
public int getEntityId() {
|
||||||
return contraption.entity.getId();
|
return contraption.entity.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDead() {
|
public boolean isDead() {
|
||||||
return !contraption.entity.isAlive();
|
return !contraption.entity.isAliveOrStale();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginFrame(BeginFrameEvent event) {
|
public void beginFrame(BeginFrameEvent event) {
|
||||||
matrices.clear();
|
matrices.clear();
|
||||||
|
|
||||||
AbstractContraptionEntity entity = contraption.entity;
|
AbstractContraptionEntity entity = contraption.entity;
|
||||||
|
|
||||||
visible = event.getFrustum().isVisible(entity.getBoundingBoxForCulling().inflate(2));
|
visible = event.getFrustum()
|
||||||
|
.isVisible(entity.getBoundingBoxForCulling()
|
||||||
|
.inflate(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVisible() {
|
public boolean isVisible() {
|
||||||
return visible && contraption.entity.isAlive() && contraption.entity.isReadyForRender();
|
return visible && contraption.entity.isAliveOrStale() && contraption.entity.isReadyForRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -762,7 +762,7 @@ public class Carriage {
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
private void invalidate(CarriageContraptionEntity entity) {
|
private void invalidate(CarriageContraptionEntity entity) {
|
||||||
ContraptionRenderDispatcher.invalidate(entity.getContraption());
|
entity.getContraption().deferInvalidate = true;
|
||||||
entity.updateRenderedPortalCutoff();
|
entity.updateRenderedPortalCutoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue