Initial implementation of container getPart(Direction)

This commit is contained in:
Shadowfacts 2018-12-29 18:33:16 -05:00
parent 6ade580e85
commit 7c465d01f4
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 67 additions and 6 deletions

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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;
}