package nova.microblock.operation; import nova.core.block.Block; import nova.core.entity.Entity; import nova.core.util.Direction; import nova.core.util.RayTracer; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.microblock.NovaMicroblock; import nova.microblock.injection.component.ContainerCollider; import nova.microblock.micro.Microblock; import nova.microblock.micro.MicroblockContainer; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.Optional; import java.util.stream.Stream; /** * Removes a container * * @author Calclavia */ public class ContainerRemove extends ContainerOperation { private final Vector3D localPos; public ContainerRemove(World world, Vector3D globalPos, Vector3D localPos) { super(world, globalPos); this.localPos = localPos; } public static void interactEventHandler(Block block, Block.RemoveEvent evt) { if (evt.entity.isPresent()) { Entity player = evt.entity.get(); if (block.components.has(MicroblockContainer.class) && block.components.has(ContainerCollider.class)) { MicroblockContainer microblockContainer = block.components.get(MicroblockContainer.class); //Ray trace through each microblock Stream<RayTraceMicroblockResult> traces = Stream.empty(); for (Microblock microblock : microblockContainer.microblocks()) { RayTracer rayTracer = new RayTracer(player).setDistance(7); traces = Stream.concat(traces, rayTracer.rayTraceCollider(microblock.block, (pos, cuboid) -> new RayTraceMicroblockResult(pos, rayTracer.ray.origin.distance(pos), cuboid.sideOf(pos), cuboid, microblock)) ); } Optional<RayTraceMicroblockResult> result = traces.sorted().findFirst(); if (result.isPresent()) { if (new ContainerRemove(block.world(), block.position(), result.get().microblock.position).operate()) { evt.result = false; } //If single player //TODO: HACKS TEMPORARY NovaMicroblock.instance.client.getPlayer().world().setBlock(block.position(), block.getFactory()); //System.out.println("client: " + MicroblockPlugin.instance.clientManager().getPlayer().world().getBlock(block.position()).get().getID()); } } } } @Override public boolean operate() { Optional<Block> opBlock = world.getBlock(globalPos); if (opBlock.isPresent()) { Block block = opBlock.get(); if (block.components.has(MicroblockContainer.class)) { MicroblockContainer microblockContainer = block.components.get(MicroblockContainer.class); if (microblockContainer.remove(localPos)) { if (microblockContainer.microblocks().size() == 0) { return false; } return true; } } //TODO: Deal withPriority multiblocks } return false; } public static class RayTraceMicroblockResult extends RayTracer.RayTraceResult { public final Microblock microblock; public RayTraceMicroblockResult(Vector3D hit, double distance, Direction side, Cuboid hitCuboid, Microblock microblock) { super(hit, distance, side, hitCuboid); this.microblock = microblock; } } }