Remove MultipartSlot

This commit is contained in:
Shadowfacts 2018-12-24 17:16:38 -05:00
parent fc5ccc35dd
commit dd479376fd
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
16 changed files with 179 additions and 179 deletions

View File

@ -30,7 +30,7 @@ public class MultipartContainerBakedModel implements BakedModel {
} }
MultipartContainerBlockState containerState = (MultipartContainerBlockState)state; MultipartContainerBlockState containerState = (MultipartContainerBlockState)state;
// TODO: would manually building the list be more efficient? // TODO: would manually building the list be more efficient?
return containerState.getParts().values().stream() return containerState.getParts().stream()
.flatMap(partState -> { .flatMap(partState -> {
Identifier partId = SimpleMultipart.MULTIPART.getId(partState.getMultipart()); Identifier partId = SimpleMultipart.MULTIPART.getId(partState.getMultipart());
String variant = BlockModels.propertyMapToString(partState.getEntries()); String variant = BlockModels.propertyMapToString(partState.getEntries());

View File

@ -12,12 +12,12 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.ExtendedBlockView; import net.minecraft.world.ExtendedBlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.shadowfacts.simplemultipart.client.util.RenderStateProvider; import net.shadowfacts.simplemultipart.client.util.RenderStateProvider;
import net.shadowfacts.simplemultipart.multipart.MultipartSlot;
import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.multipart.MultipartState;
import net.shadowfacts.simplemultipart.util.MultipartHelper; import net.shadowfacts.simplemultipart.util.MultipartHelper;
import net.shadowfacts.simplemultipart.util.MultipartHitResult; import net.shadowfacts.simplemultipart.util.MultipartHitResult;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* @author shadowfacts * @author shadowfacts
@ -30,14 +30,6 @@ public class MultipartContainerBlock extends Block implements BlockEntityProvide
@Override @Override
public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, Direction side, float hitX, float hitY, float hitZ) { public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, Direction side, float hitX, float hitY, float hitZ) {
// if (player.isSneaking()) {
// MultipartContainerBlockEntity container = (MultipartContainerBlockEntity)world.getBlockEntity(pos);
// System.out.println(container.getParts());
// return true;
// } else {
// return false;
// }
MultipartContainerBlockEntity container = (MultipartContainerBlockEntity)world.getBlockEntity(pos); MultipartContainerBlockEntity container = (MultipartContainerBlockEntity)world.getBlockEntity(pos);
if (container == null) { if (container == null) {
return false; return false;
@ -48,8 +40,7 @@ public class MultipartContainerBlock extends Block implements BlockEntityProvide
return false; return false;
} }
MultipartState partState = container.get(hit.partSlot); return hit.partState.activate(container, player, hand);
return partState.activate(hit.partSlot, container, player, hand);
} }
@Override @Override
@ -59,7 +50,7 @@ public class MultipartContainerBlock extends Block implements BlockEntityProvide
return state; return state;
} }
Map<MultipartSlot, MultipartState> parts = container.getParts(); Set<MultipartState> parts = container.getParts();
return new MultipartContainerBlockState(state, parts); return new MultipartContainerBlockState(state, parts);
} }
@ -71,8 +62,8 @@ public class MultipartContainerBlock extends Block implements BlockEntityProvide
} }
VoxelShape shape = null; VoxelShape shape = null;
for (Map.Entry<MultipartSlot, MultipartState> e : container.getParts().entrySet()) { for (MultipartState partState : container.getParts()) {
VoxelShape partShape = e.getValue().getBoundingShape(e.getKey(), container); VoxelShape partShape = partState.getBoundingShape(container);
shape = shape == null ? partShape : VoxelShapes.union(shape, partShape); shape = shape == null ? partShape : VoxelShapes.union(shape, partShape);
} }
return shape == null ? VoxelShapes.empty() : shape; return shape == null ? VoxelShapes.empty() : shape;

View File

@ -1,6 +1,7 @@
package net.shadowfacts.simplemultipart.container; package net.shadowfacts.simplemultipart.container;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet;
import net.fabricmc.fabric.api.util.NbtType;
import net.fabricmc.fabric.block.entity.ClientSerializable; import net.fabricmc.fabric.block.entity.ClientSerializable;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -8,76 +9,66 @@ import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.shape.VoxelShape;
import net.shadowfacts.simplemultipart.SimpleMultipart; import net.shadowfacts.simplemultipart.SimpleMultipart;
import net.shadowfacts.simplemultipart.multipart.MultipartSlot;
import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.multipart.MultipartState;
import net.shadowfacts.simplemultipart.util.MultipartHelper; import net.shadowfacts.simplemultipart.util.MultipartHelper;
import net.shadowfacts.simplemultipart.util.ShapeUtils;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
public class MultipartContainerBlockEntity extends BlockEntity implements ClientSerializable { public class MultipartContainerBlockEntity extends BlockEntity implements ClientSerializable {
private Map<MultipartSlot, MultipartState> parts = new HashMap<>(); private Set<MultipartState> parts = new HashSet<>();
public MultipartContainerBlockEntity() { public MultipartContainerBlockEntity() {
super(SimpleMultipart.containerBlockEntity); super(SimpleMultipart.containerBlockEntity);
} }
public ImmutableMap<MultipartSlot, MultipartState> getParts() { public ImmutableSet<MultipartState> getParts() {
return ImmutableMap.copyOf(parts); return ImmutableSet.copyOf(parts);
} }
public boolean hasPartInSlot(MultipartSlot slot) { public boolean canInsert(MultipartState partState) {
return parts.containsKey(slot); VoxelShape newShape = partState.getBoundingShape(null);
} for (MultipartState existing : parts) {
VoxelShape existingShape = existing.getBoundingShape(this);
public boolean canInsert(MultipartState partState, MultipartSlot slot) { if (ShapeUtils.intersect(newShape, existingShape)) {
if (hasPartInSlot(slot)) {
return false; return false;
} }
}
// TODO: check bounding box intersections
return true; return true;
} }
public void insert(MultipartState partState, MultipartSlot slot) { public void insert(MultipartState partState) {
parts.put(slot, partState); parts.add(partState);
markDirty(); markDirty();
world.scheduleBlockRender(pos); world.scheduleBlockRender(pos);
} }
public MultipartState get(MultipartSlot slot) { public void remove(MultipartState partState) {
return parts.get(slot); parts.remove(partState);
}
public void remove(MultipartSlot slot) {
parts.remove(slot);
if (parts.isEmpty()) { if (parts.isEmpty()) {
world.setBlockState(pos, Blocks.AIR.getDefaultState()); world.setBlockState(pos, Blocks.AIR.getDefaultState());
} }
} }
public boolean breakPart(MultipartSlot slot) { public boolean breakPart(MultipartState partState) {
MultipartState state = get(slot);
if (state == null) {
return false;
}
if (world instanceof ServerWorld) { if (world instanceof ServerWorld) {
List<ItemStack> drops = MultipartHelper.getDroppedStacks(state, (ServerWorld)world, pos); List<ItemStack> drops = MultipartHelper.getDroppedStacks(partState, (ServerWorld)world, pos);
drops.forEach(stack -> Block.dropStack(world, pos, stack)); drops.forEach(stack -> Block.dropStack(world, pos, stack));
// TODO: don't drop if player is creative // TODO: don't drop if player is creative
} }
remove(slot); remove(partState);
world.markDirty(pos, this); world.markDirty(pos, this);
world.scheduleBlockRender(pos); world.scheduleBlockRender(pos);
@ -87,48 +78,48 @@ public class MultipartContainerBlockEntity extends BlockEntity implements Client
return true; return true;
} }
private CompoundTag partsToTag(CompoundTag tag) { private ListTag partsToTag() {
parts.forEach((slot, state) -> { ListTag list = new ListTag();
parts.forEach(state -> {
if (state != null) { if (state != null) {
CompoundTag partStateTag = MultipartHelper.serializeMultipartState(state); CompoundTag partStateTag = MultipartHelper.serializeMultipartState(state);
tag.put(slot.name(), partStateTag); list.add(partStateTag);
} }
}); });
return tag; return list;
} }
private void partsFromTag(CompoundTag tag) { private void partsFromTag(ListTag list) {
parts.clear(); parts.clear();
for (MultipartSlot slot : MultipartSlot.values()) { for (Tag tag : list) {
if (!(tag.containsKey(slot.name(), 10))) { MultipartState state = MultipartHelper.deserializeMultipartState((CompoundTag)tag);
continue; parts.add(state);
}
CompoundTag partStateTag = tag.getCompound(slot.name());
MultipartState state = MultipartHelper.deserializeMultipartState(partStateTag);
parts.put(slot, state);
} }
} }
@Override @Override
public CompoundTag toTag(CompoundTag tag) { public CompoundTag toTag(CompoundTag tag) {
partsToTag(tag); tag.put("parts", partsToTag());
return super.toTag(tag); return super.toTag(tag);
} }
@Override @Override
public void fromTag(CompoundTag tag) { public void fromTag(CompoundTag tag) {
super.fromTag(tag); super.fromTag(tag);
partsFromTag(tag); ListTag list = tag.getList("parts", NbtType.COMPOUND);
partsFromTag(list);
} }
@Override @Override
public CompoundTag toClientTag(CompoundTag tag) { public CompoundTag toClientTag(CompoundTag tag) {
return partsToTag(tag); tag.put("parts", partsToTag());
return tag;
} }
@Override @Override
public void fromClientTag(CompoundTag tag) { public void fromClientTag(CompoundTag tag) {
partsFromTag(tag); ListTag list = tag.getList("parts", NbtType.COMPOUND);
partsFromTag(list);
world.scheduleBlockRender(pos); world.scheduleBlockRender(pos);
} }
} }

