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();
// Don't move if held by processing (client)
if (onClient && currentItem.locked)
if (world.isRemote && currentItem.locked)
continue;
// 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 UUID id;
public ElementLink(Class<T> elementClass) {
this(elementClass, UUID.randomUUID());
}
public ElementLink(Class<T> elementClass, UUID id) {
this.elementClass = elementClass;
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.logistics.block.funnel.FunnelTileEntity;
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.ParrotElement;
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.TileEntityDataInstruction;
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 net.minecraft.block.BlockState;
@ -265,8 +269,7 @@ public class SceneBuilder {
public void hideSection(Selection selection, Direction fadeOutDirection) {
WorldSectionElement worldSectionElement = new WorldSectionElement(selection);
ElementLink<WorldSectionElement> elementLink =
new ElementLink<>(WorldSectionElement.class, UUID.randomUUID());
ElementLink<WorldSectionElement> elementLink = new ElementLink<>(WorldSectionElement.class);
addInstruction(scene -> {
scene.getBaseWorldSection()
@ -285,8 +288,7 @@ public class SceneBuilder {
public ElementLink<WorldSectionElement> makeSectionIndependent(Selection selection) {
WorldSectionElement worldSectionElement = new WorldSectionElement(selection);
ElementLink<WorldSectionElement> elementLink =
new ElementLink<>(WorldSectionElement.class, UUID.randomUUID());
ElementLink<WorldSectionElement> elementLink = new ElementLink<>(WorldSectionElement.class);
addInstruction(scene -> {
scene.getBaseWorldSection()
@ -327,30 +329,64 @@ public class SceneBuilder {
addInstruction(scene -> scene.forEachWorldEntity(entityClass, entityCallBack));
}
public void createEntity(Function<World, Entity> factory) {
addInstruction(scene -> scene.getWorld()
.addEntity(factory.apply(scene.getWorld())));
public ElementLink<EntityElement> createEntity(Function<World, Entity> factory) {
ElementLink<EntityElement> link = new ElementLink<>(EntityElement.class, UUID.randomUUID());
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) {
createEntity(world -> {
public ElementLink<EntityElement> createItemEntity(Vec3d location, Vec3d motion, ItemStack stack) {
return createEntity(world -> {
ItemEntity itemEntity = new ItemEntity(world, location.x, location.y, location.z, stack);
itemEntity.setMotion(motion);
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 -> {
TileEntity tileEntity = scene.getWorld()
.getTileEntity(beltLocation);
PonderWorld world = scene.getWorld();
TileEntity tileEntity = world.getTileEntity(beltLocation);
if (!(tileEntity instanceof BeltTileEntity))
return;
BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity;
DirectBeltInputBehaviour behaviour = beltTileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE);
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);
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) {

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.SceneBuildingUtil;
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.WorldSectionElement;
import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter;
@ -366,9 +367,17 @@ public class DebugScenes {
}
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 -> {
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;
import java.util.UUID;
import com.simibubi.create.foundation.ponder.ElementLink;
import com.simibubi.create.foundation.ponder.PonderScene;
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) {
elementLink = new ElementLink<>(getElementClass(), UUID.randomUUID());
elementLink = new ElementLink<>(getElementClass());
scene.linkElement(element, elementLink);
return elementLink;
}