Remove MultipartSlot
This commit is contained in:
parent
fc5ccc35dd
commit
dd479376fd
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
|
|
|
@ -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 + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue