mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 18:13:48 +01:00
Crafter connectivity
- Ported input connection handler of mechanical crafters - Added new TE behaviour for interacting with faces/edges between two blocks
This commit is contained in:
parent
4e9cd1db49
commit
67f88e666c
21 changed files with 365 additions and 222 deletions
|
@ -274,7 +274,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets\create\blockstates\powered_toggl
|
|||
c29213b77ac0c78d8979c5f6188d2b265696f9b9 assets\create\blockstates\redstone_link.json
|
||||
e2990fe70ad5d10437a376e70e167d1856277cc1 assets\create\blockstates\rope.json
|
||||
e14d5f7252105934295b4e156ec0e6d62d3d6b1c assets\create\blockstates\rope_pulley.json
|
||||
e069278f8fb93cd4bb6afab3848e6f1560a04303 assets\create\blockstates\rotation_chassis.json
|
||||
d42b4ead9307a83e2a106cfa440572575e8664b2 assets\create\blockstates\rotation_chassis.json
|
||||
cc4cf3420fa290cb844f9cf4dfdd836aa9b70500 assets\create\blockstates\rotation_speed_controller.json
|
||||
56b63575c87065bc82eb9410175c501cdf959c66 assets\create\blockstates\saw.json
|
||||
36592a6542332b35445931e8e9531adf786b63ba assets\create\blockstates\schematicannon.json
|
||||
|
@ -324,7 +324,7 @@ c60c3115fd6eeaa3a696428a87a74d184ab7d62d assets\create\blockstates\weathered_lim
|
|||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets\create\blockstates\zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets\create\blockstates\zinc_ore.json
|
||||
efa942851f247891194d2c6ecdd8724a23b05aa0 assets\create\lang\en_ud.json
|
||||
fe4c49a84016a3861a86e116df2c7603d6d4b91f assets\create\lang\en_us.json
|
||||
adb6af4aa68bac360242e78b9f883d94059b1df8 assets\create\lang\en_us.json
|
||||
846200eb548d3bfa2e77b41039de159b4b6cfb45 assets\create\models\block\acacia_window.json
|
||||
1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets\create\models\block\acacia_window_pane_noside.json
|
||||
1763ea2c9b981d187f5031ba608f3d5d3be3986a assets\create\models\block\acacia_window_pane_noside_alt.json
|
||||
|
@ -1369,7 +1369,7 @@ e4d0fe35d3441a5815bd4e1357329b284e63ecd8 data\create\loot_tables\blocks\fancy_we
|
|||
f37526c092c645045c22674dea6c7b1ec503c9c3 data\create\loot_tables\blocks\flywheel.json
|
||||
8fbd865f350c615031ec3f56eb98b51ce3008de3 data\create\loot_tables\blocks\framed_glass.json
|
||||
44c8bc7271fa367ff052bef242e1ae26fb435175 data\create\loot_tables\blocks\framed_glass_pane.json
|
||||
205f5899101262f31f5c1a88bb7d954918d08d04 data\create\loot_tables\blocks\funnel.json
|
||||
ed895ef7dcb97ad9b00d80a4fa9c331229dd532e data\create\loot_tables\blocks\funnel.json
|
||||
4063880eda871fe63a4eb549a19daecabce849e5 data\create\loot_tables\blocks\furnace_engine.json
|
||||
1070cba1c0f46cf7ebe31089f35333f5eadda6e4 data\create\loot_tables\blocks\gabbro.json
|
||||
0356e003d8890d31b89d0ad98e32aae892da71f9 data\create\loot_tables\blocks\gabbro_bricks.json
|
||||
|
@ -1419,8 +1419,8 @@ cb315814960850b5080598b89ee94c833b5048f7 data\create\loot_tables\blocks\limeston
|
|||
8db1e3f0dac48b91a4839206a7d5a88cef415fdc data\create\loot_tables\blocks\limestone_cobblestone_stairs.json
|
||||
92fb16606f289ad33860270d098fad2522b24e09 data\create\loot_tables\blocks\limestone_cobblestone_wall.json
|
||||
371115e5ceb08c07a9ab2371509960c31e0baa8a data\create\loot_tables\blocks\limestone_pillar.json
|
||||
dac789cf53b00eed34308848b5e267b7ccec090c data\create\loot_tables\blocks\linked_extractor.json
|
||||
7af5a13c9e10903b11732fbc01ae3299328216f0 data\create\loot_tables\blocks\linked_transposer.json
|
||||
205f5899101262f31f5c1a88bb7d954918d08d04 data\create\loot_tables\blocks\linked_extractor.json
|
||||
205f5899101262f31f5c1a88bb7d954918d08d04 data\create\loot_tables\blocks\linked_transposer.json
|
||||
90ddf7b5c3b61758a4ad12a1e6ef16fe6ebf7794 data\create\loot_tables\blocks\mechanical_bearing.json
|
||||
e93872a90e4f4642a003539e7db28fdacfdcd114 data\create\loot_tables\blocks\mechanical_crafter.json
|
||||
b12efeeef5682966016ce6ea2d171eecd33d9667 data\create\loot_tables\blocks\mechanical_mixer.json
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "minecraft:air"
|
||||
"name": "create:funnel"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.content.contraptions.components.actors.HarvesterBlock
|
|||
import com.simibubi.create.content.contraptions.components.actors.PloughBlock;
|
||||
import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceBlock;
|
||||
import com.simibubi.create.content.contraptions.components.clock.CuckooClockBlock;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.CrafterCTBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock;
|
||||
import com.simibubi.create.content.contraptions.components.crank.HandCrankBlock;
|
||||
import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelBlock;
|
||||
|
@ -553,6 +554,7 @@ public class AllBlocks {
|
|||
.initialProperties(SharedProperties::softMetal)
|
||||
.blockstate(BlockStateGen.horizontalBlockProvider(true))
|
||||
.transform(StressConfigDefaults.setImpact(2.0))
|
||||
.transform(CreateRegistrate.connectedTextures(new CrafterCTBehaviour()))
|
||||
.addLayer(() -> RenderType::getCutoutMipped)
|
||||
.item()
|
||||
.transform(customItemModel())
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.simibubi.create.foundation.ResourceReloadHandler;
|
|||
import com.simibubi.create.foundation.block.render.CustomBlockModels;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShifter;
|
||||
import com.simibubi.create.foundation.item.IHaveCustomItemModel;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionRenderer;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.linked.LinkRenderer;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueRenderer;
|
||||
|
@ -92,6 +93,7 @@ public class CreateClient {
|
|||
LinkRenderer.tick();
|
||||
ScrollValueRenderer.tick();
|
||||
ChassisRangeDisplay.tick();
|
||||
EdgeInteractionRenderer.tick();
|
||||
outliner.tickOutlines();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,117 +12,40 @@ import java.util.Set;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.utility.RaycastHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class ConnectedInputHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onBlockActivated(PlayerInteractEvent.RightClickBlock event) {
|
||||
World world = event.getWorld();
|
||||
BlockPos pos = event.getPos();
|
||||
PlayerEntity player = event.getPlayer();
|
||||
Hand hand = event.getHand();
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
|
||||
if (player.isSneaking())
|
||||
return;
|
||||
if (!AllItems.WRENCH.typeOf(heldItem))
|
||||
return;
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if (!AllBlocks.MECHANICAL_CRAFTER.has(blockState))
|
||||
return;
|
||||
|
||||
BlockRayTraceResult ray = RaycastHelper.rayTraceRange(world, player, 10);
|
||||
if (ray == null)
|
||||
return;
|
||||
if (ray.getFace() == blockState.get(MechanicalCrafterBlock.HORIZONTAL_FACING))
|
||||
return;
|
||||
|
||||
Direction activatedDirection = getActivatedDirection(world, pos, ray.getFace(), ray.getHitVec());
|
||||
if (activatedDirection != null) {
|
||||
if (event.getSide() != LogicalSide.CLIENT)
|
||||
toggleConnection(world, pos, pos.offset(activatedDirection));
|
||||
event.setCanceled(true);
|
||||
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ADD_ITEM, SoundCategory.BLOCKS, .25f, .1f);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Pair<Direction, Vec3d>> getConnectiveSides(World world, BlockPos pos, Direction face) {
|
||||
List<Pair<Direction, Vec3d>> sides = new ArrayList<>(6);
|
||||
public static boolean shouldConnect(World world, BlockPos pos, Direction face, Direction direction) {
|
||||
BlockState refState = world.getBlockState(pos);
|
||||
if (!refState.has(HORIZONTAL_FACING))
|
||||
return false;
|
||||
Direction refDirection = refState.get(HORIZONTAL_FACING);
|
||||
Vec3d faceOffset = new Vec3d(face.getDirectionVec()).scale(.5).add(VecHelper.getCenterOf(BlockPos.ZERO));
|
||||
|
||||
if (Block.hasSolidSide(world.getBlockState(pos.offset(face)), world, pos.offset(face), face.getOpposite()))
|
||||
return sides;
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (direction.getAxis() == face.getAxis())
|
||||
continue;
|
||||
if (direction.getAxis() == refDirection.getAxis())
|
||||
continue;
|
||||
BlockPos neighbourPos = pos.offset(direction);
|
||||
BlockState neighbour = world.getBlockState(neighbourPos);
|
||||
if (!AllBlocks.MECHANICAL_CRAFTER.has(neighbour))
|
||||
continue;
|
||||
if (refDirection != neighbour.get(HORIZONTAL_FACING))
|
||||
continue;
|
||||
if (Block.hasSolidSide(world.getBlockState(neighbourPos.offset(face)), world, neighbourPos.offset(face),
|
||||
face.getOpposite()))
|
||||
continue;
|
||||
|
||||
Vec3d bbPos = new Vec3d(direction.getDirectionVec()).scale(.5).add(faceOffset);
|
||||
sides.add(Pair.of(direction, bbPos));
|
||||
}
|
||||
|
||||
return sides;
|
||||
}
|
||||
|
||||
public static Direction getActivatedDirection(World world, BlockPos pos, Direction face, Vec3d hit) {
|
||||
Vec3d localHit = hit.subtract(pos.getX(), pos.getY(), pos.getZ());
|
||||
for (Pair<Direction, Vec3d> pair : getConnectiveSides(world, pos, face)) {
|
||||
Vec3d bbPos = pair.getRight();
|
||||
AxisAlignedBB bb = new AxisAlignedBB(bbPos, bbPos).grow(1 / 6f);
|
||||
if (bb.contains(localHit))
|
||||
return pair.getKey();
|
||||
}
|
||||
return null;
|
||||
if (direction.getAxis() == refDirection.getAxis())
|
||||
return false;
|
||||
if (face == refDirection)
|
||||
return false;
|
||||
BlockState neighbour = world.getBlockState(pos.offset(direction));
|
||||
if (!AllBlocks.MECHANICAL_CRAFTER.has(neighbour))
|
||||
return false;
|
||||
if (refDirection != neighbour.get(HORIZONTAL_FACING))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void toggleConnection(World world, BlockPos pos, BlockPos pos2) {
|
||||
|
@ -132,14 +55,17 @@ public class ConnectedInputHandler {
|
|||
if (crafter1 == null || crafter2 == null)
|
||||
return;
|
||||
|
||||
BlockPos controllerPos1 = crafter1.getPos().add(crafter1.input.data.get(0));
|
||||
BlockPos controllerPos2 = crafter2.getPos().add(crafter2.input.data.get(0));
|
||||
BlockPos controllerPos1 = crafter1.getPos()
|
||||
.add(crafter1.input.data.get(0));
|
||||
BlockPos controllerPos2 = crafter2.getPos()
|
||||
.add(crafter2.input.data.get(0));
|
||||
|
||||
if (controllerPos1.equals(controllerPos2)) {
|
||||
MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1);
|
||||
|
||||
Set<BlockPos> positions =
|
||||
controller.input.data.stream().map(l -> controllerPos1.add(l)).collect(Collectors.toSet());
|
||||
Set<BlockPos> positions = controller.input.data.stream()
|
||||
.map(l -> controllerPos1.add(l))
|
||||
.collect(Collectors.toSet());
|
||||
List<BlockPos> frontier = new LinkedList<>();
|
||||
List<BlockPos> splitGroup = new ArrayList<>();
|
||||
|
||||
|
@ -195,17 +121,20 @@ public class ConnectedInputHandler {
|
|||
}
|
||||
|
||||
public static void connectControllers(World world, MechanicalCrafterTileEntity crafter1,
|
||||
MechanicalCrafterTileEntity crafter2) {
|
||||
MechanicalCrafterTileEntity crafter2) {
|
||||
|
||||
crafter1.input.data.forEach(offset -> {
|
||||
BlockPos connectedPos = crafter1.getPos().add(offset);
|
||||
modifyAndUpdate(world, connectedPos, input -> {});
|
||||
BlockPos connectedPos = crafter1.getPos()
|
||||
.add(offset);
|
||||
modifyAndUpdate(world, connectedPos, input -> {
|
||||
});
|
||||
});
|
||||
|
||||
crafter2.input.data.forEach(offset -> {
|
||||
if (offset.equals(BlockPos.ZERO))
|
||||
return;
|
||||
BlockPos connectedPos = crafter2.getPos().add(offset);
|
||||
BlockPos connectedPos = crafter2.getPos()
|
||||
.add(offset);
|
||||
modifyAndUpdate(world, connectedPos, input -> {
|
||||
input.attachTo(crafter1.getPos(), connectedPos);
|
||||
crafter1.input.data.add(BlockPos.ZERO.subtract(input.data.get(0)));
|
||||
|
@ -251,8 +180,11 @@ public class ConnectedInputHandler {
|
|||
return input.getItemHandler(world, controllerPos);
|
||||
}
|
||||
|
||||
List<IItemHandlerModifiable> list = data.stream().map(l -> CrafterHelper.getCrafter(world, pos.add(l)))
|
||||
.filter(Predicates.notNull()).map(crafter -> crafter.inventory).collect(Collectors.toList());
|
||||
List<IItemHandlerModifiable> list = data.stream()
|
||||
.map(l -> CrafterHelper.getCrafter(world, pos.add(l)))
|
||||
.filter(Predicates.notNull())
|
||||
.map(crafter -> crafter.inventory)
|
||||
.collect(Collectors.toList());
|
||||
return new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
|
||||
}
|
||||
|
||||
|
@ -266,7 +198,8 @@ public class ConnectedInputHandler {
|
|||
public void read(CompoundNBT nbt) {
|
||||
isController = nbt.getBoolean("Controller");
|
||||
data.clear();
|
||||
nbt.getList("Data", NBT.TAG_COMPOUND).forEach(inbt -> data.add(NBTUtil.readBlockPos((CompoundNBT) inbt)));
|
||||
nbt.getList("Data", NBT.TAG_COMPOUND)
|
||||
.forEach(inbt -> data.add(NBTUtil.readBlockPos((CompoundNBT) inbt)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions.components.crafter;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult.Type;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.DrawHighlightEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class ConnectedInputRenderer {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void renderHighlight(DrawHighlightEvent event) {
|
||||
RayTraceResult target = event.getTarget();
|
||||
if (!(target instanceof BlockRayTraceResult))
|
||||
return;
|
||||
|
||||
BlockRayTraceResult result = (BlockRayTraceResult) target;
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
BlockPos pos = result.getPos();
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
PlayerEntity player = Minecraft.getInstance().player;
|
||||
ItemStack heldItem = player.getHeldItem(Hand.MAIN_HAND);
|
||||
Direction face = result.getFace();
|
||||
|
||||
if (player.isSneaking())
|
||||
return;
|
||||
if (!AllItems.WRENCH.typeOf(heldItem))
|
||||
return;
|
||||
if (!AllBlocks.MECHANICAL_CRAFTER.has(blockState))
|
||||
return;
|
||||
if (target.getType() != Type.BLOCK)
|
||||
return;
|
||||
if (face == blockState.get(MechanicalCrafterBlock.HORIZONTAL_FACING))
|
||||
return;
|
||||
|
||||
TessellatorHelper.prepareForDrawing();
|
||||
RenderSystem.translated(pos.getX(), pos.getY(), pos.getZ());
|
||||
Direction activatedDirection = ConnectedInputHandler.getActivatedDirection(world, pos, face,
|
||||
result.getHitVec());
|
||||
|
||||
for (Pair<Direction, Vec3d> pair : ConnectedInputHandler.getConnectiveSides(world, pos, face)) {
|
||||
|
||||
int zRot = face == Direction.UP ? 90 : face == Direction.DOWN ? 270 : 0;
|
||||
float yRot = AngleHelper.horizontalAngle(face.getOpposite());
|
||||
Vec3d rotation = new Vec3d(0, yRot, zRot);
|
||||
//
|
||||
// GlHelper.renderTransformed(pair.getValue(), rotation, .5f, () -> {
|
||||
//
|
||||
// String label = "Connect / Disconnect";// Lang.translate("crafter.connect");
|
||||
// AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(1/3f);
|
||||
// ValueBox box = new ValueBox(label, bb, pos);
|
||||
// box.withColors(0x018383, 0x42e6a4).offsetLabel(new Vec3d(10, 0, 0));
|
||||
// ValueBoxRenderer.renderBox(box, activatedDirection == pair.getKey());
|
||||
|
||||
// });
|
||||
}
|
||||
|
||||
TessellatorHelper.cleanUpAfterDrawing();
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import java.util.List;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.ConnectedInputHandler.ConnectedInput;
|
||||
|
@ -16,6 +17,7 @@ import com.simibubi.create.content.contraptions.components.crafter.MechanicalCra
|
|||
import com.simibubi.create.content.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InventoryManagementBehaviour.Attachments;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
@ -81,6 +83,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
|
||||
protected GroupedItems groupedItemsBeforeCraft; // for rendering on client
|
||||
private InsertingBehaviour inserting;
|
||||
private EdgeInteractionBehaviour connectivity;
|
||||
|
||||
public MechanicalCrafterTileEntity() {
|
||||
super(AllTileEntities.MECHANICAL_CRAFTER.type);
|
||||
|
@ -93,7 +96,11 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
inserting = new InsertingBehaviour(this, Attachments.toward(this::getTargetFacing));
|
||||
connectivity = new EdgeInteractionBehaviour(this, ConnectedInputHandler::toggleConnection)
|
||||
.connectivity(ConnectedInputHandler::shouldConnect)
|
||||
.require(AllItems.WRENCH.get());
|
||||
behaviours.add(inserting);
|
||||
behaviours.add(connectivity);
|
||||
}
|
||||
|
||||
public void blockChanged() {
|
||||
|
@ -153,7 +160,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
groupedItemsBeforeCraft = before;
|
||||
if (phaseBefore == Phase.EXPORTING && phase == Phase.WAITING) {
|
||||
Direction facing = getBlockState().get(MechanicalCrafterBlock.HORIZONTAL_FACING);
|
||||
Vec3d vec = new Vec3d(facing.getDirectionVec()).scale(.75).add(VecHelper.getCenterOf(pos));
|
||||
Vec3d vec = new Vec3d(facing.getDirectionVec()).scale(.75)
|
||||
.add(VecHelper.getCenterOf(pos));
|
||||
Direction targetDirection = MechanicalCrafterBlock.getTargetDirection(getBlockState());
|
||||
vec = vec.add(new Vec3d(targetDirection.getDirectionVec()).scale(1));
|
||||
world.addParticle(ParticleTypes.CRIT, vec.x, vec.y, vec.z, 0, 0, 0);
|
||||
|
@ -169,7 +177,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
phase = Phase.IDLE;
|
||||
String name = compound.getString("Phase");
|
||||
for (Phase phase : Phase.values())
|
||||
if (phase.name().equals(name))
|
||||
if (phase.name()
|
||||
.equals(name))
|
||||
this.phase = phase;
|
||||
countDown = compound.getInt("CountDown");
|
||||
covered = compound.getBoolean("Cover");
|
||||
|
@ -211,10 +220,12 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
if (result != null) {
|
||||
|
||||
List<ItemStack> containers = new ArrayList<>();
|
||||
groupedItems.grid.values().forEach(stack -> {
|
||||
if (stack.hasContainerItem())
|
||||
containers.add(stack.getContainerItem().copy());
|
||||
});
|
||||
groupedItems.grid.values()
|
||||
.forEach(stack -> {
|
||||
if (stack.hasContainerItem())
|
||||
containers.add(stack.getContainerItem()
|
||||
.copy());
|
||||
});
|
||||
|
||||
groupedItems = new GroupedItems(result);
|
||||
for (int i = 0; i < containers.size(); i++) {
|
||||
|
@ -266,9 +277,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
Direction facing = getBlockState().get(MechanicalCrafterBlock.HORIZONTAL_FACING);
|
||||
float progress = countDown / 2000f;
|
||||
Vec3d facingVec = new Vec3d(facing.getDirectionVec());
|
||||
Vec3d vec = facingVec.scale(.65).add(VecHelper.getCenterOf(pos));
|
||||
Vec3d vec = facingVec.scale(.65)
|
||||
.add(VecHelper.getCenterOf(pos));
|
||||
Vec3d offset = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f)
|
||||
.mul(VecHelper.planeByNormal(facingVec)).normalize().scale(progress * .5f).add(vec);
|
||||
.mul(VecHelper.planeByNormal(facingVec))
|
||||
.normalize()
|
||||
.scale(progress * .5f)
|
||||
.add(vec);
|
||||
if (progress > .5f)
|
||||
world.addParticle(ParticleTypes.CRIT, offset.x, offset.y, offset.z, 0, 0, 0);
|
||||
|
||||
|
@ -279,11 +294,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Vec3d randVec = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f)
|
||||
.mul(VecHelper.planeByNormal(facingVec)).normalize().scale(.25f);
|
||||
.mul(VecHelper.planeByNormal(facingVec))
|
||||
.normalize()
|
||||
.scale(.25f);
|
||||
Vec3d offset2 = randVec.add(vec);
|
||||
randVec = randVec.scale(.35f);
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), offset2.x, offset2.y,
|
||||
offset2.z, randVec.x, randVec.y, randVec.z);
|
||||
offset2.z, randVec.x, randVec.y, randVec.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -362,10 +379,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
public void eject() {
|
||||
BlockState blockState = getBlockState();
|
||||
boolean present = AllBlocks.MECHANICAL_CRAFTER.has(blockState);
|
||||
Vec3d vec = present ? new Vec3d(blockState.get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f) : Vec3d.ZERO;
|
||||
Vec3d ejectPos = VecHelper.getCenterOf(pos).add(vec);
|
||||
Vec3d vec = present ? new Vec3d(blockState.get(HORIZONTAL_FACING)
|
||||
.getDirectionVec()).scale(.75f) : Vec3d.ZERO;
|
||||
Vec3d ejectPos = VecHelper.getCenterOf(pos)
|
||||
.add(vec);
|
||||
groupedItems.grid.forEach((pair, stack) -> dropItem(ejectPos, stack));
|
||||
if (!inventory.getStackInSlot(0).isEmpty())
|
||||
if (!inventory.getStackInSlot(0)
|
||||
.isEmpty())
|
||||
dropItem(ejectPos, inventory.getStackInSlot(0));
|
||||
phase = Phase.IDLE;
|
||||
groupedItems = new GroupedItems();
|
||||
|
@ -391,7 +411,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
public boolean craftingItemPresent() {
|
||||
return !inventory.getStackInSlot(0).isEmpty() || covered;
|
||||
return !inventory.getStackInSlot(0)
|
||||
.isEmpty() || covered;
|
||||
}
|
||||
|
||||
protected void checkCompletedRecipe() {
|
||||
|
@ -410,7 +431,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
phase = Phase.ACCEPTING;
|
||||
groupedItems = new GroupedItems(inventory.getStackInSlot(0));
|
||||
inventory.setStackInSlot(0, ItemStack.EMPTY);
|
||||
if (RecipeGridHandler.getPrecedingCrafters(this).isEmpty()) {
|
||||
if (RecipeGridHandler.getPrecedingCrafters(this)
|
||||
.isEmpty()) {
|
||||
phase = Phase.ASSEMBLING;
|
||||
countDown = 500;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
public class DeployerFilterSlot extends ValueBoxTransform {
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
Direction facing = state.get(DeployerBlock.FACING);
|
||||
Vec3d vec = VecHelper.voxelSpace(8f, 13.5f, 11.5f);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
public class SawFilterSlot extends ValueBoxTransform {
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
if (state.get(SawBlock.FACING) != Direction.UP)
|
||||
return null;
|
||||
Vec3d x = VecHelper.voxelSpace(8f, 12.5f, 12.25f);
|
||||
|
|
|
@ -19,8 +19,8 @@ public class DirectionalExtenderScrollOptionSlot extends CenteredSideValueBoxTra
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
return super.getLocation(state)
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
return super.getLocalOffset(state)
|
||||
.add(new Vec3d(state.get(BlockStateProperties.FACING).getDirectionVec()).scale(-2 / 16f));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ public class BeltObserverFilterSlot extends ValueBoxTransform {
|
|||
Vec3d position = VecHelper.voxelSpace(8f, 14.5f, 16f);
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
return rotateHorizontally(state, position);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
public class AdjustableRepeaterScrollSlot extends ValueBoxTransform {
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
return VecHelper.voxelSpace(8, 3f, 8);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public class ExtractorSlots {
|
|||
Vec3d offsetForDownward = VecHelper.voxelSpace(8f, 1.85f, 3.5f);
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
Vec3d location = offsetForHorizontal;
|
||||
if (state.getBlock() instanceof TransposerBlock)
|
||||
location = location.add(0, 2 / 16f, 0);
|
||||
|
@ -52,7 +52,7 @@ public class ExtractorSlots {
|
|||
Vec3d offsetForDownward = VecHelper.voxelSpace(10f, 2f, 11.5f);
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
Vec3d location = offsetForHorizontal;
|
||||
if (state.getBlock() instanceof TransposerBlock)
|
||||
location = location.add(0, 2 / 16f, 0);
|
||||
|
|
|
@ -20,7 +20,7 @@ public class FunnelFilterSlot extends ValueBoxTransform {
|
|||
Vec3d offsetForDownward = VecHelper.voxelSpace(8f, 2.5f, 2f);
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
Vec3d vec = offsetForHorizontal;
|
||||
float yRot = AngleHelper.horizontalAngle(state.get(ExtractorBlock.HORIZONTAL_FACING));
|
||||
if (AttachedLogisticalBlock.isVertical(state))
|
||||
|
|
|
@ -94,7 +94,7 @@ public class CreativeCrateTileEntity extends CrateTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
return new Vec3d(0.5, 13 / 16d, 0.5);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public class RedstoneLinkFrequencySlot extends ValueBoxTransform.Dual {
|
|||
Vec3d vertical = VecHelper.voxelSpace(10f, 2.5f, 5.5f);
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
Direction facing = state.get(RedstoneLinkBlock.FACING);
|
||||
Vec3d location = vertical;
|
||||
|
||||
|
|
|
@ -73,21 +73,23 @@ public class ValueBox extends ChasingAABBOutline {
|
|||
|
||||
@Override
|
||||
public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
|
||||
boolean hasTransform = transform != null;
|
||||
if (transform instanceof Sided && params.getHighlightedFace() != null)
|
||||
((Sided) transform).fromSide(params.getHighlightedFace());
|
||||
if (!transform.shouldRender(blockState))
|
||||
if (hasTransform && !transform.shouldRender(blockState))
|
||||
return;
|
||||
|
||||
ms.push();
|
||||
ms.translate(pos.getX(), pos.getY(), pos.getZ());
|
||||
transform.transform(blockState, ms);
|
||||
if (hasTransform)
|
||||
transform.transform(blockState, ms);
|
||||
transformNormals = ms.peek()
|
||||
.getNormal()
|
||||
.copy();
|
||||
params.colored(isPassive ? passiveColor : highlightColor);
|
||||
super.render(ms, buffer);
|
||||
|
||||
float fontScale = -1 / 64f;
|
||||
float fontScale = hasTransform ? -transform.getFontScale() : -1 / 64f;
|
||||
ms.scale(fontScale, fontScale, fontScale);
|
||||
|
||||
ms.push();
|
||||
|
|
|
@ -19,19 +19,19 @@ public abstract class ValueBoxTransform {
|
|||
|
||||
protected float scale = getScale();
|
||||
|
||||
protected abstract Vec3d getLocation(BlockState state);
|
||||
protected abstract Vec3d getLocalOffset(BlockState state);
|
||||
|
||||
protected abstract void rotate(BlockState state, MatrixStack ms);
|
||||
|
||||
public boolean testHit(BlockState state, Vec3d localHit) {
|
||||
Vec3d offset = getLocation(state);
|
||||
Vec3d offset = getLocalOffset(state);
|
||||
if (offset == null)
|
||||
return false;
|
||||
return localHit.distanceTo(offset) < scale / 2;
|
||||
}
|
||||
|
||||
public void transform(BlockState state, MatrixStack ms) {
|
||||
Vec3d position = getLocation(state);
|
||||
Vec3d position = getLocalOffset(state);
|
||||
if (position == null)
|
||||
return;
|
||||
ms.translate(position.x, position.y, position.z);
|
||||
|
@ -40,7 +40,7 @@ public abstract class ValueBoxTransform {
|
|||
}
|
||||
|
||||
public boolean shouldRender(BlockState state) {
|
||||
return state.getMaterial() != Material.AIR && getLocation(state) != null;
|
||||
return state.getMaterial() != Material.AIR && getLocalOffset(state) != null;
|
||||
}
|
||||
|
||||
protected Vec3d rotateHorizontally(BlockState state, Vec3d vec) {
|
||||
|
@ -55,6 +55,10 @@ public abstract class ValueBoxTransform {
|
|||
protected float getScale() {
|
||||
return .4f;
|
||||
}
|
||||
|
||||
protected float getFontScale() {
|
||||
return 1 / 64f;
|
||||
}
|
||||
|
||||
public static abstract class Dual extends ValueBoxTransform {
|
||||
|
||||
|
@ -73,7 +77,7 @@ public abstract class ValueBoxTransform {
|
|||
}
|
||||
|
||||
public boolean testHit(BlockState state, Vec3d localHit) {
|
||||
Vec3d offset = getLocation(state);
|
||||
Vec3d offset = getLocalOffset(state);
|
||||
if (offset == null)
|
||||
return false;
|
||||
return localHit.distanceTo(offset) < scale / 3.5f;
|
||||
|
@ -91,7 +95,7 @@ public abstract class ValueBoxTransform {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
protected Vec3d getLocalOffset(BlockState state) {
|
||||
Vec3d location = getSouthLocation();
|
||||
location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(direction), Axis.Y);
|
||||
location = VecHelper.rotateCentered(location, AngleHelper.verticalAngle(direction), Axis.Z);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EdgeInteractionBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static IBehaviourType<EdgeInteractionBehaviour> TYPE = new IBehaviourType<EdgeInteractionBehaviour>() {
|
||||
};
|
||||
|
||||
ConnectionCallback connectionCallback;
|
||||
ConnectivityPredicate connectivityPredicate;
|
||||
Optional<Item> requiredItem;
|
||||
|
||||
public EdgeInteractionBehaviour(SmartTileEntity te, ConnectionCallback callback) {
|
||||
super(te);
|
||||
this.connectionCallback = callback;
|
||||
requiredItem = Optional.empty();
|
||||
connectivityPredicate = (world, pos, face, face2) -> true;
|
||||
}
|
||||
|
||||
public EdgeInteractionBehaviour connectivity(ConnectivityPredicate pred) {
|
||||
this.connectivityPredicate = pred;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EdgeInteractionBehaviour require(Item item) {
|
||||
this.requiredItem = Optional.of(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ConnectionCallback {
|
||||
public void apply(World world, BlockPos clicked, BlockPos neighbour);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ConnectivityPredicate {
|
||||
public boolean test(World world, BlockPos pos, Direction selectedFace, Direction connectedFace);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.utility.RaycastHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class EdgeInteractionHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onBlockActivated(PlayerInteractEvent.RightClickBlock event) {
|
||||
World world = event.getWorld();
|
||||
BlockPos pos = event.getPos();
|
||||
PlayerEntity player = event.getPlayer();
|
||||
Hand hand = event.getHand();
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
|
||||
if (player.isSneaking())
|
||||
return;
|
||||
EdgeInteractionBehaviour behaviour = TileEntityBehaviour.get(world, pos, EdgeInteractionBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
BlockRayTraceResult ray = RaycastHelper.rayTraceRange(world, player, 10);
|
||||
if (ray == null)
|
||||
return;
|
||||
if (behaviour.requiredItem.orElse(heldItem.getItem()) != heldItem.getItem())
|
||||
return;
|
||||
|
||||
Direction activatedDirection = getActivatedDirection(world, pos, ray.getFace(), ray.getHitVec(), behaviour);
|
||||
if (activatedDirection == null)
|
||||
return;
|
||||
|
||||
if (event.getSide() != LogicalSide.CLIENT)
|
||||
behaviour.connectionCallback.apply(world, pos, pos.offset(activatedDirection));
|
||||
event.setCanceled(true);
|
||||
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ADD_ITEM, SoundCategory.BLOCKS, .25f, .1f);
|
||||
}
|
||||
|
||||
public static List<Direction> getConnectiveSides(World world, BlockPos pos, Direction face,
|
||||
EdgeInteractionBehaviour behaviour) {
|
||||
List<Direction> sides = new ArrayList<>(6);
|
||||
if (Block.hasSolidSide(world.getBlockState(pos.offset(face)), world, pos.offset(face), face.getOpposite()))
|
||||
return sides;
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (direction.getAxis() == face.getAxis())
|
||||
continue;
|
||||
BlockPos neighbourPos = pos.offset(direction);
|
||||
if (Block.hasSolidSide(world.getBlockState(neighbourPos.offset(face)), world, neighbourPos.offset(face),
|
||||
face.getOpposite()))
|
||||
continue;
|
||||
if (!behaviour.connectivityPredicate.test(world, pos, face, direction))
|
||||
continue;
|
||||
sides.add(direction);
|
||||
}
|
||||
|
||||
return sides;
|
||||
}
|
||||
|
||||
public static Direction getActivatedDirection(World world, BlockPos pos, Direction face, Vec3d hit,
|
||||
EdgeInteractionBehaviour behaviour) {
|
||||
for (Direction facing : getConnectiveSides(world, pos, face, behaviour)) {
|
||||
AxisAlignedBB bb = getBB(pos, facing);
|
||||
if (bb.contains(hit))
|
||||
return facing;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static AxisAlignedBB getBB(BlockPos pos, Direction direction) {
|
||||
AxisAlignedBB bb = new AxisAlignedBB(pos);
|
||||
Vec3i vec = direction.getDirectionVec();
|
||||
int x = vec.getX();
|
||||
int y = vec.getY();
|
||||
int z = vec.getZ();
|
||||
double margin = 12 / 16f;
|
||||
double absX = Math.abs(x) * margin;
|
||||
double absY = Math.abs(y) * margin;
|
||||
double absZ = Math.abs(z) * margin;
|
||||
|
||||
bb = bb.contract(absX, absY, absZ);
|
||||
bb = bb.offset(absX / 2d, absY / 2d, absZ / 2d);
|
||||
bb = bb.offset(x / 2d, y / 2d, z / 2d);
|
||||
bb = bb.grow(1 / 256f);
|
||||
return bb;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllSpecialTextures;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBox;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class EdgeInteractionRenderer {
|
||||
|
||||
public static void tick() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
RayTraceResult target = mc.objectMouseOver;
|
||||
if (target == null || !(target instanceof BlockRayTraceResult))
|
||||
return;
|
||||
|
||||
BlockRayTraceResult result = (BlockRayTraceResult) target;
|
||||
ClientWorld world = mc.world;
|
||||
BlockPos pos = result.getPos();
|
||||
PlayerEntity player = mc.player;
|
||||
ItemStack heldItem = player.getHeldItemMainhand();
|
||||
|
||||
if (player.isSneaking())
|
||||
return;
|
||||
EdgeInteractionBehaviour behaviour = TileEntityBehaviour.get(world, pos, EdgeInteractionBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
if (behaviour.requiredItem.orElse(heldItem.getItem()) != heldItem.getItem())
|
||||
return;
|
||||
|
||||
Direction face = result.getFace();
|
||||
List<Direction> connectiveSides = EdgeInteractionHandler.getConnectiveSides(world, pos, face, behaviour);
|
||||
if (connectiveSides.isEmpty())
|
||||
return;
|
||||
|
||||
Direction closestEdge = connectiveSides.get(0);
|
||||
double bestDistance = Double.MAX_VALUE;
|
||||
Vec3d center = VecHelper.getCenterOf(pos);
|
||||
for (Direction direction : connectiveSides) {
|
||||
double distance = new Vec3d(direction.getDirectionVec()).subtract(target.getHitVec()
|
||||
.subtract(center))
|
||||
.length();
|
||||
if (distance > bestDistance)
|
||||
continue;
|
||||
bestDistance = distance;
|
||||
closestEdge = direction;
|
||||
}
|
||||
|
||||
AxisAlignedBB bb = EdgeInteractionHandler.getBB(pos, closestEdge);
|
||||
boolean hit = bb.contains(target.getHitVec());
|
||||
|
||||
ValueBox box = new ValueBox("", bb.offset(-pos.getX(), -pos.getY(), -pos.getZ()), pos);
|
||||
Vec3d textOffset = Vec3d.ZERO;
|
||||
|
||||
boolean positive = closestEdge.getAxisDirection() == AxisDirection.POSITIVE;
|
||||
if (positive) {
|
||||
if (face.getAxis()
|
||||
.isHorizontal()) {
|
||||
if (closestEdge.getAxis()
|
||||
.isVertical())
|
||||
textOffset = textOffset.add(0, -128, 0);
|
||||
else
|
||||
textOffset = textOffset.add(-128, 0, 0);
|
||||
} else
|
||||
textOffset = textOffset.add(-128, 0, 0);
|
||||
}
|
||||
|
||||
box.offsetLabel(textOffset)
|
||||
.withColors(0x7A6A2C, 0xB79D64)
|
||||
.passive(!hit);
|
||||
|
||||
CreateClient.outliner.showValueBox("edge", box)
|
||||
.lineWidth(1 / 64f)
|
||||
.withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null)
|
||||
.highlightFace(face);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue