Initial implementation of container getPart(Direction)
This commit is contained in:
parent
6ade580e85
commit
7c465d01f4
|
@ -12,9 +12,14 @@ version = "0.1.0"
|
||||||
minecraft {
|
minecraft {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:18w50a"
|
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"
|
modCompile "net.fabricmc:fabric-loader:0.3.1.80"
|
||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// 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.server.world.ServerWorld;
|
||||||
import net.minecraft.util.Tickable;
|
import net.minecraft.util.Tickable;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.world.loot.context.LootContext;
|
import net.minecraft.world.loot.context.LootContext;
|
||||||
import net.minecraft.world.loot.context.Parameters;
|
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 {
|
public abstract class AbstractContainerBlockEntity extends BlockEntity implements MultipartContainer, ClientSerializable {
|
||||||
|
|
||||||
protected Set<Entry> parts = new HashSet<>();
|
protected Set<Entry> parts = new HashSet<>();
|
||||||
|
protected Map<Direction, Entry> sidePartCache = new WeakHashMap<>();
|
||||||
|
|
||||||
public AbstractContainerBlockEntity(BlockEntityType<?> type) {
|
public AbstractContainerBlockEntity(BlockEntityType<?> type) {
|
||||||
super(type);
|
super(type);
|
||||||
|
@ -50,6 +52,36 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
||||||
return !parts.isEmpty();
|
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
|
@Override
|
||||||
public boolean canInsert(MultipartState partState) {
|
public boolean canInsert(MultipartState partState) {
|
||||||
VoxelShape newShape = partState.getBoundingShape(null);
|
VoxelShape newShape = partState.getBoundingShape(null);
|
||||||
|
@ -77,6 +109,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
||||||
}
|
}
|
||||||
parts.add(e);
|
parts.add(e);
|
||||||
|
|
||||||
|
invalidateSidePartCache();
|
||||||
updateWorld();
|
updateWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +124,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
||||||
if (parts.isEmpty()) {
|
if (parts.isEmpty()) {
|
||||||
world.setBlockState(pos, Blocks.AIR.getDefaultState());
|
world.setBlockState(pos, Blocks.AIR.getDefaultState());
|
||||||
} else {
|
} else {
|
||||||
|
invalidateSidePartCache();
|
||||||
updateWorld();
|
updateWorld();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,18 +237,18 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Entry implements MultipartView {
|
public static class Entry implements MultipartView {
|
||||||
public final MultipartContainer container;
|
public final AbstractContainerBlockEntity container;
|
||||||
public MultipartState state;
|
public MultipartState state;
|
||||||
public MultipartEntity entity;
|
public MultipartEntity entity;
|
||||||
|
|
||||||
private Entry(MultipartContainer container, MultipartState state, MultipartEntity entity) {
|
private Entry(AbstractContainerBlockEntity container, MultipartState state, MultipartEntity entity) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MultipartContainer getContainer() {
|
public AbstractContainerBlockEntity getContainer() {
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +260,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
||||||
@Override
|
@Override
|
||||||
public void setState(MultipartState state) {
|
public void setState(MultipartState state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
container.invalidateSidePartCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -236,6 +271,7 @@ public abstract class AbstractContainerBlockEntity extends BlockEntity implement
|
||||||
@Override
|
@Override
|
||||||
public void setEntity(MultipartEntity entity) {
|
public void setEntity(MultipartEntity entity) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
|
container.invalidateSidePartCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.shadowfacts.simplemultipart.container;
|
package net.shadowfacts.simplemultipart.container;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import net.shadowfacts.simplemultipart.multipart.MultipartView;
|
import net.shadowfacts.simplemultipart.multipart.MultipartView;
|
||||||
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
||||||
|
|
||||||
|
@ -27,6 +28,26 @@ public interface MultipartContainer {
|
||||||
*/
|
*/
|
||||||
boolean hasParts();
|
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.
|
* 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.
|
* 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
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean activate(MultipartView view, PlayerEntity player, Hand hand) {
|
public boolean activate(MultipartView view, PlayerEntity player, Hand hand) {
|
||||||
Direction side = view.getState().get(Properties.FACING);
|
System.out.println(view.getContainer().getPart(Direction.UP));
|
||||||
System.out.println("part activated on " + side);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue