Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts: # src/main/java/appeng/client/gui/AEBaseScreen.java # src/main/java/appeng/client/gui/widgets/CustomSlotWidget.java # src/main/java/appeng/client/gui/widgets/ITooltip.java # src/main/java/appeng/client/gui/widgets/IconButton.java # src/main/java/appeng/client/gui/widgets/ProgressBar.java # src/main/java/appeng/client/gui/widgets/SettingToggleButton.java # src/main/java/appeng/client/gui/widgets/ToggleButton.java # src/main/java/appeng/container/slot/PlayerInvSlot.java # src/main/java/appeng/fluids/client/gui/widgets/FluidSlotWidget.java # src/main/java/appeng/fluids/client/gui/widgets/FluidTankWidget.java # src/main/java/appeng/fluids/client/gui/widgets/OptionalFluidSlotWidget.java # src/main/java/appeng/fluids/parts/FluidAnnihilationPlanePart.java # src/main/java/appeng/parts/automation/AbstractFormationPlanePart.java # src/main/java/appeng/parts/automation/AnnihilationPlanePart.java # src/main/java/appeng/parts/automation/FormationPlanePart.java # src/main/java/appeng/parts/automation/IdentityAnnihilationPlanePart.java # src/main/java/appeng/parts/p2p/FluidP2PTunnelPart.java
This commit is contained in:
@@ -168,14 +168,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
protected void drawGuiSlot(MatrixStack matrices, CustomSlotWidget slot, int mouseX, int mouseY,
|
||||
float partialTicks) {
|
||||
if (slot.isSlotEnabled()) {
|
||||
final int left = slot.xPos();
|
||||
final int top = slot.yPos();
|
||||
final int right = left + slot.getWidth();
|
||||
final int bottom = top + slot.getHeight();
|
||||
final int left = slot.getTooltipAreaX();
|
||||
final int top = slot.getTooltipAreaY();
|
||||
final int right = left + slot.getTooltipAreaWidth();
|
||||
final int bottom = top + slot.getTooltipAreaHeight();
|
||||
|
||||
slot.drawContent(getClient(), mouseX, mouseY, partialTicks);
|
||||
|
||||
if (this.isPointWithinBounds(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY)
|
||||
if (this.isPointWithinBounds(left, top, slot.getTooltipAreaWidth(), slot.getTooltipAreaHeight(), mouseX, mouseY)
|
||||
&& slot.canClick(getPlayer())) {
|
||||
RenderSystem.colorMask(true, true, true, false);
|
||||
this.fillGradient(matrices, left, top, right, bottom, -2130706433, -2130706433);
|
||||
@@ -185,27 +185,28 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
|
||||
private void drawTooltip(MatrixStack matrices, ITooltip tooltip, int mouseX, int mouseY) {
|
||||
final int x = tooltip.xPos();
|
||||
int y = tooltip.yPos();
|
||||
final int x = tooltip.getTooltipAreaX();
|
||||
int y = tooltip.getTooltipAreaY();
|
||||
|
||||
if (x < mouseX && x + tooltip.getWidth() > mouseX && tooltip.isVisible()) {
|
||||
if (y < mouseY && y + tooltip.getHeight() > mouseY) {
|
||||
if (x < mouseX && x + tooltip.getTooltipAreaWidth() > mouseX && tooltip.isTooltipAreaVisible()) {
|
||||
if (y < mouseY && y + tooltip.getTooltipAreaHeight() > mouseY) {
|
||||
if (y < 15) {
|
||||
y = 15;
|
||||
}
|
||||
|
||||
final Text msg = tooltip.getMessage();
|
||||
if (msg != null && !msg.getString().isEmpty()) {
|
||||
this.drawTooltip(matrices, x + 11, y + 4, msg);
|
||||
}
|
||||
final Text msg = tooltip.getTooltipMessage();
|
||||
this.drawTooltip(matrices, x + 11, y + 4, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawTooltip(MatrixStack matrices, int x, int y, Text message) {
|
||||
String[] lines = message.getString().split("\n"); // FIXME FABRIC
|
||||
List<Text> textLines = Arrays.stream(lines).map(LiteralText::new).collect(Collectors.toList());
|
||||
this.drawTooltip(matrices, x, y, textLines);
|
||||
String tooltipText = message.getString();
|
||||
|
||||
if (!tooltipText.isEmpty()) {
|
||||
String[] lines = tooltipText.split("\n"); // FIXME FABRIC
|
||||
List<Text> textLines = Arrays.stream(lines).map(LiteralText::new).collect(Collectors.toList());
|
||||
this.drawTooltip(matrices, x, y, textLines);}
|
||||
}
|
||||
|
||||
// FIXME FABRIC: move out to json (?)
|
||||
@@ -290,8 +291,8 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
|
||||
for (CustomSlotWidget slot : this.guiSlots) {
|
||||
if (this.isPointWithinBounds(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord)
|
||||
&& slot.canClick(getPlayer())) {
|
||||
if (this.isPointWithinBounds(slot.getTooltipAreaX(), slot.getTooltipAreaY(), slot.getTooltipAreaWidth(),
|
||||
slot.getTooltipAreaHeight(), xCoord, yCoord) && slot.canClick(getPlayer())) {
|
||||
slot.slotClicked(getPlayer().inventory.getCursorStack(), btn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import net.minecraft.text.Text;
|
||||
import appeng.api.config.ActionItems;
|
||||
import appeng.core.localization.ButtonToolTips;
|
||||
|
||||
public class ActionButton extends IconButton implements ITooltip {
|
||||
public class ActionButton extends IconButton {
|
||||
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
|
||||
private final int iconIndex;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public abstract class CustomSlotWidget extends DrawableHelper implements ITooltip {
|
||||
@@ -37,32 +38,32 @@ public abstract class CustomSlotWidget extends DrawableHelper implements IToolti
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
return null;
|
||||
public Text getTooltipMessage() {
|
||||
return LiteralText.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
public int getTooltipAreaX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
public int getTooltipAreaY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
public int getTooltipAreaWidth() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
public int getTooltipAreaHeight() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,48 +20,53 @@ package appeng.client.gui.widgets;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* AEBaseGui controlled Tooltip Interface.
|
||||
*/
|
||||
public interface ITooltip {
|
||||
|
||||
/**
|
||||
* returns the tooltip message.
|
||||
* Returns the tooltip message.
|
||||
*
|
||||
* Should use {@link net.minecraft.text.LiteralText#EMPTY} for no tooltip
|
||||
*
|
||||
* @return tooltip message
|
||||
*/
|
||||
Text getMessage();
|
||||
@Nonnull
|
||||
Text getTooltipMessage();
|
||||
|
||||
/**
|
||||
* x Location for the object that triggers the tooltip.
|
||||
*
|
||||
* @return xPosition
|
||||
*/
|
||||
int xPos();
|
||||
int getTooltipAreaX();
|
||||
|
||||
/**
|
||||
* y Location for the object that triggers the tooltip.
|
||||
*
|
||||
* @return yPosition
|
||||
*/
|
||||
int yPos();
|
||||
int getTooltipAreaY();
|
||||
|
||||
/**
|
||||
* Width of the object that triggers the tooltip.
|
||||
*
|
||||
* @return width
|
||||
*/
|
||||
int getWidth();
|
||||
int getTooltipAreaWidth();
|
||||
|
||||
/**
|
||||
* Height for the object that triggers the tooltip.
|
||||
*
|
||||
* @return height
|
||||
*/
|
||||
int getHeight();
|
||||
int getTooltipAreaHeight();
|
||||
|
||||
/**
|
||||
* @return true if button being drawn
|
||||
*/
|
||||
boolean isVisible();
|
||||
boolean isTooltipAreaVisible();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.texture.TextureManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
@@ -95,27 +96,32 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
protected abstract int getIconIndex();
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
public Text getTooltipMessage() {
|
||||
return getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTooltipAreaX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
public int getTooltipAreaY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
public int getTooltipAreaWidth() {
|
||||
return this.halfSize ? 8 : 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
public int getTooltipAreaHeight() {
|
||||
return this.halfSize ? 8 : 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ public class ProgressBar extends AbstractButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
public Text getTooltipMessage() {
|
||||
if (this.fullMsg != null) {
|
||||
return this.fullMsg;
|
||||
}
|
||||
@@ -88,27 +88,27 @@ public class ProgressBar extends AbstractButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
public int getTooltipAreaX() {
|
||||
return this.x - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
public int getTooltipAreaY() {
|
||||
return this.y - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
public int getTooltipAreaWidth() {
|
||||
return this.width + 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
public int getTooltipAreaHeight() {
|
||||
return this.height + 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
public Text getTooltipMessage() {
|
||||
Text displayName = null;
|
||||
Text displayValue = null;
|
||||
|
||||
|
||||
@@ -93,27 +93,32 @@ public class TabButton extends ButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
public ITextComponent getTooltipMessage() {
|
||||
return getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTooltipAreaX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
public int getTooltipAreaY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
public int getTooltipAreaWidth() {
|
||||
return 22;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
public int getTooltipAreaHeight() {
|
||||
return 22;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public class ToggleButton extends ButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
public Text getTooltipMessage() {
|
||||
if (this.displayName != null) {
|
||||
String name = this.displayName.getString();
|
||||
String value = this.displayHint.getString();
|
||||
@@ -96,27 +96,27 @@ public class ToggleButton extends ButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
public int getTooltipAreaX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
public int getTooltipAreaY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
public int getTooltipAreaWidth() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
public int getTooltipAreaHeight() {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
|
||||
return helper.open(player, locator);
|
||||
}
|
||||
|
||||
@GuiSync(6)
|
||||
@GuiSync(7)
|
||||
public YesNo placeMode;
|
||||
|
||||
public FormationPlaneContainer(int id, final PlayerInventory ip, final FormationPlanePart te) {
|
||||
|
||||
@@ -49,7 +49,7 @@ public class FacadePart implements IFacadePart {
|
||||
|
||||
@Override
|
||||
public void getBoxes(final IPartCollisionHelper ch, boolean livingEntity) {
|
||||
if (livingEntity) {
|
||||
if (livingEntity || !ch.isBBCollision()) {
|
||||
// prevent weird snag behavior
|
||||
ch.addBox(0.0, 0.0, 14, 16.0, 16.0, 16.0);
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.Set;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import alexiil.mc.lib.attributes.fluid.FluidAttributes;
|
||||
@@ -35,7 +36,12 @@ public class FluidSlotWidget extends CustomSlotWidget {
|
||||
public void drawContent(final MinecraftClient mc, final int mouseX, final int mouseY, final float partialTicks) {
|
||||
final IAEFluidStack fs = this.getFluidStack();
|
||||
if (fs != null) {
|
||||
fs.getFluidStack().renderGuiRect(xPos(), yPos(), xPos() + getWidth(), yPos() + getHeight());
|
||||
// The tooltip area coincides with the area of the slot
|
||||
int x = getTooltipAreaX();
|
||||
int y = getTooltipAreaY();
|
||||
int width = getTooltipAreaX();
|
||||
int height = getTooltipAreaY();
|
||||
fs.getFluidStack().renderGuiRect(x, y, x + width, y + height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,16 +67,16 @@ public class FluidSlotWidget extends CustomSlotWidget {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
public Text getTooltipMessage() {
|
||||
final IAEFluidStack fluid = this.getFluidStack();
|
||||
if (fluid != null) {
|
||||
return fluid.getFluidStack().getName();
|
||||
}
|
||||
return null;
|
||||
return LiteralText.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class FluidTankWidget extends AbstractButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
public Text getTooltipMessage() {
|
||||
final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot);
|
||||
if (fluid != null && fluid.getStackSize() > 0) {
|
||||
Text desc = fluid.getFluidStack().getName();
|
||||
@@ -95,27 +95,27 @@ public class FluidTankWidget extends AbstractButtonWidget implements ITooltip {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
public int getTooltipAreaX() {
|
||||
return this.x - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
public int getTooltipAreaY() {
|
||||
return this.y - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
public int getTooltipAreaWidth() {
|
||||
return this.width + 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
public int getTooltipAreaHeight() {
|
||||
return this.height + 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
public boolean isTooltipAreaVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ public class OptionalFluidSlotWidget extends FluidSlotWidget {
|
||||
}
|
||||
int oldZOffset = getZOffset();
|
||||
setZOffset(currentZIndex);
|
||||
drawTexture(matrices, guileft + this.xPos() - 1, guitop + this.yPos() - 1, this.srcX - 1, this.srcY - 1,
|
||||
this.getWidth() + 2, this.getHeight() + 2);
|
||||
drawTexture(matrices, guileft + this.getTooltipAreaX() - 1, guitop + this.getTooltipAreaY() - 1, this.srcX - 1, this.srcY - 1,
|
||||
this.getTooltipAreaWidth() + 2, this.getTooltipAreaHeight() + 2);
|
||||
setZOffset(oldZOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,15 +38,12 @@ import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.networking.ticking.IGridTickable;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.parts.IPartCollisionHelper;
|
||||
import appeng.api.parts.IPartHost;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.settings.TickRates;
|
||||
@@ -56,6 +53,7 @@ import appeng.items.parts.PartModels;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.parts.BasicStatePart;
|
||||
import appeng.parts.automation.PlaneConnectionHelper;
|
||||
import appeng.parts.automation.PlaneConnections;
|
||||
import appeng.parts.automation.PlaneModels;
|
||||
import appeng.util.Platform;
|
||||
@@ -75,115 +73,27 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
|
||||
|
||||
private final IActionSource mySrc = new MachineSource(this);
|
||||
|
||||
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
|
||||
|
||||
public FluidAnnihilationPlanePart(final ItemStack is) {
|
||||
super(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBoxes(final IPartCollisionHelper bch) {
|
||||
int minX = 1;
|
||||
int minY = 1;
|
||||
int maxX = 15;
|
||||
int maxY = 15;
|
||||
|
||||
final IPartHost host = this.getHost();
|
||||
if (host != null) {
|
||||
final BlockEntity te = host.getTile();
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
final Direction e = bch.getWorldX();
|
||||
final Direction u = bch.getWorldY();
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(e.getOpposite())), this.getSide())) {
|
||||
minX = 0;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(e)), this.getSide())) {
|
||||
maxX = 16;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(u.getOpposite())), this.getSide())) {
|
||||
minY = 0;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(e)), this.getSide())) {
|
||||
maxY = 16;
|
||||
}
|
||||
}
|
||||
|
||||
bch.addBox(5, 5, 14, 11, 11, 15);
|
||||
bch.addBox(minX, minY, 15, maxX, maxY, 16);
|
||||
connectionHelper.getBoxes(bch);
|
||||
}
|
||||
|
||||
public PlaneConnections getConnections() {
|
||||
|
||||
final Direction facingRight, facingUp;
|
||||
AEPartLocation location = this.getSide();
|
||||
switch (location) {
|
||||
case UP:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case DOWN:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case NORTH:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case SOUTH:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case WEST:
|
||||
facingRight = Direction.SOUTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case EAST:
|
||||
facingRight = Direction.NORTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
default:
|
||||
case INTERNAL:
|
||||
return PlaneConnections.of(false, false, false, false);
|
||||
}
|
||||
|
||||
boolean left = false, right = false, down = false, up = false;
|
||||
|
||||
final IPartHost host = this.getHost();
|
||||
if (host != null) {
|
||||
final BlockEntity te = host.getTile();
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingRight.getOpposite())),
|
||||
this.getSide())) {
|
||||
left = true;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingRight)), this.getSide())) {
|
||||
right = true;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingUp.getOpposite())),
|
||||
this.getSide())) {
|
||||
down = true;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingUp)), this.getSide())) {
|
||||
up = true;
|
||||
}
|
||||
}
|
||||
|
||||
return PlaneConnections.of(up, right, down, left);
|
||||
return connectionHelper.getConnections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onneighborUpdate(BlockView w, BlockPos pos, BlockPos neighbor) {
|
||||
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
|
||||
this.refresh();
|
||||
} else {
|
||||
connectionHelper.updateConnections();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,14 +102,6 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
|
||||
return 1;
|
||||
}
|
||||
|
||||
private boolean isAnnihilationPlane(final BlockEntity blockTileEntity, final AEPartLocation side) {
|
||||
if (blockTileEntity instanceof IPartHost) {
|
||||
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
|
||||
return p != null && p.getClass() == this.getClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
try {
|
||||
this.getProxy().getTick().alertDevice(this.getProxy().getNode());
|
||||
|
||||
@@ -11,9 +11,7 @@ import net.minecraft.world.BlockView;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.parts.IPartCollisionHelper;
|
||||
import appeng.api.parts.IPartHost;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.cells.ICellContainer;
|
||||
import appeng.api.storage.cells.ICellInventory;
|
||||
@@ -30,6 +28,7 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
|
||||
private boolean wasActive = false;
|
||||
private int priority = 0;
|
||||
protected boolean blocked = false;
|
||||
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
|
||||
|
||||
public AbstractFormationPlanePart(ItemStack is) {
|
||||
super(is);
|
||||
@@ -64,103 +63,11 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
|
||||
|
||||
@Override
|
||||
public void getBoxes(final IPartCollisionHelper bch) {
|
||||
int minX = 1;
|
||||
int minY = 1;
|
||||
int maxX = 15;
|
||||
int maxY = 15;
|
||||
|
||||
final IPartHost host = this.getHost();
|
||||
if (host != null) {
|
||||
final BlockEntity te = host.getTile();
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
final Direction e = bch.getWorldX();
|
||||
final Direction u = bch.getWorldY();
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(e.getOpposite())), this.getSide())) {
|
||||
minX = 0;
|
||||
}
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(e)), this.getSide())) {
|
||||
maxX = 16;
|
||||
}
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(u.getOpposite())), this.getSide())) {
|
||||
minY = 0;
|
||||
}
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(u)), this.getSide())) {
|
||||
maxY = 16;
|
||||
}
|
||||
}
|
||||
|
||||
bch.addBox(5, 5, 14, 11, 11, 15);
|
||||
bch.addBox(minX, minY, 15, maxX, maxY, 16);
|
||||
connectionHelper.getBoxes(bch);
|
||||
}
|
||||
|
||||
public PlaneConnections getConnections() {
|
||||
|
||||
final Direction facingRight, facingUp;
|
||||
AEPartLocation location = this.getSide();
|
||||
switch (location) {
|
||||
case UP:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case DOWN:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case NORTH:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case SOUTH:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case WEST:
|
||||
facingRight = Direction.SOUTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case EAST:
|
||||
facingRight = Direction.NORTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
default:
|
||||
case INTERNAL:
|
||||
return PlaneConnections.of(false, false, false, false);
|
||||
}
|
||||
|
||||
boolean left = false, right = false, down = false, up = false;
|
||||
|
||||
final IPartHost host = this.getHost();
|
||||
if (host != null) {
|
||||
final BlockEntity te = host.getTile();
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(facingRight.getOpposite())),
|
||||
this.getSide())) {
|
||||
left = true;
|
||||
}
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(facingRight)), this.getSide())) {
|
||||
right = true;
|
||||
}
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(facingUp.getOpposite())),
|
||||
this.getSide())) {
|
||||
down = true;
|
||||
}
|
||||
|
||||
if (this.isTransitionPlane(te.getWorld().getBlockEntity(pos.offset(facingUp)), this.getSide())) {
|
||||
up = true;
|
||||
}
|
||||
}
|
||||
|
||||
return PlaneConnections.of(up, right, down, left);
|
||||
return connectionHelper.getConnections();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,6 +79,8 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
|
||||
final BlockPos tePos = te.getPos().offset(side.getFacing());
|
||||
|
||||
this.blocked = isBlocking(w, tePos);
|
||||
} else {
|
||||
connectionHelper.updateConnections();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,14 +93,6 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected boolean isTransitionPlane(final BlockEntity blockTileEntity, final AEPartLocation side) {
|
||||
if (blockTileEntity instanceof IPartHost) {
|
||||
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
|
||||
return p != null && this.getClass() == p.getClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable mode, final IActionSource src) {
|
||||
return null;
|
||||
|
||||
@@ -60,9 +60,7 @@ import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.networking.ticking.IGridTickable;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.parts.IPartCollisionHelper;
|
||||
import appeng.api.parts.IPartHost;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
@@ -98,53 +96,31 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
|
||||
private boolean isAccepting = true;
|
||||
private boolean breaking = false;
|
||||
|
||||
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
|
||||
|
||||
public AnnihilationPlanePart(final ItemStack is) {
|
||||
super(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation call(final World world) throws Exception {
|
||||
public TickRateModulation call(final World world) {
|
||||
this.breaking = false;
|
||||
return this.breakBlock(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBoxes(final IPartCollisionHelper bch) {
|
||||
int minX = 1;
|
||||
int minY = 1;
|
||||
int maxX = 15;
|
||||
int maxY = 15;
|
||||
|
||||
final IPartHost host = this.getHost();
|
||||
if (host != null) {
|
||||
final BlockEntity te = host.getTile();
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
final Direction e = bch.getWorldX();
|
||||
final Direction u = bch.getWorldY();
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(e.getOpposite())), this.getSide())) {
|
||||
minX = 0;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(e)), this.getSide())) {
|
||||
maxX = 16;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(u.getOpposite())), this.getSide())) {
|
||||
minY = 0;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(e)), this.getSide())) {
|
||||
maxY = 16;
|
||||
}
|
||||
// For collision, we're using a simplified bounding box
|
||||
if (bch.isBBCollision()) {
|
||||
// The smaller collision hitbox here is needed to allow for the entity collision
|
||||
// event
|
||||
bch.addBox(0, 0, 14, 16, 16, 15.5);
|
||||
return;
|
||||
}
|
||||
|
||||
bch.addBox(5, 5, 14, 11, 11, 15);
|
||||
// The smaller collision hitbox here is needed to allow for the entity collision
|
||||
// event
|
||||
bch.addBox(minX, minY, 15, maxX, maxY, bch.isBBCollision() ? 15 : 16);
|
||||
connectionHelper.getBoxes(bch);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,73 +128,15 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
|
||||
* visually.
|
||||
*/
|
||||
public PlaneConnections getConnections() {
|
||||
|
||||
final Direction facingRight, facingUp;
|
||||
AEPartLocation location = this.getSide();
|
||||
switch (location) {
|
||||
case UP:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case DOWN:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case NORTH:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case SOUTH:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case WEST:
|
||||
facingRight = Direction.SOUTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case EAST:
|
||||
facingRight = Direction.NORTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
default:
|
||||
case INTERNAL:
|
||||
return PlaneConnections.of(false, false, false, false);
|
||||
}
|
||||
|
||||
boolean left = false, right = false, down = false, up = false;
|
||||
|
||||
final IPartHost host = this.getHost();
|
||||
if (host != null) {
|
||||
final BlockEntity te = host.getTile();
|
||||
|
||||
final BlockPos pos = te.getPos();
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingRight.getOpposite())),
|
||||
this.getSide())) {
|
||||
left = true;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingRight)), this.getSide())) {
|
||||
right = true;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingUp.getOpposite())),
|
||||
this.getSide())) {
|
||||
down = true;
|
||||
}
|
||||
|
||||
if (this.isAnnihilationPlane(te.getWorld().getBlockEntity(pos.offset(facingUp)), this.getSide())) {
|
||||
up = true;
|
||||
}
|
||||
}
|
||||
|
||||
return PlaneConnections.of(up, right, down, left);
|
||||
return connectionHelper.getConnections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onneighborUpdate(BlockView w, BlockPos pos, BlockPos neighbor) {
|
||||
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
|
||||
this.refresh();
|
||||
} else {
|
||||
connectionHelper.updateConnections();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,14 +281,6 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
|
||||
return changed;
|
||||
}
|
||||
|
||||
protected boolean isAnnihilationPlane(final BlockEntity blockTileEntity, final AEPartLocation side) {
|
||||
if (blockTileEntity instanceof IPartHost) {
|
||||
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
|
||||
return p != null && p.getClass() == this.getClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@MENetworkEventSubscribe
|
||||
public void chanRender(final MENetworkChannelsChanged c) {
|
||||
|
||||
@@ -21,11 +21,13 @@ package appeng.parts.automation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.*;
|
||||
@@ -49,7 +51,6 @@ import appeng.api.networking.events.MENetworkChannelsChanged;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.api.networking.events.MENetworkPowerStatusChange;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.parts.IPartItem;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
@@ -76,6 +77,7 @@ import appeng.util.prioritylist.PrecisePriorityList;
|
||||
public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack> {
|
||||
|
||||
private static final PlaneModels MODELS = new PlaneModels("part/formation_plane", "part/formation_plane_on");
|
||||
private static final Random RANDOM_OFFSET = new Random();
|
||||
|
||||
@PartModels
|
||||
public static List<IPartModel> getModels() {
|
||||
@@ -214,12 +216,12 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
||||
final BlockPos placePos = te.getPos().offset(side.getFacing());
|
||||
|
||||
if (w.getBlockState(placePos).getMaterial().isReplaceable()) {
|
||||
if (placeBlock == YesNo.YES && (i instanceof BlockItem || i instanceof FireworkChargeItem
|
||||
|| i instanceof FireworkItem || i instanceof IPartItem)) {
|
||||
if (placeBlock == YesNo.YES) {
|
||||
final PlayerEntity player = FakePlayer.getOrCreate(serverWorld);
|
||||
Platform.configurePlayer(player, side, this.getTile());
|
||||
Hand hand = player.getActiveHand();
|
||||
player.setStackInHand(hand, is);
|
||||
// Seems to work without...
|
||||
// Hand hand = player.getActiveHand();
|
||||
// player.setStackInHand(hand, is);
|
||||
|
||||
maxStorage = is.getCount();
|
||||
worked = true;
|
||||
@@ -227,83 +229,33 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
||||
// The side the plane is attached to will be considered the look direction
|
||||
// in terms of placing an item
|
||||
Direction lookDirection = side.getFacing();
|
||||
PlaneDirectionalPlaceContext context = new PlaneDirectionalPlaceContext(w, player, placePos,
|
||||
lookDirection, is, lookDirection.getOpposite());
|
||||
|
||||
// FIXME No idea what any of this is _supposed_ to do, comment badly needed
|
||||
if (i instanceof WallStandingBlockItem) {
|
||||
boolean Worked = false;
|
||||
i.onItemUse(context);
|
||||
maxStorage -= is.getCount();
|
||||
|
||||
// Up or Down, Attempt 1??
|
||||
if (side.xOffset == 0 && side.zOffset == 0) {
|
||||
Worked = i
|
||||
.useOnBlock(new AutomaticItemPlacementContext(w, placePos.offset(side.getFacing()),
|
||||
lookDirection, is, side.getFacing())) == ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
// Up or Down, Attempt 2??
|
||||
if (!Worked && side.xOffset == 0 && side.zOffset == 0) {
|
||||
Worked = i.useOnBlock(new AutomaticItemPlacementContext(w,
|
||||
placePos.offset(side.getFacing().getOpposite()), lookDirection, is,
|
||||
side.getFacing().getOpposite())) == ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
// Horizontal, attempt 1??
|
||||
if (!Worked && side.yOffset == 0) {
|
||||
Worked = i.useOnBlock(new AutomaticItemPlacementContext(w, placePos.offset(Direction.DOWN),
|
||||
lookDirection, is, Direction.DOWN)) == ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if (!Worked) {
|
||||
i.useOnBlock(new AutomaticItemPlacementContext(w, placePos, lookDirection, is,
|
||||
lookDirection.getOpposite()));
|
||||
}
|
||||
|
||||
maxStorage -= is.getCount();
|
||||
} else {
|
||||
i.useOnBlock(new AutomaticItemPlacementContext(w, placePos, lookDirection, is,
|
||||
lookDirection.getOpposite()));
|
||||
maxStorage -= is.getCount();
|
||||
}
|
||||
} else {
|
||||
maxStorage = 1;
|
||||
}
|
||||
|
||||
// Safe keeping
|
||||
player.setStackInHand(hand, ItemStack.EMPTY);
|
||||
// Seems to work without... Safe keeping
|
||||
// player.setStackInHand(hand, ItemStack.EMPTY);
|
||||
} else {
|
||||
worked = true;
|
||||
|
||||
final int sum = this.countEntitesAround(w, placePos);
|
||||
|
||||
// Disable spawning once there is a certain amount of entities in an area.
|
||||
if (sum < AEConfig.instance().getFormationPlaneEntityLimit()) {
|
||||
worked = true;
|
||||
|
||||
if (type == Actionable.MODULATE) {
|
||||
is.setCount((int) maxStorage);
|
||||
final double x = (side.xOffset != 0 ? 0 : .7 * (Platform.getRandomFloat() - .5)) + side.xOffset
|
||||
+ .5 + te.getPos().getX();
|
||||
final double y = (side.yOffset != 0 ? 0 : .7 * (Platform.getRandomFloat() - .5)) + side.yOffset
|
||||
+ .5 + te.getPos().getY();
|
||||
final double z = (side.zOffset != 0 ? 0 : .7 * (Platform.getRandomFloat() - .5)) + side.zOffset
|
||||
+ .5 + te.getPos().getZ();
|
||||
|
||||
final ItemEntity ei = new ItemEntity(w, x, y, z, is.copy());
|
||||
ei.setVelocity(side.xOffset * 0.2, side.yOffset * 0.2, side.zOffset * 0.2);
|
||||
|
||||
Entity result;
|
||||
if (is.getItem() instanceof AECustomEntityItem) {
|
||||
result = ((AECustomEntityItem) is.getItem()).replaceItemEntity(serverWorld, ei, is);
|
||||
if (result != ei) {
|
||||
ei.remove();
|
||||
}
|
||||
} else {
|
||||
result = ei;
|
||||
}
|
||||
|
||||
if (!w.spawnEntity(result)) {
|
||||
result.remove();
|
||||
if (!spawnItemEntity(serverWorld, te, side, is)) {
|
||||
// revert in case something prevents spawning.
|
||||
worked = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
worked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,6 +274,56 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
||||
return input;
|
||||
}
|
||||
|
||||
private static boolean spawnItemEntity(ServerWorld w, BlockEntity te, AEPartLocation side, ItemStack is) {
|
||||
// the item offset based on the entity height plus some offset
|
||||
final double itemOffset = .55 + EntityType.ITEM.getHeight();
|
||||
|
||||
// The center of the block the plane is located in
|
||||
final double centerX = te.getPos().getX() + .5;
|
||||
final double centerY = te.getPos().getY() + .5;
|
||||
final double centerZ = te.getPos().getZ() + .5;
|
||||
|
||||
// When spawning downwards, we have to take the item height of 0.25 into account
|
||||
// Otherwise it will get stuck and be spit out in a random direction as
|
||||
// minecraft spawns it at its feet position and not center
|
||||
final double additionalYOffset = side.yOffset == -1 ? -.3 : 0;
|
||||
|
||||
// Calculate the offsets to spawn it into the adjacent block, taking the sign
|
||||
// into account.
|
||||
// Spawn it 0.8 blocks away from the center pos when facing in this direction
|
||||
// Every other direction will select a position in a .5 block area around the
|
||||
// block center.
|
||||
final double offsetX = (side.xOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25)
|
||||
: (side.xOffset * itemOffset);
|
||||
final double offsetY = (side.yOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25)
|
||||
: ((side.yOffset * itemOffset) + additionalYOffset);
|
||||
final double offsetZ = (side.zOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25)
|
||||
: (side.zOffset * itemOffset);
|
||||
|
||||
final double absoluteX = centerX + offsetX;
|
||||
final double absoluteY = centerY + offsetY;
|
||||
final double absoluteZ = centerZ + offsetZ;
|
||||
|
||||
final ItemEntity ei = new ItemEntity(w, absoluteX, absoluteY, absoluteZ, is.copy());
|
||||
ei.setVelocity(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1);
|
||||
|
||||
Entity result;
|
||||
if (is.getItem() instanceof AECustomEntityItem) {
|
||||
result = ((AECustomEntityItem) is.getItem()).replaceItemEntity(w, ei, is);
|
||||
if (result != ei) {
|
||||
ei.remove();
|
||||
}
|
||||
} else {
|
||||
result = ei;
|
||||
}
|
||||
|
||||
if (!w.spawnEntity(result)) {
|
||||
result.remove();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEItemStack> getChannel() {
|
||||
return Api.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
@@ -354,11 +356,76 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
||||
return list.size();
|
||||
}
|
||||
|
||||
private class ForcedItemUseContext extends ItemUsageContext {
|
||||
protected ForcedItemUseContext(World worldIn, @Nullable PlayerEntity player, Hand handIn, ItemStack heldItem,
|
||||
BlockHitResult rayTraceResultIn) {
|
||||
super(worldIn, player, handIn, heldItem, rayTraceResultIn);
|
||||
/**
|
||||
* A custom {@link DirectionalPlaceContext} which also accepts a player needed
|
||||
* various blocks like seeds.
|
||||
* <p>
|
||||
* Also removed {@link DirectionalPlaceContext#replacingClickedOnBlock} as this
|
||||
* can cause a {@link StackOverflowError} for certain replaceable blocks.
|
||||
*/
|
||||
private static class PlaneDirectionalPlaceContext extends BlockItemUseContext {
|
||||
private final Direction lookDirection;
|
||||
|
||||
public PlaneDirectionalPlaceContext(World world, PlayerEntity player, BlockPos pos, Direction lookDirection,
|
||||
ItemStack itemStack, Direction facing) {
|
||||
super(world, player, Hand.MAIN_HAND, itemStack,
|
||||
new BlockRayTraceResult(Vector3d.copyCenteredHorizontally(pos), facing, pos, false));
|
||||
this.lookDirection = lookDirection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return this.rayTraceResult.getPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlace() {
|
||||
return this.world.getBlockState(this.rayTraceResult.getPos()).isReplaceable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getNearestLookingDirection() {
|
||||
return Direction.DOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction[] getNearestLookingDirections() {
|
||||
switch (this.lookDirection) {
|
||||
case DOWN:
|
||||
default:
|
||||
return new Direction[] { Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.SOUTH,
|
||||
Direction.WEST, Direction.UP };
|
||||
case UP:
|
||||
return new Direction[] { Direction.DOWN, Direction.UP, Direction.NORTH, Direction.EAST,
|
||||
Direction.SOUTH, Direction.WEST };
|
||||
case NORTH:
|
||||
return new Direction[] { Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.WEST,
|
||||
Direction.UP, Direction.SOUTH };
|
||||
case SOUTH:
|
||||
return new Direction[] { Direction.DOWN, Direction.SOUTH, Direction.EAST, Direction.WEST,
|
||||
Direction.UP, Direction.NORTH };
|
||||
case WEST:
|
||||
return new Direction[] { Direction.DOWN, Direction.WEST, Direction.SOUTH, Direction.UP,
|
||||
Direction.NORTH, Direction.EAST };
|
||||
case EAST:
|
||||
return new Direction[] { Direction.DOWN, Direction.EAST, Direction.SOUTH, Direction.UP,
|
||||
Direction.NORTH, Direction.WEST };
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getPlacementHorizontalFacing() {
|
||||
return this.lookDirection.getAxis() == Axis.Y ? Direction.NORTH : this.lookDirection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_225518_g_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPlacementYaw() {
|
||||
return (float) (this.lookDirection.getHorizontalIndex() * 90);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,15 +54,6 @@ public class IdentityAnnihilationPlanePart extends AnnihilationPlanePart {
|
||||
super(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAnnihilationPlane(final BlockEntity blockTileEntity, final AEPartLocation side) {
|
||||
if (blockTileEntity instanceof IPartHost) {
|
||||
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
|
||||
return p != null && p.getClass() == this.getClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float calculateEnergyUsage(final ServerWorld w, final BlockPos pos, final List<ItemStack> items) {
|
||||
final float requiredEnergy = super.calculateEnergyUsage(w, pos, items);
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
package appeng.parts.automation;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.parts.IPartCollisionHelper;
|
||||
import appeng.api.parts.IPartHost;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.parts.AEBasePart;
|
||||
|
||||
/**
|
||||
* Helps plane parts (annihilation, formation) with determining and checking for
|
||||
* connections to adjacent plane parts of the same type to form a visually
|
||||
* larger plane.
|
||||
*/
|
||||
public final class PlaneConnectionHelper {
|
||||
|
||||
private final AEBasePart part;
|
||||
|
||||
public PlaneConnectionHelper(AEBasePart part) {
|
||||
this.part = part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets on which sides this part has adjacent planes that it visually connects
|
||||
* to
|
||||
*/
|
||||
public PlaneConnections getConnections() {
|
||||
TileEntity hostTileEntity = getHostTileEntity();
|
||||
AEPartLocation side = part.getSide();
|
||||
|
||||
final Direction facingRight, facingUp;
|
||||
switch (side) {
|
||||
case UP:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case DOWN:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.NORTH;
|
||||
break;
|
||||
case NORTH:
|
||||
facingRight = Direction.WEST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case SOUTH:
|
||||
facingRight = Direction.EAST;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case WEST:
|
||||
facingRight = Direction.SOUTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
case EAST:
|
||||
facingRight = Direction.NORTH;
|
||||
facingUp = Direction.UP;
|
||||
break;
|
||||
default:
|
||||
case INTERNAL:
|
||||
return PlaneConnections.of(false, false, false, false);
|
||||
}
|
||||
|
||||
boolean left = false, right = false, down = false, up = false;
|
||||
|
||||
if (hostTileEntity != null) {
|
||||
World world = hostTileEntity.getWorld();
|
||||
BlockPos pos = hostTileEntity.getPos();
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingRight.getOpposite())))) {
|
||||
left = true;
|
||||
}
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingRight)))) {
|
||||
right = true;
|
||||
}
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingUp.getOpposite())))) {
|
||||
down = true;
|
||||
}
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingUp)))) {
|
||||
up = true;
|
||||
}
|
||||
}
|
||||
|
||||
return PlaneConnections.of(up, right, down, left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounding boxes of this plane parts components.
|
||||
*/
|
||||
public void getBoxes(IPartCollisionHelper bch) {
|
||||
int minX = 1;
|
||||
int minY = 1;
|
||||
int maxX = 15;
|
||||
int maxY = 15;
|
||||
|
||||
TileEntity hostTile = getHostTileEntity();
|
||||
if (hostTile != null) {
|
||||
World world = hostTile.getWorld();
|
||||
|
||||
final BlockPos pos = hostTile.getPos();
|
||||
|
||||
final Direction e = bch.getWorldX();
|
||||
final Direction u = bch.getWorldY();
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(e.getOpposite())))) {
|
||||
minX = 0;
|
||||
}
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(e)))) {
|
||||
maxX = 16;
|
||||
}
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(u.getOpposite())))) {
|
||||
minY = 0;
|
||||
}
|
||||
|
||||
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(u)))) {
|
||||
maxY = 16;
|
||||
}
|
||||
}
|
||||
|
||||
bch.addBox(5, 5, 14, 11, 11, 15);
|
||||
bch.addBox(minX, minY, 15, maxX, maxY, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when an adjacent block has changed since the connections need to be
|
||||
* recalculated.
|
||||
*/
|
||||
public void updateConnections() {
|
||||
TileEntity hostTile = getHostTileEntity();
|
||||
if (hostTile != null) {
|
||||
hostTile.requestModelDataUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCompatiblePlaneAdjacent(@Nullable TileEntity adjacentTileEntity) {
|
||||
if (adjacentTileEntity instanceof IPartHost) {
|
||||
final IPart p = ((IPartHost) adjacentTileEntity).getPart(part.getSide());
|
||||
return p != null && p.getClass() == part.getClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private TileEntity getHostTileEntity() {
|
||||
IPartHost host = part.getHost();
|
||||
if (host != null) {
|
||||
return host.getTile();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,32 +18,32 @@
|
||||
|
||||
package appeng.parts.p2p;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import alexiil.mc.lib.attributes.AttributeList;
|
||||
import alexiil.mc.lib.attributes.Simulation;
|
||||
import alexiil.mc.lib.attributes.fluid.FluidAttributes;
|
||||
import alexiil.mc.lib.attributes.fluid.FluidInsertable;
|
||||
import alexiil.mc.lib.attributes.fluid.FluidVolumeUtil;
|
||||
import alexiil.mc.lib.attributes.fluid.amount.FluidAmount;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidKey;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
import appeng.api.config.PowerUnits;
|
||||
import appeng.api.parts.IPartModel;
|
||||
import appeng.items.parts.PartModels;
|
||||
import appeng.me.GridAccessException;
|
||||
|
||||
public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implements FluidInsertable {
|
||||
public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
|
||||
|
||||
private static final P2PModels MODELS = new P2PModels("part/p2p/p2p_tunnel_fluids");
|
||||
private static final IFluidHandler NULL_FLUID_HANDLER = new NullFluidHandler();
|
||||
|
||||
private static final ThreadLocal<Deque<FluidP2PTunnelPart>> DEPTH = new ThreadLocal<>();;
|
||||
|
||||
private FluidInsertable cachedTank;
|
||||
private final IFluidHandler inputHandler = new InputFluidHandler();
|
||||
private final IFluidHandler outputHandler = new OutputFluidHandler();
|
||||
|
||||
public FluidP2PTunnelPart(final ItemStack is) {
|
||||
super(is);
|
||||
@@ -60,13 +60,10 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
|
||||
|
||||
@Override
|
||||
public void onTunnelNetworkChange() {
|
||||
this.cachedTank = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onneighborUpdate(BlockView w, BlockPos pos, BlockPos neighbor) {
|
||||
this.cachedTank = null;
|
||||
|
||||
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
|
||||
if (this.isOutput()) {
|
||||
final FluidP2PTunnelPart in = this.getInput();
|
||||
if (in != null) {
|
||||
@@ -75,9 +72,17 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void addAllAttributes(AttributeList<?> to) {
|
||||
to.offer(this);
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
|
||||
if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
|
||||
if (this.isOutput()) {
|
||||
return (LazyOptional<T>) LazyOptional.of(() -> this.outputHandler);
|
||||
}
|
||||
return (LazyOptional<T>) LazyOptional.of(() -> this.inputHandler);
|
||||
}
|
||||
|
||||
return super.getCapability(capabilityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,122 +90,173 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
|
||||
return MODELS.getModel(this.isPowered(), this.isActive());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidVolume attemptInsertion(FluidVolume fluid, Simulation simulation) {
|
||||
private IFluidHandler getAttachedFluidHandler() {
|
||||
LazyOptional<IFluidHandler> fluidHandler = LazyOptional.empty();
|
||||
if (this.isActive()) {
|
||||
final TileEntity self = this.getTile();
|
||||
final TileEntity te = self.getWorld().getTileEntity(self.getPos().offset(this.getSide().getFacing()));
|
||||
|
||||
final Deque<FluidP2PTunnelPart> stack = this.getDepth();
|
||||
|
||||
for (final FluidP2PTunnelPart t : stack) {
|
||||
if (t == this) {
|
||||
return fluid;
|
||||
if (te != null) {
|
||||
fluidHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
|
||||
this.getSide().getOpposite().getFacing());
|
||||
}
|
||||
}
|
||||
|
||||
stack.push(this);
|
||||
|
||||
final List<FluidP2PTunnelPart> list = this.getOutputs(fluid.getFluidKey());
|
||||
FluidAmount requestTotal = FluidAmount.ZERO;
|
||||
|
||||
Iterator<FluidP2PTunnelPart> i = list.iterator();
|
||||
|
||||
while (i.hasNext()) {
|
||||
final FluidP2PTunnelPart l = i.next();
|
||||
final FluidInsertable tank = l.getTarget();
|
||||
FluidAmount inserted;
|
||||
if (tank != null) {
|
||||
inserted = fluid.amount().sub(tank.attemptInsertion(fluid.copy(), Simulation.SIMULATE).amount());
|
||||
} else {
|
||||
inserted = FluidAmount.ZERO;
|
||||
}
|
||||
|
||||
if (inserted.isZero()) {
|
||||
i.remove();
|
||||
} else {
|
||||
requestTotal = requestTotal.add(inserted);
|
||||
}
|
||||
}
|
||||
|
||||
if (requestTotal.isZero()) {
|
||||
if (stack.pop() != this) {
|
||||
throw new IllegalStateException("Invalid Recursion detected.");
|
||||
}
|
||||
|
||||
return fluid;
|
||||
}
|
||||
|
||||
if (simulation != Simulation.ACTION) {
|
||||
if (stack.pop() != this) {
|
||||
throw new IllegalStateException("Invalid Recursion detected.");
|
||||
}
|
||||
|
||||
return fluid.copy().split(fluid.amount().min(requestTotal));
|
||||
}
|
||||
|
||||
FluidAmount remaining = fluid.amount();
|
||||
|
||||
i = list.iterator();
|
||||
|
||||
while (i.hasNext() && !remaining.isZero()) {
|
||||
final FluidP2PTunnelPart l = i.next();
|
||||
|
||||
FluidVolume insert = fluid.withAmount(fluid.amount().div(list.size()));
|
||||
if (insert.amount().isGreaterThan(remaining)) {
|
||||
insert = insert.withAmount(remaining);
|
||||
}
|
||||
|
||||
FluidInsertable tank = l.getTarget();
|
||||
if (tank != null) {
|
||||
remaining = remaining
|
||||
.sub(insert.amount().sub(tank.attemptInsertion(insert, Simulation.ACTION).amount()));
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.pop() != this) {
|
||||
throw new IllegalStateException("Invalid Recursion detected.");
|
||||
}
|
||||
|
||||
return remaining.isZero() ? FluidVolumeUtil.EMPTY : fluid.withAmount(remaining);
|
||||
return fluidHandler.orElse(NULL_FLUID_HANDLER);
|
||||
}
|
||||
|
||||
private Deque<FluidP2PTunnelPart> getDepth() {
|
||||
Deque<FluidP2PTunnelPart> s = DEPTH.get();
|
||||
private class InputFluidHandler implements IFluidHandler {
|
||||
|
||||
if (s == null) {
|
||||
DEPTH.set(s = new ArrayDeque<>());
|
||||
@Override
|
||||
public int getTanks() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack getFluidInTank(int tank) {
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
private List<FluidP2PTunnelPart> getOutputs(final FluidKey input) {
|
||||
final List<FluidP2PTunnelPart> outs = new ArrayList<>();
|
||||
@Override
|
||||
public int getTankCapacity(int tank) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
try {
|
||||
for (final FluidP2PTunnelPart l : this.getOutputs()) {
|
||||
final FluidInsertable handler = l.getTarget();
|
||||
@Override
|
||||
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (handler != null) {
|
||||
outs.add(l);
|
||||
@Override
|
||||
public int fill(FluidStack resource, FluidAction action) {
|
||||
int total = 0;
|
||||
|
||||
try {
|
||||
final int outputTunnels = FluidP2PTunnelPart.this.getOutputs().size();
|
||||
final int amount = resource.getAmount();
|
||||
|
||||
if (outputTunnels == 0 || amount == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final int amountPerOutput = Math.max(1, amount / outputTunnels);
|
||||
int overflow = amountPerOutput == 0 ? amount : amount % amountPerOutput;
|
||||
|
||||
for (FluidP2PTunnelPart target : FluidP2PTunnelPart.this.getOutputs()) {
|
||||
final IFluidHandler output = target.getAttachedFluidHandler();
|
||||
final int toSend = amountPerOutput + overflow;
|
||||
final FluidStack fillWithFluidStack = resource.copy();
|
||||
fillWithFluidStack.setAmount(toSend);
|
||||
|
||||
final int received = output.fill(fillWithFluidStack, action);
|
||||
|
||||
overflow = toSend - received;
|
||||
total += received;
|
||||
}
|
||||
|
||||
if (action == FluidAction.EXECUTE) {
|
||||
FluidP2PTunnelPart.this.queueTunnelDrain(PowerUnits.RF, total);
|
||||
}
|
||||
} catch (GridAccessException ignored) {
|
||||
}
|
||||
} catch (final GridAccessException e) {
|
||||
// :P
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
return outs;
|
||||
}
|
||||
|
||||
private FluidInsertable getTarget() {
|
||||
if (!this.getProxy().isActive()) {
|
||||
return null;
|
||||
private class OutputFluidHandler implements IFluidHandler {
|
||||
|
||||
@Override
|
||||
public int getTanks() {
|
||||
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTanks();
|
||||
}
|
||||
|
||||
if (this.cachedTank != null) {
|
||||
return this.cachedTank;
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack getFluidInTank(int tank) {
|
||||
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getFluidInTank(tank);
|
||||
}
|
||||
|
||||
return this.cachedTank = FluidAttributes.INSERTABLE.getFirstOrNullFromNeighbour(this.getTile(),
|
||||
this.getSide().getFacing());
|
||||
@Override
|
||||
public int getTankCapacity(int tank) {
|
||||
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTankCapacity(tank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
|
||||
return FluidP2PTunnelPart.this.getAttachedFluidHandler().isFluidValid(tank, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, FluidAction action) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||
return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(resource, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||
return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(maxDrain, action);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NullFluidHandler implements IFluidHandler {
|
||||
|
||||
@Override
|
||||
public int getTanks() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack getFluidInTank(int tank) {
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTankCapacity(int tank) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(FluidStack resource, FluidAction action) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack drain(FluidStack resource, FluidAction action) {
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack drain(int maxDrain, FluidAction action) {
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user