View File

@ -1,24 +1,24 @@
package net.shadowfacts.simplemultipart.container; package net.shadowfacts.simplemultipart.container;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.shadowfacts.simplemultipart.multipart.MultipartSlot;
import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.multipart.MultipartState;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
public class MultipartContainerBlockState extends BlockState { public class MultipartContainerBlockState extends BlockState {
private Map<MultipartSlot, MultipartState> parts; private Set<MultipartState> parts;
public MultipartContainerBlockState(BlockState delegate, Map<MultipartSlot, MultipartState> parts) { public MultipartContainerBlockState(BlockState delegate, Set<MultipartState> parts) {
super(delegate.getBlock(), delegate.getEntries()); super(delegate.getBlock(), delegate.getEntries());
this.parts = parts; this.parts = parts;
} }
public Map<MultipartSlot, MultipartState> getParts() { public Set<MultipartState> getParts() {
return parts; return parts;
} }
} }

View File

@ -35,7 +35,7 @@ public class MultipartContainerEventHandler {
return ActionResult.FAILURE; return ActionResult.FAILURE;
} }
boolean success = container.breakPart(hit.partSlot); boolean success = container.breakPart(hit.partState);
return success ? ActionResult.SUCCESS : ActionResult.FAILURE; return success ? ActionResult.SUCCESS : ActionResult.FAILURE;
} }

View File

