mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-18 07:53:07 +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;
|
||||
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) {
|
||||
super(entityTypeIn, worldIn);
|
||||
prevPosInvalid = true;
|
||||
|
@ -309,6 +318,14 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
tickContraption();
|
||||
super.tick();
|
||||
|
||||
if (level.isClientSide())
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
if (!contraption.deferInvalidate)
|
||||
return;
|
||||
contraption.deferInvalidate = false;
|
||||
ContraptionRenderDispatcher.invalidate(contraption);
|
||||
});
|
||||
|
||||
if (!(level instanceof ServerLevelAccessor sl))
|
||||
return;
|
||||
|
||||
|
@ -695,7 +712,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
StructureBlockInfo info = contraption.blocks.get(localPos);
|
||||
contraption.blocks.put(localPos, new StructureBlockInfo(info.pos, newState, info.nbt));
|
||||
if (info.state != newState && !(newState.getBlock() instanceof SlidingDoorBlock))
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ContraptionRenderDispatcher.invalidate(contraption));
|
||||
contraption.deferInvalidate = true;
|
||||
contraption.invalidateColliders();
|
||||
}
|
||||
|
||||
|
@ -851,4 +868,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
return initialized;
|
||||
}
|
||||
|
||||
public boolean isAliveOrStale() {
|
||||
return isAlive() || level.isClientSide() ? staleTicks > 0 : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -151,6 +151,7 @@ public abstract class Contraption {
|
|||
public List<BlockEntity> specialRenderedTileEntities;
|
||||
|
||||
protected ContraptionWorld world;
|
||||
public boolean deferInvalidate;
|
||||
|
||||
public Contraption() {
|
||||
blocks = new HashMap<>();
|
||||
|
|
|
@ -45,10 +45,15 @@ public class ContraptionHandler {
|
|||
for (Iterator<WeakReference<AbstractContraptionEntity>> iterator = values.iterator(); iterator.hasNext();) {
|
||||
WeakReference<AbstractContraptionEntity> weakReference = iterator.next();
|
||||
AbstractContraptionEntity contraptionEntity = weakReference.get();
|
||||
if (contraptionEntity == null || !contraptionEntity.isAlive()) {
|
||||
if (contraptionEntity == null || !contraptionEntity.isAliveOrStale()) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
if (!contraptionEntity.isAlive()) {
|
||||
contraptionEntity.staleTicks--;
|
||||
continue;
|
||||
}
|
||||
|
||||
ContraptionCollider.collideEntities(contraptionEntity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,11 @@ package com.simibubi.create.content.contraptions.components.structureMovement;
|
|||
|
||||
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.world.InteractionHand;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
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 {
|
||||
|
||||
|
@ -22,7 +17,7 @@ public abstract class MovingInteractionBehaviour {
|
|||
contraptionEntity.contraption.actors.remove(index);
|
||||
contraptionEntity.contraption.actors.add(index, MutablePair.of(info, ctx));
|
||||
if (contraptionEntity.level.isClientSide)
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> invalidate(contraptionEntity.contraption));
|
||||
contraptionEntity.contraption.deferInvalidate = true;
|
||||
}
|
||||
|
||||
protected void setContraptionBlockData(AbstractContraptionEntity contraptionEntity, BlockPos pos,
|
||||
|
@ -32,11 +27,6 @@ public abstract class MovingInteractionBehaviour {
|
|||
contraptionEntity.setBlock(pos, info);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected void invalidate(Contraption contraption) {
|
||||
ContraptionRenderDispatcher.invalidate(contraption);
|
||||
}
|
||||
|
||||
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||
AbstractContraptionEntity contraptionEntity) {
|
||||
return true;
|
||||
|
|
|
@ -26,7 +26,7 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
|
|||
double cameraZ) {
|
||||
if (entity.getContraption() == null)
|
||||
return false;
|
||||
if (!entity.isAlive())
|
||||
if (!entity.isAliveOrStale())
|
||||
return false;
|
||||
if (!entity.isReadyForRender())
|
||||
return false;
|
||||
|
|
|
@ -26,7 +26,7 @@ public class ContraptionRenderInfo {
|
|||
}
|
||||
|
||||
public boolean isDead() {
|
||||
return !contraption.entity.isAlive();
|
||||
return !contraption.entity.isAliveOrStale();
|
||||
}
|
||||
|
||||
public void beginFrame(BeginFrameEvent event) {
|
||||
|
@ -34,11 +34,13 @@ public class ContraptionRenderInfo {
|
|||
|
||||
AbstractContraptionEntity entity = contraption.entity;
|
||||
|
||||
visible = event.getFrustum().isVisible(entity.getBoundingBoxForCulling().inflate(2));
|
||||
visible = event.getFrustum()
|
||||
.isVisible(entity.getBoundingBoxForCulling()
|
||||
.inflate(2));
|
||||
}
|
||||
|
||||
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)
|
||||
private void invalidate(CarriageContraptionEntity entity) {
|
||||
ContraptionRenderDispatcher.invalidate(entity.getContraption());
|
||||
entity.getContraption().deferInvalidate = true;
|
||||
entity.updateRenderedPortalCutoff();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue