Desperate Control

- Belt items and item entities now support element links (albeit in a slightly limited fashion)
This commit is contained in:
simibubi 2021-02-24 17:48:45 +01:00
parent 9d4e52092e
commit 051a32557f
8 changed files with 134 additions and 18 deletions

View file

@ -107,7 +107,7 @@ public class BeltInventory {
movement *= ServerSpeedProvider.get(); movement *= ServerSpeedProvider.get();
// Don't move if held by processing (client) // Don't move if held by processing (client)
if (onClient && currentItem.locked) if (world.isRemote && currentItem.locked)
continue; continue;
// Don't move if other items are waiting in front // Don't move if other items are waiting in front

View file

@ -7,6 +7,10 @@ public class ElementLink<T extends PonderElement> {
private Class<T> elementClass; private Class<T> elementClass;
private UUID id; private UUID id;
public ElementLink(Class<T> elementClass) {
this(elementClass, UUID.randomUUID());
}
public ElementLink(Class<T> elementClass, UUID id) { public ElementLink(Class<T> elementClass, UUID id) {
this.elementClass = elementClass; this.elementClass = elementClass;
this.id = id; this.id = id;

View file

@ -10,6 +10,8 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity; import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity;
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
import com.simibubi.create.foundation.ponder.content.PonderPalette; import com.simibubi.create.foundation.ponder.content.PonderPalette;
import com.simibubi.create.foundation.ponder.elements.BeltItemElement;
import com.simibubi.create.foundation.ponder.elements.EntityElement;
import com.simibubi.create.foundation.ponder.elements.InputWindowElement; import com.simibubi.create.foundation.ponder.elements.InputWindowElement;
import com.simibubi.create.foundation.ponder.elements.ParrotElement; import com.simibubi.create.foundation.ponder.elements.ParrotElement;
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
@ -30,6 +32,8 @@ import com.simibubi.create.foundation.ponder.instructions.ShowInputInstruction;
import com.simibubi.create.foundation.ponder.instructions.TextInstruction; import com.simibubi.create.foundation.ponder.instructions.TextInstruction;
import com.simibubi.create.foundation.ponder.instructions.TileEntityDataInstruction; import com.simibubi.create.foundation.ponder.instructions.TileEntityDataInstruction;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -265,8 +269,7 @@ public class SceneBuilder {
public void hideSection(Selection selection, Direction fadeOutDirection) { public void hideSection(Selection selection, Direction fadeOutDirection) {
WorldSectionElement worldSectionElement = new WorldSectionElement(selection); WorldSectionElement worldSectionElement = new WorldSectionElement(selection);
ElementLink<WorldSectionElement> elementLink = ElementLink<WorldSectionElement> elementLink = new ElementLink<>(WorldSectionElement.class);
new ElementLink<>(WorldSectionElement.class, UUID.randomUUID());
addInstruction(scene -> { addInstruction(scene -> {
scene.getBaseWorldSection() scene.getBaseWorldSection()
@ -285,8 +288,7 @@ public class SceneBuilder {
public ElementLink<WorldSectionElement> makeSectionIndependent(Selection selection) { public ElementLink<WorldSectionElement> makeSectionIndependent(Selection selection) {
WorldSectionElement worldSectionElement = new WorldSectionElement(selection); WorldSectionElement worldSectionElement = new WorldSectionElement(selection);
ElementLink<WorldSectionElement> elementLink = ElementLink<WorldSectionElement> elementLink = new ElementLink<>(WorldSectionElement.class);
new ElementLink<>(WorldSectionElement.class, UUID.randomUUID());
addInstruction(scene -> { addInstruction(scene -> {
scene.getBaseWorldSection() scene.getBaseWorldSection()
@ -327,30 +329,64 @@ public class SceneBuilder {
addInstruction(scene -> scene.forEachWorldEntity(entityClass, entityCallBack)); addInstruction(scene -> scene.forEachWorldEntity(entityClass, entityCallBack));
} }
public void createEntity(Function<World, Entity> factory) { public ElementLink<EntityElement> createEntity(Function<World, Entity> factory) {
addInstruction(scene -> scene.getWorld() ElementLink<EntityElement> link = new ElementLink<>(EntityElement.class, UUID.randomUUID());
.addEntity(factory.apply(scene.getWorld()))); addInstruction(scene -> {
PonderWorld world = scene.getWorld();
Entity entity = factory.apply(world);
EntityElement handle = new EntityElement(entity);
scene.addElement(handle);
scene.linkElement(handle, link);
world.addEntity(entity);
});
return link;
} }
public void createItemEntity(Vec3d location, Vec3d motion, ItemStack stack) { public ElementLink<EntityElement> createItemEntity(Vec3d location, Vec3d motion, ItemStack stack) {
createEntity(world -> { return createEntity(world -> {
ItemEntity itemEntity = new ItemEntity(world, location.x, location.y, location.z, stack); ItemEntity itemEntity = new ItemEntity(world, location.x, location.y, location.z, stack);
itemEntity.setMotion(motion); itemEntity.setMotion(motion);
return itemEntity; return itemEntity;
}); });
} }
public void createItemOnBelt(BlockPos beltLocation, Direction insertionSide, ItemStack stack) { public ElementLink<BeltItemElement> createItemOnBelt(BlockPos beltLocation, Direction insertionSide,
ItemStack stack) {
ElementLink<BeltItemElement> link = new ElementLink<>(BeltItemElement.class);
addInstruction(scene -> { addInstruction(scene -> {
TileEntity tileEntity = scene.getWorld() PonderWorld world = scene.getWorld();
.getTileEntity(beltLocation); TileEntity tileEntity = world.getTileEntity(beltLocation);
if (!(tileEntity instanceof BeltTileEntity)) if (!(tileEntity instanceof BeltTileEntity))
return; return;
BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity; BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity;
DirectBeltInputBehaviour behaviour = beltTileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE); DirectBeltInputBehaviour behaviour = beltTileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE);
behaviour.handleInsertion(stack, insertionSide.getOpposite(), false); behaviour.handleInsertion(stack, insertionSide.getOpposite(), false);
BeltTileEntity controllerTE = beltTileEntity.getControllerTE();
if (controllerTE != null)
controllerTE.tick();
TransportedItemStackHandlerBehaviour transporter =
beltTileEntity.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
transporter.handleProcessingOnAllItems(tis -> {
BeltItemElement tracker = new BeltItemElement(tis);
scene.addElement(tracker);
scene.linkElement(tracker, link);
return TransportedResult.doNothing();
});
}); });
flapFunnels(scene.getSceneBuildingUtil().select.position(beltLocation.up()), true); flapFunnels(scene.getSceneBuildingUtil().select.position(beltLocation.up()), true);
return link;
}
public void stallBeltItem(ElementLink<BeltItemElement> link, boolean stalled) {
addInstruction(scene -> {
BeltItemElement resolve = scene.resolve(link);
if (resolve != null)
resolve.ifPresent(tis -> tis.locked = stalled);
});
} }
public void setKineticSpeed(Selection selection, float speed) { public void setKineticSpeed(Selection selection, float speed) {

View file

@ -12,6 +12,7 @@ import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry.PonderStoryBo
import com.simibubi.create.foundation.ponder.SceneBuilder; import com.simibubi.create.foundation.ponder.SceneBuilder;
import com.simibubi.create.foundation.ponder.SceneBuildingUtil; import com.simibubi.create.foundation.ponder.SceneBuildingUtil;
import com.simibubi.create.foundation.ponder.Selection; import com.simibubi.create.foundation.ponder.Selection;
import com.simibubi.create.foundation.ponder.elements.BeltItemElement;
import com.simibubi.create.foundation.ponder.elements.InputWindowElement; import com.simibubi.create.foundation.ponder.elements.InputWindowElement;
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter; import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter;
@ -366,9 +367,17 @@ public class DebugScenes {
} }
BlockPos beltPos = util.grid.at(2, 1, 3); BlockPos beltPos = util.grid.at(2, 1, 3);
scene.world.createItemOnBelt(beltPos, Direction.EAST, copperItem.copy()); ElementLink<BeltItemElement> itemOnBelt =
scene.world.createItemOnBelt(beltPos, Direction.EAST, copperItem.copy());
scene.idle(35); scene.idle(10);
scene.world.stallBeltItem(itemOnBelt, true);
scene.idle(5);
scene.overlay.showTargetedText(PonderPalette.FAST, util.vector.topOf(2, 1, 2), "stalling",
"Belt Items can only be force-stalled on the belt they were created on.", 40);
scene.idle(45);
scene.world.stallBeltItem(itemOnBelt, false);
scene.idle(20);
scene.world.modifyEntities(ItemEntity.class, entity -> { scene.world.modifyEntities(ItemEntity.class, entity -> {
if (copperItem.isItemEqual(entity.getItem())) if (copperItem.isItemEqual(entity.getItem()))

View file

@ -0,0 +1,11 @@
package com.simibubi.create.foundation.ponder.elements;
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
public class BeltItemElement extends TrackedElement<TransportedItemStack> {
public BeltItemElement(TransportedItemStack wrapped) {
super(wrapped);
}
}

View file

@ -0,0 +1,16 @@
package com.simibubi.create.foundation.ponder.elements;
import net.minecraft.entity.Entity;
public class EntityElement extends TrackedElement<Entity> {
public EntityElement(Entity wrapped) {
super(wrapped);
}
@Override
protected boolean isStillValid(Entity element) {
return element.isAlive();
}
}

View file

@ -0,0 +1,42 @@
package com.simibubi.create.foundation.ponder.elements;
import java.lang.ref.WeakReference;
import java.util.function.Consumer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.ponder.PonderWorld;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
public abstract class TrackedElement<T> extends PonderSceneElement {
private WeakReference<T> reference;
public TrackedElement(T wrapped) {
this.reference = new WeakReference<>(wrapped);
}
public void ifPresent(Consumer<T> func) {
if (reference == null)
return;
T resolved = reference.get();
if (resolved == null)
return;
func.accept(resolved);
}
protected boolean isStillValid(T element) {
return true;
}
@Override
public void renderFirst(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms) {}
@Override
public void renderLayer(PonderWorld world, IRenderTypeBuffer buffer, RenderType type, MatrixStack ms) {}
@Override
public void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms) {}
}

View file

@ -1,7 +1,5 @@
package com.simibubi.create.foundation.ponder.instructions; package com.simibubi.create.foundation.ponder.instructions;
import java.util.UUID;
import com.simibubi.create.foundation.ponder.ElementLink; import com.simibubi.create.foundation.ponder.ElementLink;
import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderScene;
import com.simibubi.create.foundation.ponder.elements.AnimatedSceneElement; import com.simibubi.create.foundation.ponder.elements.AnimatedSceneElement;
@ -41,7 +39,7 @@ public abstract class FadeIntoSceneInstruction<T extends AnimatedSceneElement> e
} }
public ElementLink<T> createLink(PonderScene scene) { public ElementLink<T> createLink(PonderScene scene) {
elementLink = new ElementLink<>(getElementClass(), UUID.randomUUID()); elementLink = new ElementLink<>(getElementClass());
scene.linkElement(element, elementLink); scene.linkElement(element, elementLink);
return elementLink; return elementLink;
} }