@ -10,8 +10,8 @@ import net.minecraft.world.World;
import net.shadowfacts.simplemultipart.SimpleMultipart; import net.shadowfacts.simplemultipart.SimpleMultipart;
import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity; import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity;
import net.shadowfacts.simplemultipart.multipart.Multipart; import net.shadowfacts.simplemultipart.multipart.Multipart;
import net.shadowfacts.simplemultipart.multipart.MultipartSlot;
import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.multipart.MultipartState;
import net.shadowfacts.simplemultipart.util.MultipartPlacementContext;
/** /**
* @author shadowfacts * @author shadowfacts
@ -36,21 +36,35 @@ public class ItemMultipart extends Item {
return ActionResult.FAILURE; return ActionResult.FAILURE;
} }
MultipartSlot slot = getSlotForPlacement(container, context); MultipartPlacementContext partContext = new MultipartPlacementContext(container, context);
if (slot == null) { MultipartState state = part.getPlacementState(partContext);
if (!container.canInsert(state)) {
// container.destroyIfEmpty();
return ActionResult.FAILURE; return ActionResult.FAILURE;
} }
MultipartState partState = part.getPlacementState(slot, container); container.insert(state);
if (!container.canInsert(partState, slot)) {
return ActionResult.FAILURE;
}
container.insert(partState, slot);
context.getItemStack().addAmount(-1); context.getItemStack().addAmount(-1);
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
// MultipartSlot slot = getSlotForPlacement(container, context);
// if (slot == null) {
// return ActionResult.FAILURE;
// }
//
// MultipartState partState = part.getPlacementState(slot, container);
// if (!container.canInsert(partState, slot)) {
// return ActionResult.FAILURE;
// }
//
// container.insert(partState, slot);
//
// context.getItemStack().addAmount(-1);
//
// return ActionResult.SUCCESS;
} }
protected MultipartContainerBlockEntity getOrCreateContainer(World world, BlockPos pos) { protected MultipartContainerBlockEntity getOrCreateContainer(World world, BlockPos pos) {
@ -65,15 +79,15 @@ public class ItemMultipart extends Item {
} }
} }
protected MultipartSlot getSlotForPlacement(MultipartContainerBlockEntity container, ItemPlacementContext context) { // protected MultipartSlot getSlotForPlacement(MultipartContainerBlockEntity container, ItemPlacementContext context) {
MultipartSlot slot = MultipartSlot.fromClickedSide(context.getFacing()); // MultipartSlot slot = MultipartSlot.fromClickedSide(context.getFacing());
if (part.isValidSlot(slot) && !container.hasPartInSlot(slot)) { // if (part.isValidSlot(slot) && !container.hasPartInSlot(slot)) {
return slot; // return slot;
} // }
if (part.isValidSlot(MultipartSlot.CENTER) && !container.hasPartInSlot(MultipartSlot.CENTER)) { // if (part.isValidSlot(MultipartSlot.CENTER) && !container.hasPartInSlot(MultipartSlot.CENTER)) {
return MultipartSlot.CENTER; // return MultipartSlot.CENTER;
} // }
return null; // return null;
} // }
} }

View File

@ -15,6 +15,7 @@ import net.minecraft.world.loot.LootTables;
import net.minecraft.world.loot.context.LootContext; import net.minecraft.world.loot.context.LootContext;
import net.shadowfacts.simplemultipart.SimpleMultipart; import net.shadowfacts.simplemultipart.SimpleMultipart;
import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity; import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity;
import net.shadowfacts.simplemultipart.util.MultipartPlacementContext;
import java.util.List; import java.util.List;
@ -23,8 +24,6 @@ import java.util.List;
*/ */
public abstract class Multipart { public abstract class Multipart {
public static final EnumProperty<MultipartSlot> SLOT = EnumProperty.create("slot", MultipartSlot.class);
private StateFactory<Multipart, MultipartState> stateFactory; private StateFactory<Multipart, MultipartState> stateFactory;
private MultipartState defaultState; private MultipartState defaultState;
@ -51,11 +50,7 @@ public abstract class Multipart {
return stateFactory; return stateFactory;
} }
public boolean isValidSlot(MultipartSlot slot) { public MultipartState getPlacementState(MultipartPlacementContext context) {
return true;
}
public MultipartState getPlacementState(MultipartSlot slot, MultipartContainerBlockEntity container) {
return getDefaultState(); return getDefaultState();
} }
@ -63,7 +58,7 @@ public abstract class Multipart {
* Can be overridden, should only be called via {@link MultipartState#getStateForRendering} * Can be overridden, should only be called via {@link MultipartState#getStateForRendering}
*/ */
@Deprecated @Deprecated
public MultipartState getStateForRendering(MultipartState state, MultipartSlot slot, MultipartContainerBlockEntity container) { public MultipartState getStateForRendering(MultipartState state, MultipartContainerBlockEntity container) {
return state; return state;
} }
@ -71,7 +66,7 @@ public abstract class Multipart {
* Can be overridden, should only be called via {@link MultipartState#getBoundingShape} * Can be overridden, should only be called via {@link MultipartState#getBoundingShape}
*/ */
@Deprecated @Deprecated
public abstract VoxelShape getBoundingShape(MultipartState state, MultipartSlot slot, MultipartContainerBlockEntity container); public abstract VoxelShape getBoundingShape(/*@Nullable*/ MultipartState state, MultipartContainerBlockEntity container);
public Identifier getDropTableId() { public Identifier getDropTableId() {
if (dropTableId == null) { if (dropTableId == null) {
@ -101,7 +96,7 @@ public abstract class Multipart {
* Can be overridden, should only be called via {@link MultipartState#activate} * Can be overridden, should only be called via {@link MultipartState#activate}
*/ */
@Deprecated @Deprecated
public boolean activate(MultipartState state, MultipartSlot slot, MultipartContainerBlockEntity container, PlayerEntity player, Hand hand) { public boolean activate(MultipartState state, MultipartContainerBlockEntity container, PlayerEntity player, Hand hand) {
return false; return false;
} }

View File

@ -1,40 +0,0 @@
package net.shadowfacts.simplemultipart.multipart;
import net.minecraft.util.StringRepresentable;
import net.minecraft.util.math.Direction;
/**
* @author shadowfacts
*/
public enum MultipartSlot implements StringRepresentable {
TOP,
BOTTOM,
NORTH,
SOUTH,
EAST,
WEST,
CENTER;
public static MultipartSlot fromClickedSide(Direction side) {
switch (side) {
case UP:
return BOTTOM;
case DOWN:
return TOP;
case NORTH:
return SOUTH;
case SOUTH:
return NORTH;
case EAST:
return WEST;
case WEST:
return EAST;
}
throw new RuntimeException("Unreachable: got direction outside of DUNSWE");
}
@Override
public String asString() {
return name().toLowerCase();
}
}

View File

@ -25,14 +25,14 @@ public class MultipartState extends AbstractPropertyContainer<Multipart, Multipa
return owner; return owner;
} }
public MultipartState getStateForRendering(MultipartSlot slot, MultipartContainerBlockEntity container) { public MultipartState getStateForRendering(MultipartContainerBlockEntity container) {
//noinspection deprecation //noinspection deprecation
return owner.getStateForRendering(this, slot, container); return owner.getStateForRendering(this, container);
} }
public VoxelShape getBoundingShape(MultipartSlot slot, MultipartContainerBlockEntity container) { public VoxelShape getBoundingShape(/*@Nullable*/ MultipartContainerBlockEntity container) {
//noinspection deprecation //noinspection deprecation
return owner.getBoundingShape(this, slot, container); return owner.getBoundingShape(this, container);
} }
public List<ItemStack> getDroppedStacks(LootContext.Builder builder) { public List<ItemStack> getDroppedStacks(LootContext.Builder builder) {
@ -40,9 +40,9 @@ public class MultipartState extends AbstractPropertyContainer<Multipart, Multipa
return owner.getDroppedStacks(this, builder); return owner.getDroppedStacks(this, builder);
} }
public boolean activate(MultipartSlot slot, MultipartContainerBlockEntity container, PlayerEntity player, Hand hand) { public boolean activate(MultipartContainerBlockEntity container, PlayerEntity player, Hand hand) {
//noinspection deprecated //noinspection deprecated
return owner.activate(this, slot, container, player, hand); return owner.activate(this, container, player, hand);
} }
} }

View File

@ -50,11 +50,11 @@ public class MultipartHelper {
} }
public static MultipartHitResult rayTrace(MultipartContainerBlockEntity container, World world, BlockPos pos, Vec3d start, Vec3d end) { public static MultipartHitResult rayTrace(MultipartContainerBlockEntity container, World world, BlockPos pos, Vec3d start, Vec3d end) {
return container.getParts().entrySet().stream() return container.getParts().stream()
.map(e -> { .map(partState -> {
VoxelShape shape = e.getValue().getBoundingShape(e.getKey(), container); VoxelShape shape = partState.getBoundingShape(container);
HitResult result = shape.rayTrace(start, end, pos); HitResult result = shape.rayTrace(start, end, pos);
return result == null ? null : new MultipartHitResult(result, e.getKey()); return result == null ? null : new MultipartHitResult(result, partState);
}) })
.filter(Objects::nonNull) .filter(Objects::nonNull)
.min(Comparator.comparingDouble(hit -> hit.pos.subtract(start).lengthSquared())) .min(Comparator.comparingDouble(hit -> hit.pos.subtract(start).lengthSquared()))

View File

@ -4,22 +4,22 @@ import net.minecraft.util.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.shadowfacts.simplemultipart.multipart.MultipartSlot; import net.shadowfacts.simplemultipart.multipart.MultipartState;
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
public class MultipartHitResult extends HitResult { public class MultipartHitResult extends HitResult {
public MultipartSlot partSlot; public MultipartState partState;
public MultipartHitResult(Vec3d pos, Direction side, BlockPos blockPos, MultipartSlot partSlot) { public MultipartHitResult(Vec3d pos, Direction side, BlockPos blockPos, MultipartState partState) {
super(pos, side, blockPos); super(pos, side, blockPos);
this.partSlot = partSlot; this.partState = partState;
} }
public MultipartHitResult(HitResult result, MultipartSlot partSlot) { public MultipartHitResult(HitResult result, MultipartState partState) {
this(result.pos, result.side, result.getBlockPos(), partSlot); this(result.pos, result.side, result.getBlockPos(), partState);
if (result.type != Type.BLOCK) { if (result.type != Type.BLOCK) {
throw new IllegalArgumentException("Can't create a MultipartHitResult from a non BLOCK-type HitResult"); throw new IllegalArgumentException("Can't create a MultipartHitResult from a non BLOCK-type HitResult");
} }
@ -27,6 +27,6 @@ public class MultipartHitResult extends HitResult {
@Override @Override
public String toString() { public String toString() {
return "HitResult{type=" + type + ", blockpos=" + getBlockPos() + ", f=" + side + ", pos=" + pos + ", partSlot=" + partSlot + '}'; return "HitResult{type=" + type + ", blockpos=" + getBlockPos() + ", f=" + side + ", pos=" + pos + ", partState=" + partState + '}';
} }
} }

View File

@ -0,0 +1,31 @@
package net.shadowfacts.simplemultipart.util;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity;
/**
* @author shadowfacts
*/
public class MultipartPlacementContext extends ItemUsageContext {
private final MultipartContainerBlockEntity container;
public MultipartPlacementContext(MultipartContainerBlockEntity container, PlayerEntity player, ItemStack stack, BlockPos pos, Direction side, float hitX, float hitY, float hitZ) {
super(player, stack, pos, side, hitX, hitY, hitZ);
this.container = container;
}
public MultipartPlacementContext(MultipartContainerBlockEntity container, ItemPlacementContext context) {
this(container, context.getPlayer(), context.getItemStack(), context.getPos(), context.getFacing(), context.getHitX(), context.getHitY(), context.getHitZ());
}
public MultipartContainerBlockEntity getContainer() {
return container;
}
}

View File

@ -0,0 +1,17 @@
package net.shadowfacts.simplemultipart.util;
import net.minecraft.util.BooleanBiFunction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
/**
* @author shadowfacts
*/
public class ShapeUtils {
public static boolean intersect(VoxelShape a, VoxelShape b) {
VoxelShape overlap = VoxelShapes.combine(a, b, BooleanBiFunction.AND);
return !overlap.isEmpty();
}
}

View File

@ -2,13 +2,15 @@ package net.shadowfacts.simplemultipart.test;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.StateFactory; import net.minecraft.state.StateFactory;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes; import net.minecraft.util.shape.VoxelShapes;
import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity; import net.shadowfacts.simplemultipart.container.MultipartContainerBlockEntity;
import net.shadowfacts.simplemultipart.multipart.Multipart; import net.shadowfacts.simplemultipart.multipart.Multipart;
import net.shadowfacts.simplemultipart.multipart.MultipartSlot;
import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.multipart.MultipartState;
import net.shadowfacts.simplemultipart.util.MultipartPlacementContext;
/** /**
* @author shadowfacts * @author shadowfacts
@ -16,32 +18,29 @@ import net.shadowfacts.simplemultipart.multipart.MultipartState;
public class TestMultipart extends Multipart { public class TestMultipart extends Multipart {
public TestMultipart() { public TestMultipart() {
setDefaultState(getDefaultState().with(SLOT, MultipartSlot.BOTTOM)); setDefaultState(getDefaultState().with(Properties.FACING, Direction.DOWN));
} }
@Override @Override
protected void appendProperties(StateFactory.Builder<Multipart, MultipartState> builder) { protected void appendProperties(StateFactory.Builder<Multipart, MultipartState> builder) {
super.appendProperties(builder); super.appendProperties(builder);
builder.with(SLOT); builder.with(Properties.FACING);
} }
@Override @Override
public boolean isValidSlot(MultipartSlot slot) { public MultipartState getPlacementState(MultipartPlacementContext context) {
return slot != MultipartSlot.CENTER; Direction hitSide = context.getFacing();
} return getDefaultState().with(Properties.FACING, hitSide.getOpposite());
@Override
public MultipartState getPlacementState(MultipartSlot slot, MultipartContainerBlockEntity container) {
return getDefaultState().with(SLOT, slot);
} }
@Override @Override
@Deprecated @Deprecated
public VoxelShape getBoundingShape(MultipartState state, MultipartSlot slot, MultipartContainerBlockEntity container) { public VoxelShape getBoundingShape(MultipartState state, MultipartContainerBlockEntity container) {
switch (slot) { Direction side = state.get(Properties.FACING);
case TOP: switch (side) {
case UP:
return VoxelShapes.cube(0, 15/16f, 0, 1, 1, 1); return VoxelShapes.cube(0, 15/16f, 0, 1, 1, 1);
case BOTTOM: case DOWN:
return VoxelShapes.cube(0, 0, 0, 1, 1/16f, 1); return VoxelShapes.cube(0, 0, 0, 1, 1/16f, 1);
case NORTH: case NORTH:
return VoxelShapes.cube(0, 0, 0, 1, 1, 1/16f); return VoxelShapes.cube(0, 0, 0, 1, 1, 1/16f);
@ -57,8 +56,10 @@ public class TestMultipart extends Multipart {
@Override @Override
@Deprecated @Deprecated
public boolean activate(MultipartState state, MultipartSlot slot, MultipartContainerBlockEntity container, PlayerEntity player, Hand hand) { public boolean activate(MultipartState state, MultipartContainerBlockEntity container, PlayerEntity player, Hand hand) {
System.out.println("part activated: " + slot); Direction side = state.get(Properties.FACING);
System.out.println("part activated on " + side);
return true; return true;
} }
} }

View File

@ -4,11 +4,11 @@
"apply": { "model": "multipart_test:multipart/center" } "apply": { "model": "multipart_test:multipart/center" }
}, },
{ {
"when": { "slot": "bottom" }, "when": { "facing": "down" },
"apply": { "model": "multipart_test:multipart/bottom" } "apply": { "model": "multipart_test:multipart/bottom" }
}, },
{ {
"when": { "slot": "north" }, "when": { "facing": "north" },
"apply": { "model": "multipart_test:multipart/vertical" } "apply": { "model": "multipart_test:multipart/vertical" }
} }
] ]

View File

@ -1,11 +1,11 @@
{ {
"variants": { "variants": {
"slot=bottom": { "model": "multipart_test:multipart/bottom" }, "facing=down": { "model": "multipart_test:multipart/bottom" },
"slot=top": { "model": "multipart_test:multipart/bottom", "x": 180 }, "facing=up": { "model": "multipart_test:multipart/bottom", "x": 180 },
"slot=north": { "model": "multipart_test:multipart/vertical" }, "facing=north": { "model": "multipart_test:multipart/vertical" },
"slot=south": { "model": "multipart_test:multipart/vertical", "y": 180 }, "facing=south": { "model": "multipart_test:multipart/vertical", "y": 180 },
"slot=east": { "model": "multipart_test:multipart/vertical", "y": 90 }, "facing=east": { "model": "multipart_test:multipart/vertical", "y": 90 },
"slot=west": { "model": "multipart_test:multipart/vertical", "y": 270 }, "facing=west": { "model": "multipart_test:multipart/vertical", "y": 270 },
"inventory": { "model": "multipart_test:multipart/vertical", "y": 180 } "inventory": { "model": "multipart_test:multipart/vertical", "y": 180 }
} }
} }