diff --git a/src/api/java/appeng/api/parts/IBoxProvider.java b/src/api/java/appeng/api/parts/IBoxProvider.java deleted file mode 100644 index 105842f13..000000000 --- a/src/api/java/appeng/api/parts/IBoxProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2013 AlgorithmX2 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -package appeng.api.parts; - -public interface IBoxProvider { - - /** - * add your collision information to the the list. - * - * @param boxes collision boxes - */ - void getBoxes(IPartCollisionHelper boxes); -} diff --git a/src/api/java/appeng/api/parts/IFacadePart.java b/src/api/java/appeng/api/parts/IFacadePart.java index 8f7107d9d..752606fb6 100644 --- a/src/api/java/appeng/api/parts/IFacadePart.java +++ b/src/api/java/appeng/api/parts/IFacadePart.java @@ -45,10 +45,10 @@ public interface IFacadePart { /** * used to collide, and pick the part * - * @param ch collision helper - * @param e colliding entity + * @param ch collision helper + * @param livingEntity collision with a living entity? */ - void getBoxes(IPartCollisionHelper ch, Entity e); + void getBoxes(IPartCollisionHelper ch, boolean livingEntity); /** * @return side the facade is in diff --git a/src/api/java/appeng/api/parts/IPart.java b/src/api/java/appeng/api/parts/IPart.java index 3b2aa7e7a..05db17b45 100644 --- a/src/api/java/appeng/api/parts/IPart.java +++ b/src/api/java/appeng/api/parts/IPart.java @@ -56,7 +56,7 @@ import appeng.api.util.AECableType; import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; -public interface IPart extends IBoxProvider, ICustomCableConnection { +public interface IPart extends ICustomCableConnection { /** * get an ItemStack that represents the bus, should contain the settings for @@ -364,4 +364,11 @@ public interface IPart extends IBoxProvider, ICustomCableConnection { return EmptyModelData.INSTANCE; } + /** + * add your collision information to the the list. + * + * @param bch collision boxes + */ + void getBoxes(final IPartCollisionHelper bch); + } diff --git a/src/main/java/appeng/block/networking/CableBusBlock.java b/src/main/java/appeng/block/networking/CableBusBlock.java index cb538da79..21e712a39 100644 --- a/src/main/java/appeng/block/networking/CableBusBlock.java +++ b/src/main/java/appeng/block/networking/CableBusBlock.java @@ -370,36 +370,22 @@ public class CableBusBlock extends AEBaseTileBlock implement @Override public VoxelShape getShape(BlockState state, IBlockReader w, BlockPos pos, ISelectionContext context) { - - // FIXME: this has to be cached, optimized, fixed in all kinds of ways CableBusTileEntity te = getTileEntity(w, pos); - VoxelShape result = VoxelShapes.empty(); - if (te != null) { - for (final AxisAlignedBB bx : te.getCableBus().getSelectedBoundingBoxesFromPool(false, true, - context.getEntity(), true)) { - result = VoxelShapes.or(result, - VoxelShapes.create(new AxisAlignedBB(bx.minX, bx.minY, bx.minZ, bx.maxX, bx.maxY, bx.maxZ))); - } + if (te == null) { + return VoxelShapes.empty(); + } else { + return te.getCableBus().getShape(); } - return result; - } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader w, BlockPos pos, ISelectionContext context) { - - // FIXME: this has to be cached, optimized, fixed in all kinds of ways CableBusTileEntity te = getTileEntity(w, pos); - VoxelShape result = VoxelShapes.empty(); - if (te != null) { - for (final AxisAlignedBB bx : te.getCableBus().getSelectedBoundingBoxesFromPool(false, true, - context.getEntity(), false)) { - result = VoxelShapes.or(result, - VoxelShapes.create(new AxisAlignedBB(bx.minX, bx.minY, bx.minZ, bx.maxX, bx.maxY, bx.maxZ))); - } + if (te == null) { + return VoxelShapes.empty(); + } else { + return te.getCableBus().getCollisionShape(context.getEntity()); } - return result; - } } diff --git a/src/main/java/appeng/facade/FacadePart.java b/src/main/java/appeng/facade/FacadePart.java index 57801c1d0..e010a513d 100644 --- a/src/main/java/appeng/facade/FacadePart.java +++ b/src/main/java/appeng/facade/FacadePart.java @@ -20,18 +20,15 @@ package appeng.facade; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.entity.Entity; -import net.minecraft.entity.LivingEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import appeng.api.parts.IBoxProvider; import appeng.api.parts.IFacadePart; import appeng.api.parts.IPartCollisionHelper; import appeng.api.util.AEPartLocation; -public class FacadePart implements IFacadePart, IBoxProvider { +public class FacadePart implements IFacadePart { private final ItemStack facade; private final AEPartLocation side; @@ -51,8 +48,8 @@ public class FacadePart implements IFacadePart, IBoxProvider { } @Override - public void getBoxes(final IPartCollisionHelper ch, final Entity e) { - if (e instanceof LivingEntity) { + public void getBoxes(final IPartCollisionHelper ch, boolean livingEntity) { + if (livingEntity) { // prevent weird snag behavior ch.addBox(0.0, 0.0, 14, 16.0, 16.0, 16.0); } else { @@ -108,8 +105,4 @@ public class FacadePart implements IFacadePart, IBoxProvider { return Blocks.GLASS.getDefaultState(); } - @Override - public void getBoxes(final IPartCollisionHelper bch) { - this.getBoxes(bch, null); - } } diff --git a/src/main/java/appeng/parts/BusCollisionHelper.java b/src/main/java/appeng/parts/BusCollisionHelper.java index 2078abda4..93d1a65c6 100644 --- a/src/main/java/appeng/parts/BusCollisionHelper.java +++ b/src/main/java/appeng/parts/BusCollisionHelper.java @@ -20,7 +20,6 @@ package appeng.parts; import java.util.List; -import net.minecraft.entity.Entity; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; @@ -35,23 +34,19 @@ public class BusCollisionHelper implements IPartCollisionHelper { private final Direction y; private final Direction z; - private final Entity entity; private final boolean isVisual; public BusCollisionHelper(final List boxes, final Direction x, final Direction y, final Direction z, - final Entity e, final boolean visual) { + final boolean visual) { this.boxes = boxes; this.x = x; this.y = y; this.z = z; - this.entity = e; this.isVisual = visual; } - public BusCollisionHelper(final List boxes, final AEPartLocation s, final Entity e, - final boolean visual) { + public BusCollisionHelper(final List boxes, final AEPartLocation s, final boolean visual) { this.boxes = boxes; - this.entity = e; this.isVisual = visual; switch (s) { @@ -94,13 +89,6 @@ public class BusCollisionHelper implements IPartCollisionHelper { } } - /** - * pretty much useless... - */ - public Entity getEntity() { - return this.entity; - } - @Override public void addBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { minX /= 16.0; diff --git a/src/main/java/appeng/parts/CableBusContainer.java b/src/main/java/appeng/parts/CableBusContainer.java index d362ecc46..2f4741ffa 100644 --- a/src/main/java/appeng/parts/CableBusContainer.java +++ b/src/main/java/appeng/parts/CableBusContainer.java @@ -37,6 +37,8 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; @@ -71,6 +73,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I // TODO 1.10.2-R - does somebody seriously want to make parts TESR??? Hope not. private boolean requiresDynamicRender = false; private boolean inWorld = false; + // Cached collision shape for living entities + private VoxelShape cachedCollisionShapeLiving; + // Cached collision shape for anything but living entities + private VoxelShape cachedCollisionShape; + private VoxelShape cachedShape; public CableBusContainer(final IPartHost host) { this.tcb = host; @@ -210,6 +217,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } } + this.invalidateShapes(); this.updateConnections(); this.markForUpdate(); this.markForSave(); @@ -249,6 +257,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } } + this.invalidateShapes(); this.updateDynamicRender(); this.updateConnections(); this.markForUpdate(); @@ -289,6 +298,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } if (!suppressUpdate) { + this.invalidateShapes(); this.updateDynamicRender(); this.updateConnections(); this.markForUpdate(); @@ -338,7 +348,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I if (p != null) { final List boxes = new ArrayList<>(); - final IPartCollisionHelper bch = new BusCollisionHelper(boxes, side, null, true); + final IPartCollisionHelper bch = new BusCollisionHelper(boxes, side, true); p.getBoxes(bch); for (AxisAlignedBB bb : boxes) { bb = bb.grow(0.002, 0.002, 0.002); @@ -356,8 +366,8 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I if (p != null) { final List boxes = new ArrayList<>(); - final IPartCollisionHelper bch = new BusCollisionHelper(boxes, side, null, true); - p.getBoxes(bch, null); + final IPartCollisionHelper bch = new BusCollisionHelper(boxes, side, true); + p.getBoxes(bch, true); for (AxisAlignedBB bb : boxes) { bb = bb.grow(0.01, 0.01, 0.01); if (bb.contains(pos)) { @@ -545,6 +555,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } } + this.invalidateShapes(); this.partChanged(); } @@ -599,36 +610,6 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } } - public Iterable getSelectedBoundingBoxesFromPool(final boolean ignoreConnections, - final boolean includeFacades, final Entity e, final boolean visual) { - final List boxes = new ArrayList<>(); - - final IFacadeContainer fc = this.getFacadeContainer(); - for (final AEPartLocation s : AEPartLocation.values()) { - final IPartCollisionHelper bch = new BusCollisionHelper(boxes, s, e, visual); - - final IPart part = this.getPart(s); - if (part != null) { - if (ignoreConnections && part instanceof ICablePart) { - bch.addBox(6.0, 6.0, 6.0, 10.0, 10.0, 10.0); - } else { - part.getBoxes(bch); - } - } - - if (AEApi.instance().partHelper().getCableRenderMode().opaqueFacades || !visual) { - if (includeFacades && s != null && s != AEPartLocation.INTERNAL) { - final IFacadePart fp = fc.getFacade(s); - if (fp != null) { - fp.getBoxes(bch, e); - } - } - } - } - - return boxes; - } - @Override public int isProvidingStrongPower(final Direction side) { final IPart part = this.getPart(side); @@ -699,6 +680,9 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I part.onNeighborChanged(w, pos, neighbor); } } + + // Some parts will change their shape (connected texture style) + invalidateShapes(); } @Override @@ -798,9 +782,10 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } } - if (this.getFacadeContainer().readFromStream(data)) { - return true; - } + updateBlock |= this.getFacadeContainer().readFromStream(data); + + // Updating tiles may change the collision shape + this.invalidateShapes(); return updateBlock; } @@ -841,6 +826,8 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I } public void readFromNBT(final CompoundNBT data) { + invalidateShapes(); + if (data.contains("hasRedstone")) { this.hasRedstone = YesNo.values()[data.getInt("hasRedstone")]; } @@ -1006,8 +993,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I // This will add the part's bounding boxes to the render state, which is // required for facades final AEPartLocation loc = AEPartLocation.fromFacing(facing); - final IPartCollisionHelper bch = new BusCollisionHelper(renderState.getBoundingBoxes(), loc, null, true); - + final IPartCollisionHelper bch = new BusCollisionHelper(renderState.getBoundingBoxes(), loc, true); part.getBoxes(bch); if (part instanceof IGridHost) { @@ -1049,4 +1035,71 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I return null; } + + /** + * See {@link net.minecraft.block.Block#getShape} + */ + public VoxelShape getShape() { + if (cachedShape == null) { + cachedShape = createShape(false, false); + } + + return cachedShape; + } + + /** + * See {@link net.minecraft.block.Block#getCollisionShape} + */ + public VoxelShape getCollisionShape(Entity entity) { + // This is a hack for facades + boolean livingEntity = entity instanceof LivingEntity; + + if (livingEntity) { + if (cachedCollisionShapeLiving == null) { + cachedCollisionShapeLiving = createShape(true, true); + } + return cachedCollisionShapeLiving; + } else { + if (cachedCollisionShape == null) { + cachedCollisionShape = createShape(true, false); + } + return cachedCollisionShape; + } + } + + private VoxelShape createShape(boolean forCollision, boolean forLivingEntity) { + final List boxes = new ArrayList<>(); + + final IFacadeContainer fc = this.getFacadeContainer(); + for (final AEPartLocation s : AEPartLocation.values()) { + final IPartCollisionHelper bch = new BusCollisionHelper(boxes, s, !forCollision); + + final IPart part = this.getPart(s); + if (part != null) { + part.getBoxes(bch); + } + + if (AEApi.instance().partHelper().getCableRenderMode().opaqueFacades || forCollision) { + if (s != AEPartLocation.INTERNAL) { + final IFacadePart fp = fc.getFacade(s); + if (fp != null) { + fp.getBoxes(bch, forLivingEntity); + } + } + } + } + + VoxelShape shape = VoxelShapes.empty(); + for (final AxisAlignedBB bx : boxes) { + shape = VoxelShapes.or(shape, VoxelShapes.create(bx)); + } + return shape; + } + + private void invalidateShapes() { + cachedShape = null; + cachedCollisionShape = null; + cachedCollisionShapeLiving = null; + } + }