Initial implementation of container getPart(Direction)
This commit is contained in:
parent
6ade580e85
commit
7c465d01f4
|
@ -12,9 +12,14 @@ version = "0.1.0"
|
|||
minecraft {
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:18w50a"
|
||||
mappings "net.fabricmc:yarn:18w50a.80"
|
||||
// mappings "net.fabricmc:yarn:18w50a.80"
|
||||
mappings "net.fabricmc:yarn:18w50a.local" // temporary until yarn #369
|
||||
modCompile "net.fabricmc:fabric-loader:0.3.1.80"
|
||||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
|
|
|
@ -15,6 +15,7 @@ import net.minecraft.nbt.Tag;
|
|||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Tickable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.loot.context.LootContext;
|
||||
import net.minecraft.world.loot.context.Parameters;
|
||||
|
@ -35,6 +36,7 @@ import java.util.stream.Collectors;
|
|||
public abstract class AbstractContainerBlockEntity extends BlockEntity implements MultipartContainer, ClientSerializable {
|
||||
|
||||
protected Set<Entry> parts = new HashSet<>();
|
||||
protected Map<Direction, Entry> sidePartCache = new WeakHashMap<>();
|
||||
|
||||
public AbstractContainerBlockEntity(BlockEntityType<?> type) {
|
||||
super(type);
|
||||
|
@ -50,6 +52,36 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
|||
return !parts.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultipartView getPart(Direction side) {
|
||||
Entry existing = sidePartCache.get(side);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
Optional<Entry> e = parts.stream()
|
||||
.min((a, b) -> {
|
||||
VoxelShape aShape = a.getState().getBoundingShape(a);
|
||||
VoxelShape bShape = b.getState().getBoundingShape(b);
|
||||
double aCoord = side.getDirection() == Direction.AxisDirection.POSITIVE ? aShape.getMaximum(side.getAxis()) : aShape.getMinimum(side.getAxis());
|
||||
double bCoord = side.getDirection() == Direction.AxisDirection.POSITIVE ? bShape.getMaximum(side.getAxis()) : bShape.getMinimum(side.getAxis());
|
||||
return Double.compare(bCoord, aCoord);
|
||||
});
|
||||
|
||||
if (!e.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
sidePartCache.put(side, e.get());
|
||||
|
||||
return e.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateSidePartCache() {
|
||||
sidePartCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert(MultipartState partState) {
|
||||
VoxelShape newShape = partState.getBoundingShape(null);
|
||||
|
@ -77,6 +109,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
|||
}
|
||||
parts.add(e);
|
||||
|
||||
invalidateSidePartCache();
|
||||
updateWorld();
|
||||
}
|
||||
|
||||
|
@ -91,6 +124,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
|||
if (parts.isEmpty()) {
|
||||
world.setBlockState(pos, Blocks.AIR.getDefaultState());
|
||||
} else {
|
||||
invalidateSidePartCache();
|
||||
updateWorld();
|
||||
}
|
||||
}
|
||||
|
@ -203,18 +237,18 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
|||
}
|
||||
|
||||
public static class Entry implements MultipartView {
|
||||
public final MultipartContainer container;
|
||||
public final AbstractContainerBlockEntity container;
|
||||
public MultipartState state;
|
||||
public MultipartEntity entity;
|
||||
|
||||
private Entry(MultipartContainer container, MultipartState state, MultipartEntity entity) {
|
||||
private Entry(AbstractContainerBlockEntity container, MultipartState state, MultipartEntity entity) {
|
||||
this.container = container;
|
||||
this.state = state;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultipartContainer getContainer() {
|
||||
public AbstractContainerBlockEntity getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
|
@ -226,6 +260,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
|||
@Override
|
||||
public void setState(MultipartState state) {
|
||||
this.state = state;
|
||||
container.invalidateSidePartCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -236,6 +271,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
|||
@Override
|
||||
public void setEntity(MultipartEntity entity) {
|
||||
this.entity = entity;
|
||||
container.invalidateSidePartCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.shadowfacts.simplemultipart.container;
|
||||
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.shadowfacts.simplemultipart.multipart.MultipartView;
|
||||
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
||||
|
||||
|
@ -27,6 +28,26 @@ public interface MultipartContainer {
|
|||
*/
|
||||
boolean hasParts();
|
||||
|
||||
/**
|
||||
* Gets the part on the given side.
|
||||
*
|
||||
* Will return the part with the greatest/least min/max coordinate based on the direction's axis.
|
||||
* For example, getting the part on the {@code NORTH} side will return the part with the smallest minimum Z coordinate.
|
||||
* If multiple parts have the same min/max coordinate, which one will be returned is undefined.
|
||||
*
|
||||
* @param side The side to determine the part for.
|
||||
* @return The part on the given side.
|
||||
*/
|
||||
MultipartView getPart(Direction side);
|
||||
|
||||
/**
|
||||
* Containers store a cache of which part is on which side, calculated using the bounding box.
|
||||
*
|
||||
* If anything changes in your part that changes its bounding shape, this method should be called.
|
||||
* The container {@code insert}, {@code breakPart}, and {@code remove} methods automatically call this.
|
||||
*/
|
||||
void invalidateSidePartCache();
|
||||
|
||||
/**
|
||||
* Determines whether the given multipart state can be inserted into this container.
|
||||
* Checks that the bounding box of the new part does not intersect with any existing ones.
|
||||
|
|
|
@ -57,8 +57,7 @@ public class TestMultipart extends Multipart {
|
|||
@Override
|
||||
@Deprecated
|
||||
public boolean activate(MultipartView view, PlayerEntity player, Hand hand) {
|
||||
Direction side = view.getState().get(Properties.FACING);
|
||||
System.out.println("part activated on " + side);
|
||||
System.out.println(view.getContainer().getPart(Direction.UP));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue