Compare commits

...

19 Commits

Author SHA1 Message Date
Sebastian Hartte 822249dda8 Added missing @Override annotations. 2020-08-05 22:11:00 +02:00
yueh 1404806d3d Fixes #4559: Use visual bounding box for overlay (#4561) 2020-08-05 21:52:34 +02:00
yueh 12e3fa9127 Makes formation planes a bit more consistent and less violent. (#4553)
* Makes formation planes a bit more consistent and less violent.

Items will now have a slower speed when spawning as well as a narrower area to avoid having them glitch into a wall and be teleported around

* Removed debug output, added clarifying parenthesis and extracted method.

* Fixes various other issues with the formation plane

Also removed now useless code

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-08-05 17:56:42 +02:00
shartte 8617dc8340 Plane Connection Refactor (#4556)
* Refactors all plane parts to use a common helper for
calculating connections to adjacent planes.
Also fixes problems with updating these connections on neighbor updates.

* Fix conflicting GuiSync ID.

* Slightly refactor PlaneConnectionHelper, and fix an issue where the bounding box was calculated incorrectly by using the wrong up-direction.
2020-08-05 17:45:33 +02:00
shartte 9bc844738c Fixes #4547: Name clash between ITooltip#getWidth, ITooltip#getHeight and Vanilla Widget methods leads to missing methods at runtime, since the implementing methods will be remapped to SRG names, while referees of the interface will try to call the renamed methods by their name in the interface, leading to an AbstractMethodError. (#4557) 2020-08-05 16:33:44 +02:00
Sebastian Hartte eab6483bd7 Fixes #4551: Bounding box of annihilation planes is too small. 2020-08-05 00:54:26 +02:00
yueh 7ca9405c8b Apply the FE tunnel behaviour to the fluid tunnel (#4550) 2020-08-04 17:57:59 +02:00
yueh 39959145a3 Revert "Apply the FE tunnel behaviour to the fluid tunnel (#4545)" (#4549)
This reverts commit 22f552217f.
2020-08-04 08:45:10 +02:00
yueh 22f552217f Apply the FE tunnel behaviour to the fluid tunnel (#4545)
* Apply the FE tunnel behaviour to the fluid tunnel

* Make a second pass to try and get all the requested fill amount sent out to outputs.

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-08-03 21:39:34 +02:00
yueh 8f0e408772 Fixes NPE on empty tooltips (#4546) 2020-08-03 20:57:10 +02:00
Sebastian Hartte 62bbc32763 Minor cleanup. 2020-08-03 20:31:30 +02:00
shartte 872d8d33cb Clean up global state for cable render mode (#4539)
* Clean up the global state used to hack part interaction into respecting
the player's facade render mode. Make the name more indicative of
what is actually happening.

* Fun.
2020-08-03 14:46:39 +02:00
shartte 1801302d8f Fix SkyStone chest model issues that I had introduced back in 1.8. (#4542)
This makes the chest 1 pixel higher to restore the look it had in 1.7.
Since the skystone chest's texture is a grungy mess, only the most
obvious texture problems were fixed, while for the skystone block chest,
the look should be close to what it was now.
Also introduces caching for the skystone chest's block shape.
2020-08-03 14:46:23 +02:00
Sebastian Hartte a85ffec9f9 Unified Parameter-Names for Slots 2020-08-02 22:12:08 +02:00
Sebastian Hartte 5fca946ef3 The lambda has to be replaced with an explicit method to annotate it with @OnlyIn. 2020-08-02 15:45:15 +02:00
Sebastian Hartte f8446209ce Move CraftingMonitor rendering customization out to its own class to circumvent issues with a client-side only lambda method being generated in a common-side class. 2020-08-02 15:40:50 +02:00
Sebastian Hartte 088627aedf Remove client-only methods from ChargerBlock which could potentially create synthetic lambda methods that reference client-only classes (and are not stripped). 2020-08-02 15:13:20 +02:00
shartte c8d08f9726 Fixes sidedness issues that cropped up with 1.16 (#4533) 2020-08-01 22:16:57 +02:00
yueh 259d932946 Fixes 4529: Updated IPart to match new ICapabilityProvider (#4534) 2020-08-01 21:01:19 +02:00
73 changed files with 967 additions and 935 deletions
+5 -2
View File
@@ -50,6 +50,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import appeng.api.networking.IGridNode;
@@ -346,10 +347,12 @@ public interface IPart extends ICustomCableConnection {
* capabilities on the cable bus will be forwarded to parts on the appropriate
* side.
*
* @see TileEntity#getCapability(Capability, net.minecraft.util.Direction)
* @see CapabilityProvider#getCapability(Capability,
* net.minecraft.util.Direction)
*
* @return The capability or null.
* @return The capability
*/
@Nonnull
default <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
return LazyOptional.empty();
}
@@ -45,14 +45,6 @@ public class AEBaseBlockItemChargeable extends AEBaseBlockItem implements IAEIte
public AEBaseBlockItemChargeable(Block id, Properties props) {
super(id, props);
ItemModelsProperties.func_239418_a_(this, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> {
double curPower = getAECurrentPower(is);
double maxPower = getAEMaxPower(is);
return (int) Math.round(100 * curPower / maxPower);
});
}
@Override
@@ -0,0 +1,33 @@
package appeng.block.crafting;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
public class CraftingMonitorBlockRendering extends BlockRenderingCustomizer {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer(CraftingMonitorBlockRendering::customizeModel);
}
@OnlyIn(Dist.CLIENT)
private static IBakedModel customizeModel(ResourceLocation path, IBakedModel model) {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
}
}
@@ -19,18 +19,12 @@
package appeng.block.misc;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
@@ -42,8 +36,6 @@ import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
@@ -52,8 +44,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.util.AEAxisAlignedBB;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.renderable.ItemRenderable;
import appeng.client.render.tesr.ModularTESR;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
@@ -175,15 +165,4 @@ public class ChargerBlock extends AEBaseTileBlock<ChargerTileEntity> {
return VoxelShapes.create(new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0));
}
@OnlyIn(Dist.CLIENT)
public static Function<TileEntityRendererDispatcher, TileEntityRenderer<ChargerTileEntity>> createTesr() {
return dispatcher -> new ModularTESR<>(dispatcher, new ItemRenderable<>(ChargerBlock::getRenderedItem));
}
@OnlyIn(Dist.CLIENT)
private static Pair<ItemStack, TransformationMatrix> getRenderedItem(ChargerTileEntity tile) {
TransformationMatrix transform = new TransformationMatrix(new Vector3f(0.5f, 0.375f, 0.5f), null, null, null);
return new ImmutablePair<>(tile.getInternalInventory().getStackInSlot(0), transform);
}
}
@@ -18,6 +18,9 @@
package appeng.block.storage;
import java.util.EnumMap;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraft.block.BlockRenderType;
@@ -47,7 +50,18 @@ public class SkyChestBlock extends AEBaseTileBlock<SkyChestTileEntity> {
private static final double AABB_OFFSET_BOTTOM = 0.00;
private static final double AABB_OFFSET_SIDES = 0.06;
private static final double AABB_OFFSET_TOP = 0.125;
private static final double AABB_OFFSET_TOP = 0.0625;
// Precomputed bounding boxes of the chest, sorted into the map by the UP
// direction
private static final Map<Direction, VoxelShape> SHAPES = new EnumMap<>(Direction.class);
static {
for (Direction up : Direction.values()) {
AxisAlignedBB aabb = computeAABB(up);
SHAPES.put(up, VoxelShapes.create(aabb));
}
}
public enum SkyChestType {
STONE, BLOCK
@@ -87,37 +101,30 @@ public class SkyChestBlock extends AEBaseTileBlock<SkyChestTileEntity> {
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
// TODO Cache this! It can't be that hard!
AxisAlignedBB aabb = computeAABB(worldIn, pos);
return VoxelShapes.create(aabb);
final SkyChestTileEntity sk = this.getTileEntity(worldIn, pos);
Direction up = sk != null ? sk.getUp() : Direction.UP;
return SHAPES.get(up);
}
private AxisAlignedBB computeAABB(final IBlockReader w, final BlockPos pos) {
final SkyChestTileEntity sk = this.getTileEntity(w, pos);
Direction o = Direction.UP;
if (sk != null) {
o = sk.getUp();
}
final double offsetX = o.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = o.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = o.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
private static AxisAlignedBB computeAABB(Direction up) {
final double offsetX = up.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = up.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = up.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
// for x/z top and bottom is swapped
final double minX = Math.max(0.0,
offsetX + (o.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getXOffset() * AABB_OFFSET_TOP)));
offsetX + (up.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getXOffset() * AABB_OFFSET_TOP)));
final double minY = Math.max(0.0,
offsetY + (o.getYOffset() < 0 ? AABB_OFFSET_TOP : (o.getYOffset() * AABB_OFFSET_BOTTOM)));
offsetY + (up.getYOffset() < 0 ? AABB_OFFSET_TOP : (up.getYOffset() * AABB_OFFSET_BOTTOM)));
final double minZ = Math.max(0.0,
offsetZ + (o.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getZOffset() * AABB_OFFSET_TOP)));
offsetZ + (up.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getZOffset() * AABB_OFFSET_TOP)));
final double maxX = Math.min(1.0,
1.0 - offsetX - (o.getXOffset() < 0 ? AABB_OFFSET_TOP : (o.getXOffset() * AABB_OFFSET_BOTTOM)));
1.0 - offsetX - (up.getXOffset() < 0 ? AABB_OFFSET_TOP : (up.getXOffset() * AABB_OFFSET_BOTTOM)));
final double maxY = Math.min(1.0,
1.0 - offsetY - (o.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getYOffset() * AABB_OFFSET_TOP)));
1.0 - offsetY - (up.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getYOffset() * AABB_OFFSET_TOP)));
final double maxZ = Math.min(1.0,
1.0 - offsetZ - (o.getZOffset() < 0 ? AABB_OFFSET_TOP : (o.getZOffset() * AABB_OFFSET_BOTTOM)));
1.0 - offsetZ - (up.getZOffset() < 0 ? AABB_OFFSET_TOP : (up.getZOffset() * AABB_OFFSET_BOTTOM)));
return new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
}
@@ -31,6 +31,8 @@ import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -38,8 +40,10 @@ import appeng.api.definitions.IBlockDefinition;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlock;
import appeng.block.AEBaseBlockItem;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.block.AEBaseTileBlock;
import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.core.AEItemGroup;
@@ -149,6 +153,24 @@ class BlockDefinitionBuilder implements IBlockBuilder {
item.setRegistryName(AppEng.MOD_ID, this.registryName);
}
// Register the client-only item model property for chargeable items
if (item instanceof AEBaseBlockItemChargeable) {
AEBaseBlockItemChargeable chargeable = (AEBaseBlockItemChargeable) item;
this.factory.addBootstrapComponent(new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> {
double curPower = chargeable.getAECurrentPower(is);
double maxPower = chargeable.getAEMaxPower(is);
return (int) Math.round(100 * curPower / maxPower);
});
}
});
}
// Register the item and block with the game
this.factory.addBootstrapComponent((IBlockRegistrationComponent) (side, registry) -> registry.register(block));
if (item != null) {
@@ -30,10 +30,14 @@ import net.minecraft.block.DispenserBlock;
import net.minecraft.dispenser.IDispenseItemBehavior;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
import appeng.core.AEItemGroup;
@@ -138,15 +138,15 @@ public class ClientHelper extends ServerHelper {
}
@Override
public CableRenderMode getRenderMode() {
public CableRenderMode getCableRenderMode() {
if (Platform.isServer()) {
return super.getRenderMode();
return super.getCableRenderMode();
}
final Minecraft mc = Minecraft.getInstance();
final PlayerEntity player = mc.player;
return this.renderModeForPlayer(player);
return this.getCableRenderModeForPlayer(player);
}
@Override
@@ -158,14 +158,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
protected void drawGuiSlot(MatrixStack matrixStack, 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(matrixStack, getMinecraft(), mouseX, mouseY, partialTicks);
if (this.isPointInRegion(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY)
if (this.isPointInRegion(left, top, slot.getTooltipAreaWidth(), slot.getTooltipAreaHeight(), mouseX, mouseY)
&& slot.canClick(getPlayer())) {
RenderSystem.colorMask(true, true, true, false);
this.fillGradient(matrixStack, left, top, right, bottom, -2130706433, -2130706433);
@@ -175,26 +175,30 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
private void drawTooltip(MatrixStack matrixStack, ITooltip tooltip, int mouseX, int mouseY) {
final int x = tooltip.xPos(); // ((GuiImgButton) c).x;
int y = tooltip.yPos(); // ((GuiImgButton) c).y;
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 ITextComponent msg = tooltip.getMessage();
final ITextComponent msg = tooltip.getTooltipMessage();
this.drawTooltip(matrixStack, x + 11, y + 4, msg);
}
}
}
protected void drawTooltip(MatrixStack matrices, int x, int y, ITextComponent message) {
String[] lines = message.getString().split("\n"); // FIXME FABRIC
List<ITextComponent> textLines = Arrays.stream(lines).map(StringTextComponent::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<ITextComponent> textLines = Arrays.stream(lines).map(StringTextComponent::new)
.collect(Collectors.toList());
this.drawTooltip(matrices, x, y, textLines);
}
}
// FIXME FABRIC: move out to json (?)
@@ -281,8 +285,8 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
for (CustomSlotWidget slot : this.guiSlots) {
if (this.isPointInRegion(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord)
&& slot.canClick(getPlayer())) {
if (this.isPointInRegion(slot.getTooltipAreaX(), slot.getTooltipAreaY(), slot.getTooltipAreaWidth(),
slot.getTooltipAreaHeight(), xCoord, yCoord) && slot.canClick(getPlayer())) {
slot.slotClicked(getPlayer().inventory.getItemStack(), btn);
}
}
@@ -27,7 +27,7 @@ import net.minecraft.util.text.StringTextComponent;
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;
@@ -8,6 +8,7 @@ import net.minecraft.client.gui.AbstractGui;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
private final int x;
@@ -38,32 +39,32 @@ public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
}
@Override
public ITextComponent getMessage() {
return null;
public ITextComponent getTooltipMessage() {
return StringTextComponent.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;
}
@@ -18,7 +18,10 @@
package appeng.client.gui.widgets;
import javax.annotation.Nonnull;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
/**
* AEBaseGui controlled Tooltip Interface.
@@ -26,42 +29,45 @@ import net.minecraft.util.text.ITextComponent;
public interface ITooltip {
/**
* returns the tooltip message.
* Returns the tooltip message.
*
* Should use {@link StringTextComponent#EMPTY} for no tooltip
*
* @return tooltip message
*/
ITextComponent getMessage();
@Nonnull
ITextComponent 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.Minecraft;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
@@ -97,27 +98,32 @@ public abstract class IconButton extends Button implements ITooltip {
protected abstract int getIconIndex();
@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 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;
}
@@ -81,7 +81,7 @@ public class ProgressBar extends Widget implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
if (this.fullMsg != null) {
return this.fullMsg;
}
@@ -92,27 +92,27 @@ public class ProgressBar extends Widget 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 ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
ITextComponent displayName = null;
ITextComponent displayValue = null;
@@ -99,27 +99,32 @@ public class TabButton extends Button 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;
}
@@ -77,7 +77,7 @@ public class ToggleButton extends Button implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
if (this.displayName != null) {
String name = I18n.format(this.displayName);
String value = I18n.format(this.displayHint);
@@ -106,27 +106,27 @@ public class ToggleButton extends Button 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;
}
}
@@ -29,13 +29,13 @@ public class SlotDisconnected extends AppEngSlot {
private final ClientDCInternalInv mySlot;
public SlotDisconnected(final ClientDCInternalInv me, final int which, final int x, final int y) {
super(me.getInventory(), which, x, y);
public SlotDisconnected(final ClientDCInternalInv me, final int invSlot, final int x, final int y) {
super(me.getInventory(), invSlot, x, y);
this.mySlot = me;
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -45,7 +45,7 @@ public class SlotDisconnected extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -0,0 +1,30 @@
package appeng.client.render.tesr;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import appeng.client.render.renderable.ItemRenderable;
import appeng.tile.misc.ChargerTileEntity;
public final class ChargerTESR {
private ChargerTESR() {
}
public static Function<TileEntityRendererDispatcher, TileEntityRenderer<ChargerTileEntity>> FACTORY = dispatcher -> new ModularTESR<>(
dispatcher, new ItemRenderable<>(ChargerTESR::getRenderedItem));
private static Pair<ItemStack, TransformationMatrix> getRenderedItem(ChargerTileEntity tile) {
TransformationMatrix transform = new TransformationMatrix(new Vector3f(0.5f, 0.375f, 0.5f), null, null, null);
return new ImmutablePair<>(tile.getInternalInventory().getStackInSlot(0), transform);
}
}
@@ -60,11 +60,11 @@ public class SkyChestTESR extends TileEntityRenderer<SkyChestTileEntity> {
this.singleBottom.addBox(1.0F, 0.0F, 1.0F, 14.0F, 10.0F, 14.0F, 0.0F);
this.singleLid = new ModelRenderer(64, 64, 0, 0);
this.singleLid.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
this.singleLid.rotationPointY = 9.0F;
this.singleLid.rotationPointY = 10.0F;
this.singleLid.rotationPointZ = 1.0F;
this.singleLatch = new ModelRenderer(64, 64, 0, 0);
this.singleLatch.addBox(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
this.singleLatch.rotationPointY = 8.0F;
this.singleLatch.rotationPointY = 9.0F;
}
@Override
@@ -93,8 +93,6 @@ public abstract class AEBaseContainer extends Container {
private boolean sentCustomName;
private int ticksSinceCheck = 900;
private IAEItemStack clientRequestedTargetItem = null;
// Slots that were created to represent the player inventory
private List<Slot> playerInventorySlots = null;
public AEBaseContainer(ContainerType<?> containerType, int id, final PlayerInventory ip, final TileEntity myTile,
final IPart myPart) {
@@ -52,7 +52,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) {
@@ -105,8 +105,8 @@ public class QuartzKnifeContainer extends AEBaseContainer {
}
private class QuartzKniveSlot extends OutputSlot {
QuartzKniveSlot(IItemHandler a, int b, int c, int d, int i) {
super(a, b, c, d, i);
QuartzKniveSlot(IItemHandler inv, int invSlot, int x, int y, int iconIdx) {
super(inv, invSlot, x, y, iconIdx);
}
@Override
@@ -49,8 +49,8 @@ public class AppEngCraftingSlot extends AppEngSlot {
private int amountCrafted;
public AppEngCraftingSlot(final PlayerEntity par1PlayerEntity, final IItemHandler par2IInventory,
final IItemHandler par3IInventory, final int par4, final int par5, final int par6) {
super(par3IInventory, par4, par5, par6);
final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.thePlayer = par1PlayerEntity;
this.craftMatrix = par2IInventory;
}
@@ -60,7 +60,7 @@ public class AppEngCraftingSlot extends AppEngSlot {
* armor slots.
*/
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -33,9 +33,9 @@ import appeng.container.AEBaseContainer;
import appeng.util.helpers.ItemHandlerUtil;
public class AppEngSlot extends Slot {
private static IInventory emptyInventory = new Inventory(0);
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
private final IItemHandler itemHandler;
private final int index;
private final int invSlot;
private final int defX;
private final int defY;
@@ -46,10 +46,10 @@ public class AppEngSlot extends Slot {
private CalculatedValidity isValid;
private boolean isDisplay = false;
public AppEngSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(emptyInventory, idx, x, y);
public AppEngSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(EMPTY_INVENTORY, invSlot, x, y);
this.itemHandler = inv;
this.index = idx;
this.invSlot = invSlot;
this.defX = x;
this.defY = y;
@@ -71,13 +71,13 @@ public class AppEngSlot extends Slot {
}
public void clearStack() {
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.index, ItemStack.EMPTY);
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.invSlot, ItemStack.EMPTY);
}
@Override
public boolean isItemValid(@Nonnull final ItemStack par1ItemStack) {
public boolean isItemValid(@Nonnull final ItemStack stack) {
if (this.isSlotEnabled()) {
return this.itemHandler.isItemValid(this.index, par1ItemStack);
return this.itemHandler.isItemValid(this.invSlot, stack);
}
return false;
}
@@ -98,13 +98,13 @@ public class AppEngSlot extends Slot {
return this.getDisplayStack();
}
return this.itemHandler.getStackInSlot(this.index);
return this.itemHandler.getStackInSlot(this.invSlot);
}
@Override
public void putStack(final ItemStack stack) {
if (this.isSlotEnabled()) {
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.index, stack);
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.invSlot, stack);
this.onSlotChanged();
}
}
@@ -128,7 +128,7 @@ public class AppEngSlot extends Slot {
@Override
public int getSlotStackLimit() {
return this.itemHandler.getSlotLimit(this.index);
return this.itemHandler.getSlotLimit(this.invSlot);
}
@Override
@@ -137,9 +137,9 @@ public class AppEngSlot extends Slot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
if (this.isSlotEnabled()) {
return !this.itemHandler.extractItem(this.index, 1, true).isEmpty();
return !this.itemHandler.extractItem(this.invSlot, 1, true).isEmpty();
}
return false;
}
@@ -147,7 +147,7 @@ public class AppEngSlot extends Slot {
@Override
@Nonnull
public ItemStack decrStackSize(int amount) {
return this.itemHandler.extractItem(this.index, amount, false);
return this.itemHandler.extractItem(this.invSlot, amount, false);
}
@Override
@@ -166,7 +166,7 @@ public class AppEngSlot extends Slot {
}
public ItemStack getDisplayStack() {
return this.itemHandler.getStackInSlot(this.index);
return this.itemHandler.getStackInSlot(this.invSlot);
}
public float getOpacityOfIcon() {
@@ -29,11 +29,11 @@ public class CraftingMatrixSlot extends AppEngSlot {
private final AEBaseContainer c;
private final IInventory wrappedInventory;
public CraftingMatrixSlot(final AEBaseContainer c, final IItemHandler par1iInventory, final int par2,
final int par3, final int par4) {
super(par1iInventory, par2, par3, par4);
public CraftingMatrixSlot(final AEBaseContainer c, final IItemHandler inv, final int invSlot, final int x,
final int y) {
super(inv, invSlot, x, y);
this.c = c;
this.wrappedInventory = new WrapperInvItemHandler(par1iInventory);
this.wrappedInventory = new WrapperInvItemHandler(inv);
}
@Override
@@ -82,7 +82,7 @@ public class CraftingTermSlot extends AppEngCraftingSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -24,17 +24,17 @@ import net.minecraftforge.items.IItemHandler;
public class DisabledSlot extends AppEngSlot {
public DisabledSlot(final IItemHandler par1iInventory, final int slotIndex, final int x, final int y) {
super(par1iInventory, slotIndex, x, y);
public DisabledSlot(final IItemHandler par1iInventory, final int invSlot, final int x, final int y) {
super(par1iInventory, invSlot, x, y);
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
@@ -22,8 +22,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeBlacklistSlot extends FakeTypeOnlySlot {
public FakeBlacklistSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeBlacklistSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -22,7 +22,7 @@ import net.minecraftforge.items.IItemHandler;
public class FakeCraftingMatrixSlot extends FakeSlot {
public FakeCraftingMatrixSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeCraftingMatrixSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
}
@@ -24,8 +24,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeSlot extends AppEngSlot {
public FakeSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -39,7 +39,7 @@ public class FakeSlot extends AppEngSlot {
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -53,7 +53,7 @@ public class FakeSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
@@ -23,8 +23,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeTypeOnlySlot extends FakeSlot {
public FakeTypeOnlySlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeTypeOnlySlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -26,12 +26,12 @@ public class InaccessibleSlot extends AppEngSlot {
private ItemStack dspStack = ItemStack.EMPTY;
public InaccessibleSlot(final IItemHandler i, final int slotIdx, final int x, final int y) {
super(i, slotIdx, x, y);
public InaccessibleSlot(final IItemHandler i, final int invSlot, final int x, final int y) {
super(i, invSlot, x, y);
}
@Override
public boolean isItemValid(final ItemStack i) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -42,7 +42,7 @@ public class InaccessibleSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -27,14 +27,14 @@ public class MolecularAssemblerPatternSlot extends AppEngSlot {
private final MolecularAssemblerContainer mac;
public MolecularAssemblerPatternSlot(final MolecularAssemblerContainer mac, final IItemHandler i, final int slotIdx,
final int x, final int y) {
super(i, slotIdx, x, y);
public MolecularAssemblerPatternSlot(final MolecularAssemblerContainer mac, final IItemHandler inv,
final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.mac = mac;
}
@Override
public boolean isItemValid(final ItemStack i) {
return this.mac.isValidItemForSlot(this.getSlotIndex(), i);
public boolean isItemValid(final ItemStack stack) {
return this.mac.isValidItemForSlot(this.getSlotIndex(), stack);
}
}
@@ -22,7 +22,7 @@ import net.minecraftforge.items.IItemHandler;
public class NormalSlot extends AppEngSlot {
public NormalSlot(final IItemHandler inv, final int slot, final int xPos, final int yPos) {
super(inv, slot, xPos, yPos);
public NormalSlot(final IItemHandler inv, final int invSlot, final int xPos, final int yPos) {
super(inv, invSlot, xPos, yPos);
}
}
@@ -31,9 +31,9 @@ public class OptionalFakeSlot extends FakeSlot implements IOptionalSlot {
private final IOptionalSlotHost host;
private boolean renderDisabled = true;
public OptionalFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, idx, x + offX * 18, y + offY * 18);
public OptionalFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, invSlot, x + offX * 18, y + offY * 18);
this.srcX = x;
this.srcY = y;
this.groupNum = groupNum;
@@ -25,9 +25,9 @@ public class OptionalNormalSlot extends AppEngSlot implements IOptionalSlot {
private final int groupNum;
private final IOptionalSlotHost host;
public OptionalNormalSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int slot,
public OptionalNormalSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int xPos, final int yPos, final int groupNum) {
super(inv, slot, xPos, yPos);
super(inv, invSlot, xPos, yPos);
this.groupNum = groupNum;
this.host = containerBus;
}
@@ -26,9 +26,10 @@ public class OptionalRestrictedInputSlot extends RestrictedInputSlot {
private final int groupNum;
private final IOptionalSlotHost host;
public OptionalRestrictedInputSlot(final PlacableItemType valid, final IItemHandler i, final IOptionalSlotHost host,
final int slotIndex, final int x, final int y, final int grpNum, final PlayerInventory invPlayer) {
super(valid, i, slotIndex, x, y, invPlayer);
public OptionalRestrictedInputSlot(final PlacableItemType valid, final IItemHandler inv,
final IOptionalSlotHost host, final int invSlot, final int x, final int y, final int grpNum,
final PlayerInventory invPlayer) {
super(valid, inv, invSlot, x, y, invPlayer);
this.groupNum = grpNum;
this.host = host;
}
@@ -23,9 +23,9 @@ import net.minecraftforge.items.IItemHandler;
public class OptionalTypeOnlyFakeSlot extends OptionalFakeSlot {
public OptionalTypeOnlyFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx,
public OptionalTypeOnlyFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
super(inv, containerBus, invSlot, x, y, offX, offY, groupNum);
}
@Override
@@ -23,13 +23,13 @@ import net.minecraftforge.items.IItemHandler;
public class OutputSlot extends AppEngSlot {
public OutputSlot(final IItemHandler a, final int b, final int c, final int d, final int i) {
super(a, b, c, d);
this.setIIcon(i);
public OutputSlot(final IItemHandler inv, final int invSlot, final int x, final int y, final int iconIndex) {
super(inv, invSlot, x, y);
this.setIIcon(iconIndex);
}
@Override
public boolean isItemValid(final ItemStack i) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
}
@@ -22,9 +22,9 @@ import net.minecraftforge.items.IItemHandler;
public class PatternOutputsSlot extends OptionalFakeSlot {
public PatternOutputsSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
public PatternOutputsSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, invSlot, x, y, offX, offY, groupNum);
}
@Override
@@ -22,8 +22,8 @@ import net.minecraftforge.items.IItemHandler;
public class PlayerHotBarSlot extends AppEngSlot {
public PlayerHotBarSlot(final IItemHandler par1iInventory, final int par2, final int par3, final int par4) {
super(par1iInventory, par2, par3, par4);
public PlayerHotBarSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.setPlayerSide(true);
}
}
@@ -24,8 +24,8 @@ import net.minecraftforge.items.IItemHandler;
public class PlayerInvSlot extends AppEngSlot {
public PlayerInvSlot(final IItemHandler par1iInventory, final int idx, final int x, final int y) {
super(par1iInventory, idx, x, y);
public PlayerInvSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.setPlayerSide(true);
}
@@ -70,9 +70,9 @@ public class RestrictedInputSlot extends AppEngSlot {
private boolean allowEdit = true;
private int stackLimit = -1;
public RestrictedInputSlot(final PlacableItemType valid, final IItemHandler i, final int slotIndex, final int x,
public RestrictedInputSlot(final PlacableItemType valid, final IItemHandler inv, final int invSlot, final int x,
final int y, final PlayerInventory p) {
super(i, slotIndex, x, y);
super(inv, invSlot, x, y);
this.which = valid;
this.setIIcon(valid.IIcon);
this.p = p;
@@ -99,20 +99,20 @@ public class RestrictedInputSlot extends AppEngSlot {
}
@Override
public boolean isItemValid(final ItemStack i) {
if (!this.getContainer().isValidForSlot(this, i)) {
public boolean isItemValid(final ItemStack stack) {
if (!this.getContainer().isValidForSlot(this, stack)) {
return false;
}
if (i.isEmpty()) {
if (stack.isEmpty()) {
return false;
}
if (i.getItem() == Items.AIR) {
if (stack.getItem() == Items.AIR) {
return false;
}
if (!super.isItemValid(i)) {
if (!super.isItemValid(stack)) {
return false;
}
@@ -127,7 +127,7 @@ public class RestrictedInputSlot extends AppEngSlot {
switch (this.which) {
case ENCODED_CRAFTING_PATTERN:
final ICraftingPatternDetails de = crafting.decodePattern(i, this.p.player.world);
final ICraftingPatternDetails de = crafting.decodePattern(stack, this.p.player.world);
if (de != null) {
return de.isCraftable();
}
@@ -135,19 +135,19 @@ public class RestrictedInputSlot extends AppEngSlot {
case VALID_ENCODED_PATTERN_W_OUTPUT:
case ENCODED_PATTERN_W_OUTPUT:
case ENCODED_PATTERN:
return crafting.isEncodedPattern(i);
return crafting.isEncodedPattern(stack);
case BLANK_PATTERN:
return materials.blankPattern().isSameAs(i);
return materials.blankPattern().isSameAs(stack);
case PATTERN:
return materials.blankPattern().isSameAs(i) || crafting.isEncodedPattern(i);
return materials.blankPattern().isSameAs(stack) || crafting.isEncodedPattern(stack);
case INSCRIBER_PLATE:
if (materials.namePress().isSameAs(i)) {
if (materials.namePress().isSameAs(stack)) {
return true;
}
return InscriberRecipes.isValidOptionalIngredient(p.player.world, i);
return InscriberRecipes.isValidOptionalIngredient(p.player.world, stack);
case INSCRIBER_INPUT:
return true;/*
@@ -157,46 +157,48 @@ public class RestrictedInputSlot extends AppEngSlot {
case METAL_INGOTS:
return isMetalIngot(i);
return isMetalIngot(stack);
case VIEW_CELL:
return items.viewCell().isSameAs(i);
return items.viewCell().isSameAs(stack);
case ORE:
return GrinderRecipes.isValidIngredient(p.player.world, i);
return GrinderRecipes.isValidIngredient(p.player.world, stack);
case FUEL:
return ForgeHooks.getBurnTime(i) > 0;
return ForgeHooks.getBurnTime(stack) > 0;
case POWERED_TOOL:
return Platform.isChargeable(i);
return Platform.isChargeable(stack);
case QE_SINGULARITY:
return materials.qESingularity().isSameAs(i);
return materials.qESingularity().isSameAs(stack);
case RANGE_BOOSTER:
return materials.wirelessBooster().isSameAs(i);
return materials.wirelessBooster().isSameAs(stack);
case SPATIAL_STORAGE_CELLS:
return i.getItem() instanceof ISpatialStorageCell
&& ((ISpatialStorageCell) i.getItem()).isSpatialStorage(i);
return stack.getItem() instanceof ISpatialStorageCell
&& ((ISpatialStorageCell) stack.getItem()).isSpatialStorage(stack);
case STORAGE_CELLS:
return Api.instance().registries().cell().isCellHandled(i);
return Api.instance().registries().cell().isCellHandled(stack);
case WORKBENCH_CELL:
return i.getItem() instanceof ICellWorkbenchItem && ((ICellWorkbenchItem) i.getItem()).isEditable(i);
return stack.getItem() instanceof ICellWorkbenchItem
&& ((ICellWorkbenchItem) stack.getItem()).isEditable(stack);
case STORAGE_COMPONENT:
return i.getItem() instanceof IStorageComponent
&& ((IStorageComponent) i.getItem()).isStorageComponent(i);
return stack.getItem() instanceof IStorageComponent
&& ((IStorageComponent) stack.getItem()).isStorageComponent(stack);
case TRASH:
if (Api.instance().registries().cell().isCellHandled(i)) {
if (Api.instance().registries().cell().isCellHandled(stack)) {
return false;
}
return !(i.getItem() instanceof IStorageComponent
&& ((IStorageComponent) i.getItem()).isStorageComponent(i));
return !(stack.getItem() instanceof IStorageComponent
&& ((IStorageComponent) stack.getItem()).isStorageComponent(stack));
case ENCODABLE_ITEM:
return i.getItem() instanceof INetworkEncodable
|| Api.instance().registries().wireless().isWirelessTerminal(i);
return stack.getItem() instanceof INetworkEncodable
|| Api.instance().registries().wireless().isWirelessTerminal(stack);
case BIOMETRIC_CARD:
return i.getItem() instanceof IBiometricCard;
return stack.getItem() instanceof IBiometricCard;
case UPGRADES:
return i.getItem() instanceof IUpgradeModule && ((IUpgradeModule) i.getItem()).getType(i) != null;
return stack.getItem() instanceof IUpgradeModule
&& ((IUpgradeModule) stack.getItem()).getType(stack) != null;
default:
break;
}
@@ -205,7 +207,7 @@ public class RestrictedInputSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return this.isAllowEdit();
}
+1 -1
View File
@@ -117,7 +117,7 @@ public final class AppEng {
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
proxy = DistExecutor.safeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
proxy = DistExecutor.unsafeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
CreativeTab.init();
new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
+10 -2
View File
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerEntity;
@@ -55,11 +56,18 @@ public abstract class CommonHelper {
public abstract void postInit();
public abstract CableRenderMode getRenderMode();
public abstract CableRenderMode getCableRenderMode();
public abstract void triggerUpdates();
public abstract void updateRenderMode(PlayerEntity player);
/**
* Sets the player that is currently interacting with a cable or part attached
* to a cable. This will return that player's cable render mode from calls to
* {@link #getCableRenderMode()}, until another player or null is set.
*
* @param player Null to revert to the default cable render mode.
*/
public abstract void setPartInteractionPlayer(@Nullable PlayerEntity player);
public abstract boolean isActionKey(@Nonnull final ActionKey key, InputMappings.Input input);
+1 -1
View File
@@ -41,6 +41,6 @@ public class ApiPart implements IPartHelper {
@Override
public CableRenderMode getCableRenderMode() {
return AppEng.proxy.getRenderMode();
return AppEng.proxy.getCableRenderMode();
}
}
@@ -39,6 +39,7 @@ import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
import appeng.block.crafting.CraftingMonitorBlock;
import appeng.block.crafting.CraftingMonitorBlockRendering;
import appeng.block.crafting.CraftingStorageBlock;
import appeng.block.crafting.CraftingStorageItem;
import appeng.block.crafting.CraftingUnitBlock;
@@ -94,9 +95,8 @@ import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.client.render.crafting.CraftingCubeRendering;
import appeng.client.render.crafting.CraftingMonitorTESR;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
import appeng.client.render.spatial.SpatialPylonRendering;
import appeng.client.render.tesr.ChargerTESR;
import appeng.client.render.tesr.ChestTileEntityRenderer;
import appeng.client.render.tesr.CrankTESR;
import appeng.client.render.tesr.DriveLedTileEntityRenderer;
@@ -371,7 +371,7 @@ public final class ApiBlocks implements IBlocks {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(TileEntityRendering<ChargerTileEntity> rendering) {
rendering.tileEntityRenderer(ChargerBlock.createTesr());
rendering.tileEntityRenderer(ChargerTESR.FACTORY);
}
}).build())
.build();
@@ -532,20 +532,7 @@ public final class ApiBlocks implements IBlocks {
rendering.tileEntityRenderer(CraftingMonitorTESR::new);
}
}).build())
.rendering(new BlockRenderingCustomizer() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer((path, model) -> {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
});
}
}).build();
.rendering(new CraftingMonitorBlockRendering()).build();
this.molecularAssembler = registry
.block("molecular_assembler", () -> new MolecularAssemblerBlock(defaultProps(Material.IRON).notSolid()))
@@ -23,6 +23,9 @@ import java.util.function.Consumer;
import net.minecraft.entity.EntityClassification;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.Rarity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ToolType;
@@ -35,6 +38,8 @@ import appeng.api.util.AEColoredItemDefinition;
import appeng.bootstrap.FeatureFactory;
import appeng.bootstrap.IItemRendering;
import appeng.bootstrap.ItemRenderingCustomizer;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.core.AppEng;
import appeng.core.features.ActivityState;
import appeng.core.features.ColoredItemDefinition;
import appeng.core.features.ItemStackSrc;
@@ -210,7 +215,22 @@ public final class ApiItems implements IItems {
.addFeatures(AEFeature.PORTABLE_CELL, AEFeature.STORAGE_CELLS).build();
this.colorApplicator = powerTools.item("color_applicator", ColorApplicatorItem::new).props(chargedDefaults)
.addFeatures(AEFeature.COLOR_APPLICATOR).dispenserBehavior(BlockToolDispenseItemBehavior::new)
.rendering(new ColorApplicatorItemRendering()).build();
.bootstrap(item -> new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item;
ItemModelsProperties.func_239418_a_(item, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> {
// If the stack has no color, don't use the colored model since the impact of
// calling getColor for every quad is extremely high, if the stack tries to
// re-search its
// inventory for a new paintball everytime
AEColor col = colorApplicatorItem.getActiveColor(itemStack);
return (col != null) ? 1 : 0;
});
}
}).rendering(new ColorApplicatorItemRendering()).build();
this.biometricCard = registry.item("biometric_card", BiometricCardItem::new)
.props(props -> props.maxStackSize(1)).features(AEFeature.SECURITY).build();
@@ -221,7 +241,8 @@ public final class ApiItems implements IItems {
.features(AEFeature.NETWORK_TOOL).build();
this.cellCreative = registry.item("creative_storage_cell", CreativeStorageCellItem::new)
.props(props -> props.maxStackSize(1)).features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
.props(props -> props.maxStackSize(1).rarity(Rarity.EPIC))
.features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
this.viewCell = registry.item("view_cell", ViewCellItem::new).props(props -> props.maxStackSize(1))
.features(AEFeature.VIEW_CELL).build();
@@ -278,7 +299,16 @@ public final class ApiItems implements IItems {
this.certusCrystalSeed = registry
.item("certus_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedCertusQuartzCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(item -> new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
// Expose the growth of the seed to the model system
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:growth"),
(is, w, p) -> CrystalSeedItem.getGrowthTicks(is)
/ (float) CrystalSeedItem.GROWTH_TICKS_REQUIRED);
}
}).features(AEFeature.CRYSTAL_SEEDS).build();
this.fluixCrystalSeed = registry
.item("fluix_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedFluixCrystal().item()))
@@ -68,11 +68,14 @@ public class PartPlacementPacket extends BasePacket {
@Override
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
final ServerPlayerEntity sender = (ServerPlayerEntity) player;
AppEng.proxy.updateRenderMode(sender);
PartPlacement.setEyeHeight(this.eyeHeight);
PartPlacement.place(sender.getHeldItem(this.hand), new BlockPos(this.x, this.y, this.z),
Direction.values()[this.face], sender, this.hand, sender.world,
PartPlacement.PlaceType.INTERACT_FIRST_PASS, 0);
AppEng.proxy.updateRenderMode(null);
AppEng.proxy.setPartInteractionPlayer(sender);
try {
PartPlacement.setEyeHeight(this.eyeHeight);
PartPlacement.place(sender.getHeldItem(this.hand), new BlockPos(this.x, this.y, this.z),
Direction.values()[this.face], sender, this.hand, sender.world,
PartPlacement.PlaceType.INTERACT_FIRST_PASS, 0);
} finally {
AppEng.proxy.setPartInteractionPlayer(null);
}
}
}
+1 -1
View File
@@ -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 {
@@ -12,6 +12,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
@@ -55,7 +56,8 @@ public class FluidSlotWidget extends CustomSlotWidget {
final float blue = (attributes.getColor() & 255) / 255.0F;
RenderSystem.color3f(red, green, blue);
blit(matrixStack, xPos(), yPos(), this.getBlitOffset(), getWidth(), getHeight(), sprite);
blit(matrixStack, getTooltipAreaX(), getTooltipAreaY(), this.getBlitOffset(), getTooltipAreaWidth(),
getTooltipAreaHeight(), sprite);
}
}
@@ -79,16 +81,16 @@ public class FluidSlotWidget extends CustomSlotWidget {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
final IAEFluidStack fluid = this.getFluidStack();
if (fluid != null) {
return new TranslationTextComponent(fluid.getFluidStack().getTranslationKey());
}
return null;
return StringTextComponent.EMPTY;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -89,7 +89,7 @@ public class FluidTankWidget extends Widget implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot);
if (fluid != null && fluid.getStackSize() > 0) {
return fluid.getFluid().getAttributes().getDisplayName(fluid.getFluidStack()).deepCopy()
@@ -99,27 +99,27 @@ public class FluidTankWidget extends Widget 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;
}
@@ -48,7 +48,8 @@ public class OptionalFluidSlotWidget extends FluidSlotWidget {
} else {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F);
}
GuiUtils.drawTexturedModalRect(guileft + this.xPos() - 1, guitop + this.yPos() - 1, this.srcX - 1,
this.srcY - 1, this.getWidth() + 2, this.getHeight() + 2, currentZIndex);
GuiUtils.drawTexturedModalRect(guileft + this.getTooltipAreaX() - 1, guitop + this.getTooltipAreaY() - 1,
this.srcX - 1, this.srcY - 1, this.getTooltipAreaWidth() + 2, this.getTooltipAreaHeight() + 2,
currentZIndex);
}
}
@@ -210,7 +210,7 @@ public class DualityFluidInterface
} else if (capabilityClass == Capabilities.STORAGE_MONITORABLE_ACCESSOR) {
return (LazyOptional<T>) LazyOptional.of(() -> this.accessor);
}
return null;
return LazyOptional.empty();
}
private boolean hasConfig() {
@@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tags.FluidTags;
import net.minecraft.tags.ITag;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
@@ -35,15 +34,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;
@@ -53,6 +49,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.PlaneModelData;
import appeng.parts.automation.PlaneModels;
@@ -73,115 +70,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 TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(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 TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
return connectionHelper.getConnections();
}
@Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
this.refresh();
} else {
connectionHelper.updateConnections();
}
}
@@ -190,14 +99,6 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
return 1;
}
private boolean isAnnihilationPlane(final TileEntity 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());
@@ -61,7 +61,7 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
/**
* The number of growth ticks required to finish growing.
*/
private static final int GROWTH_TICKS_REQUIRED = 600;
public static final int GROWTH_TICKS_REQUIRED = 600;
/**
* The item to convert to, when growth finishes.
@@ -71,9 +71,6 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
public CrystalSeedItem(Properties properties, IItemProvider grownItem) {
super(properties);
this.grownItem = Preconditions.checkNotNull(grownItem);
// Expose the growth of the seed to the model system
ItemModelsProperties.func_239418_a_(this, new ResourceLocation("appliedenergistics2:growth"),
(is, w, p) -> getGrowthTicks(is) / (float) GROWTH_TICKS_REQUIRED);
}
@Nullable
@@ -88,7 +85,7 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
}
}
private static int getGrowthTicks(final ItemStack is) {
public static int getGrowthTicks(final ItemStack is) {
CompoundNBT tag = is.getTag();
return tag != null ? tag.getInt(TAG_GROWTH_TICKS) : 0;
}
@@ -107,15 +107,6 @@ public class ColorApplicatorItem extends AEBasePoweredItem
public ColorApplicatorItem(Item.Properties props) {
super(AEConfig.instance().getColorApplicatorBattery(), props);
ItemModelsProperties.func_239418_a_(this, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> {
// If the stack has no color, don't use the colored model since the impact of
// calling getColor for every quad is extremely high, if the stack tries to
// re-search its
// inventory for a new paintball everytime
AEColor col = getActiveColor(itemStack);
return (col != null) ? 1 : 0;
});
}
@Override
@@ -12,6 +12,7 @@ import net.minecraft.util.RegistryKey;
import net.minecraft.world.DimensionType;
import appeng.spatial.SpatialDimensionManager;
import appeng.spatial.StorageSkyProperties;
@Mixin(DimensionRenderInfo.class)
public class SkyPropertiesMixin {
@@ -20,7 +21,7 @@ public class SkyPropertiesMixin {
private static void byDimensionType(Optional<RegistryKey<DimensionType>> optional,
CallbackInfoReturnable<DimensionRenderInfo> ci) {
if (optional.orElse(null) == SpatialDimensionManager.STORAGE_DIMENSION_TYPE) {
ci.setReturnValue(SpatialDimensionManager.STORAGE_SKY);
ci.setReturnValue(StorageSkyProperties.INSTANCE);
}
}
@@ -330,11 +330,12 @@ public class PartPlacement {
}
private static SelectedPart selectPart(final PlayerEntity player, final IPartHost host, final Vector3d pos) {
AppEng.proxy.updateRenderMode(player);
final SelectedPart sp = host.selectPart(pos);
AppEng.proxy.updateRenderMode(null);
return sp;
AppEng.proxy.setPartInteractionPlayer(player);
try {
return host.selectPart(pos);
} finally {
AppEng.proxy.setPartInteractionPlayer(null);
}
}
public static IFacadePart isFacade(final ItemStack held, final AEPartLocation side) {
@@ -4,16 +4,13 @@ package appeng.parts.automation;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
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 +27,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 +62,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 TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(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 TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
return connectionHelper.getConnections();
}
@Override
@@ -172,6 +78,8 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
final BlockPos tePos = te.getPos().offset(side.getFacing());
this.blocked = !w.getBlockState(tePos).getMaterial().isReplaceable();
} else {
connectionHelper.updateConnections();
}
}
@@ -180,14 +88,6 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
return 1;
}
protected boolean isTransitionPlane(final TileEntity 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;
@@ -35,7 +35,6 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ITag;
import net.minecraft.tags.ItemTags;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
@@ -58,9 +57,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;
@@ -96,53 +93,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 TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(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);
}
/**
@@ -150,73 +125,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 TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
return connectionHelper.getConnections();
}
@Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
this.refresh();
} else {
connectionHelper.updateConnections();
}
}
@@ -362,14 +279,6 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
return changed;
}
protected boolean isAnnihilationPlane(final TileEntity 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,26 +21,23 @@ package appeng.parts.automation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.DirectionalPlaceContext;
import net.minecraft.item.FireworkRocketItem;
import net.minecraft.item.FireworkStarItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.item.WallOrFloorItem;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Hand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
@@ -49,7 +46,6 @@ import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.items.IItemHandler;
import appeng.api.config.AccessRestriction;
@@ -64,7 +60,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;
@@ -89,6 +84,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() {
@@ -222,12 +218,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 IPlantable
|| i instanceof FireworkStarItem || i instanceof FireworkRocketItem || i instanceof IPartItem)) {
if (placeBlock == YesNo.YES) {
final PlayerEntity player = Platform.getPlayer((ServerWorld) w);
Platform.configurePlayer(player, side, this.getTile());
Hand hand = player.getActiveHand();
player.setHeldItem(hand, is);
// Seems to work without...
// Hand hand = player.getActiveHand();
// player.setHeldItem(hand, is);
maxStorage = is.getCount();
worked = true;
@@ -235,84 +231,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 IPlantable || i instanceof WallOrFloorItem) {
boolean Worked = false;
i.onItemUse(context);
maxStorage -= is.getCount();
// Up or Down, Attempt 1??
if (side.xOffset == 0 && side.zOffset == 0) {
Worked = i.onItemUse(new DirectionalPlaceContext(w, placePos.offset(side.getFacing()),
lookDirection, is, side.getFacing())) == ActionResultType.SUCCESS;
}
// Up or Down, Attempt 2??
if (!Worked && side.xOffset == 0 && side.zOffset == 0) {
Worked = i.onItemUse(new DirectionalPlaceContext(w,
placePos.offset(side.getFacing().getOpposite()), lookDirection, is,
side.getFacing().getOpposite())) == ActionResultType.SUCCESS;
}
// Horizontal, attempt 1??
if (!Worked && side.yOffset == 0) {
Worked = i.onItemUse(new DirectionalPlaceContext(w, placePos.offset(Direction.DOWN),
lookDirection, is, Direction.DOWN)) == ActionResultType.SUCCESS;
}
if (!Worked) {
i.onItemUse(new DirectionalPlaceContext(w, placePos, lookDirection, is,
lookDirection.getOpposite()));
}
maxStorage -= is.getCount();
} else {
i.onItemUse(new DirectionalPlaceContext(w, placePos, lookDirection, is,
lookDirection.getOpposite()));
maxStorage -= is.getCount();
}
} else {
maxStorage = 1;
}
// Safe keeping
player.setHeldItem(hand, ItemStack.EMPTY);
// Seems to work without... Safe keeping
// player.setHeldItem(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());
Entity result = ei;
ei.setMotion(side.xOffset * 0.2, side.yOffset * 0.2, side.zOffset * 0.2);
if (is.getItem().hasCustomEntity(is)) {
result = is.getItem().createEntity(w, ei, is);
if (result != null) {
ei.remove();
} else {
result = ei;
}
}
if (!w.addEntity(result)) {
result.remove();
if (!spawnItemEntity(w, te, side, is)) {
// revert in case something prevents spawning.
worked = false;
}
}
} else {
worked = false;
}
}
}
@@ -331,6 +276,57 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
return input;
}
private static boolean spawnItemEntity(World w, TileEntity 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());
Entity result = ei;
ei.setMotion(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1);
if (is.getItem().hasCustomEntity(is)) {
result = is.getItem().createEntity(w, ei, is);
if (result != null) {
ei.remove();
} else {
result = ei;
}
}
if (!w.addEntity(result)) {
result.remove();
return false;
}
return true;
}
@Override
public IStorageChannel<IAEItemStack> getChannel() {
return Api.instance().storage().getStorageChannel(IItemStorageChannel.class);
@@ -364,11 +360,76 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
return list.size();
}
private class ForcedItemUseContext extends ItemUseContext {
protected ForcedItemUseContext(World worldIn, @Nullable PlayerEntity player, Hand handIn, ItemStack heldItem,
BlockRayTraceResult 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);
}
}
}
@@ -55,15 +55,6 @@ public class IdentityAnnihilationPlanePart extends AnnihilationPlanePart {
super(is);
}
@Override
protected boolean isAnnihilationPlane(final TileEntity 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,15 +18,10 @@
package appeng.parts.p2p;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
@@ -37,18 +32,18 @@ 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 IFluidHandler {
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 LazyOptional<IFluidHandler> cachedTank;
private int tmpUsed;
private final IFluidHandler inputHandler = new InputFluidHandler();
private final IFluidHandler outputHandler = new OutputFluidHandler();
public FluidP2PTunnelPart(final ItemStack is) {
super(is);
@@ -65,13 +60,10 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
@Override
public void onTunnelNetworkChange() {
this.cachedTank = null;
}
@Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
this.cachedTank = null;
if (this.isOutput()) {
final FluidP2PTunnelPart in = this.getInput();
if (in != null) {
@@ -84,7 +76,10 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
@Override
public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return (LazyOptional<T>) LazyOptional.of(() -> this);
if (this.isOutput()) {
return (LazyOptional<T>) LazyOptional.of(() -> this.outputHandler);
}
return (LazyOptional<T>) LazyOptional.of(() -> this.inputHandler);
}
return super.getCapability(capabilityClass);
@@ -95,168 +90,173 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
return MODELS.getModel(this.isPowered(), this.isActive());
}
@Override
public int getTanks() {
return 0;
}
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()));
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return 1000;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
final Deque<FluidP2PTunnelPart> stack = this.getDepth();
for (final FluidP2PTunnelPart t : stack) {
if (t == this) {
return 0;
if (te != null) {
fluidHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getOpposite().getFacing());
}
}
return fluidHandler.orElse(NULL_FLUID_HANDLER);
}
stack.push(this);
private class InputFluidHandler implements IFluidHandler {
final List<FluidP2PTunnelPart> list = this.getOutputs(resource.getFluid());
int requestTotal = 0;
Iterator<FluidP2PTunnelPart> i = list.iterator();
while (i.hasNext()) {
final FluidP2PTunnelPart l = i.next();
final IFluidHandler tank = l.getTarget().orElse(null);
if (tank != null) {
l.tmpUsed = tank.fill(resource.copy(), FluidAction.SIMULATE);
} else {
l.tmpUsed = 0;
}
if (l.tmpUsed <= 0) {
i.remove();
} else {
requestTotal += l.tmpUsed;
}
@Override
public int getTanks() {
return 1;
}
if (requestTotal <= 0) {
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return Integer.MAX_VALUE;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return true;
}
@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) {
}
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;
}
}
private class OutputFluidHandler implements IFluidHandler {
@Override
public int getTanks() {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTanks();
}
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getFluidInTank(tank);
}
@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;
}
if (action != FluidAction.EXECUTE) {
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
return Math.min(resource.getAmount(), requestTotal);
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(resource, action);
}
int available = resource.getAmount();
i = list.iterator();
int used = 0;
while (i.hasNext() && available > 0) {
final FluidP2PTunnelPart l = i.next();
final FluidStack insert = resource.copy();
insert.setAmount((int) Math.ceil(insert.getAmount() * ((double) l.tmpUsed / (double) requestTotal)));
if (insert.getAmount() > available) {
insert.setAmount(available);
}
final IFluidHandler tank = l.getTarget().orElse(null);
if (tank != null) {
l.tmpUsed = tank.fill(insert.copy(), action);
} else {
l.tmpUsed = 0;
}
available -= insert.getAmount();
used += l.tmpUsed;
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(maxDrain, action);
}
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
return used;
}
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
private static class NullFluidHandler implements IFluidHandler {
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
private Deque<FluidP2PTunnelPart> getDepth() {
Deque<FluidP2PTunnelPart> s = DEPTH.get();
if (s == null) {
DEPTH.set(s = new ArrayDeque<>());
@Override
public int getTanks() {
return 0;
}
return s;
}
private List<FluidP2PTunnelPart> getOutputs(final Fluid input) {
final List<FluidP2PTunnelPart> outs = new ArrayList<>();
try {
for (final FluidP2PTunnelPart l : this.getOutputs()) {
final IFluidHandler handler = l.getTarget().orElse(null);
if (handler != null) {
outs.add(l);
}
}
} catch (final GridAccessException e) {
// :P
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
return outs;
}
private LazyOptional<IFluidHandler> getTarget() {
if (!this.getProxy().isActive()) {
return null;
@Override
public int getTankCapacity(int tank) {
return 0;
}
if (this.cachedTank != null) {
return this.cachedTank;
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
}
final TileEntity te = this.getTile().getWorld()
.getTileEntity(this.getTile().getPos().offset(this.getSide().getFacing()));
if (te != null && te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getFacing().getOpposite()).isPresent()) {
return this.cachedTank = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getFacing().getOpposite());
@Override
public int fill(FluidStack resource, FluidAction action) {
return 0;
}
return null;
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
}
}
+18 -10
View File
@@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
@@ -46,7 +48,17 @@ import appeng.util.Platform;
public class ServerHelper extends CommonHelper {
private PlayerEntity renderModeBased;
/**
* While we process a player-specific part placement/cable interaction packet,
* we need to use that player's transparent-facade mode to understand whether
* the player can see through facades or not.
* <p>
* We need to use this method since the collision shape methods do not know
* about the player that the shape is being requested for, so they will call
* {@link #getCableRenderMode()} below, which then will use this field to figure
* out which player it's for.
*/
private final ThreadLocal<PlayerEntity> partInteractionPlayer = new ThreadLocal<>();
@Override
public World getWorld() {
@@ -112,12 +124,8 @@ public class ServerHelper extends CommonHelper {
}
@Override
public CableRenderMode getRenderMode() {
if (this.renderModeBased == null) {
return CableRenderMode.STANDARD;
}
return this.renderModeForPlayer(this.renderModeBased);
public CableRenderMode getCableRenderMode() {
return this.getCableRenderModeForPlayer(partInteractionPlayer.get());
}
@Override
@@ -126,11 +134,11 @@ public class ServerHelper extends CommonHelper {
}
@Override
public void updateRenderMode(final PlayerEntity player) {
this.renderModeBased = player;
public void setPartInteractionPlayer(final PlayerEntity player) {
this.partInteractionPlayer.set(player);
}
protected CableRenderMode renderModeForPlayer(final PlayerEntity player) {
protected final CableRenderMode getCableRenderModeForPlayer(@Nullable final PlayerEntity player) {
if (player != null) {
for (int x = 0; x < PlayerInventory.getHotbarSize(); x++) {
final ItemStack is = player.inventory.getStackInSlot(x);
@@ -23,12 +23,10 @@ import java.util.Locale;
import javax.annotation.Nullable;
import net.minecraft.client.world.DimensionRenderInfo;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.DimensionType;
@@ -52,27 +50,6 @@ public final class SpatialDimensionManager implements ISpatialDimension {
public static final RegistryKey<DimensionType> STORAGE_DIMENSION_TYPE = RegistryKey
.func_240903_a_(Registry.DIMENSION_TYPE_KEY, AppEng.makeId("storage_cell"));
// See the fabric version of this to get any idea what its doing
public static final DimensionRenderInfo STORAGE_SKY = new DimensionRenderInfo(Float.NaN /* disables clouds */,
false, DimensionRenderInfo.FogType.NONE /* we use a custom render mixin */, true, false) {
@Override
public Vector3d func_230494_a_(Vector3d p_230494_1_, float p_230494_2_) {
return Vector3d.ZERO;
}
@Override
public boolean func_230493_a_(int p_230493_1_, int p_230493_2_) {
return false;
}
@Nullable
@Override
public float[] func_230492_a_(float p_230492_1_, float p_230492_2_) {
return null;
}
};
public static final ISpatialDimension INSTANCE = new SpatialDimensionManager();
private static final String DIM_ID_PREFIX = "spatial_";
@@ -0,0 +1,34 @@
package appeng.spatial;
import javax.annotation.Nullable;
import net.minecraft.client.world.DimensionRenderInfo;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class StorageSkyProperties {
// See the fabric version of this to get any idea what its doing
public static final DimensionRenderInfo INSTANCE = new DimensionRenderInfo(Float.NaN /* disables clouds */, false,
DimensionRenderInfo.FogType.NONE /* we use a custom render mixin */, true, false) {
@Override
public Vector3d func_230494_a_(Vector3d p_230494_1_, float p_230494_2_) {
return Vector3d.ZERO;
}
@Override
public boolean func_230493_a_(int p_230493_1_, int p_230493_2_) {
return false;
}
@Nullable
@Override
public float[] func_230492_a_(float p_230492_1_, float p_230492_2_) {
return null;
}
};
}
@@ -311,7 +311,7 @@ public class CableBusTileEntity extends AEBaseTileEntity implements AEMultiTile
IPart part = this.getPart(partLocation);
LazyOptional<T> result = part == null ? LazyOptional.empty() : part.getCapability(capabilityClass);
if (result != null) {
if (result.isPresent()) {
return result;
}
@@ -7,94 +7,71 @@
"elements": [
{
"name": "Base",
"from": [1.0, 0.0, 1.0],
"to": [15.0, 10.0, 15.0],
"from": [1, 0, 1],
"to": [15, 10, 15],
"shade": false,
"faces": {
"north": {
"texture": "#0",
"uv": [3.5, 8.25, 7, 10.75]
"uv": [3.5, 8.25, 7, 10.75],
"rotation": 180,
"texture": "#0"
},
"east": {
"texture": "#0",
"uv": [0.0, 8.25, 3.5, 10.75]
"uv": [0, 8.25, 3.5, 10.75],
"rotation": 180,
"texture": "#0"
},
"south": {
"texture": "#0",
"uv": [10.5, 8.25, 14, 10.75]
"uv": [10.5, 8.25, 14, 10.75],
"rotation": 180,
"texture": "#0"
},
"west": {
"texture": "#0",
"uv": [7, 8.25, 10.5, 10.75]
"uv": [7, 8.25, 10.5, 10.75],
"rotation": 180,
"texture": "#0"
},
"up": {
"texture": "#0",
"uv": [3.5, 0.0, 7, 3.5]
},
"down": {
"texture": "#0",
"uv": [7, 0.0, 10.5, 3.5]
}
"up": { "uv": [3.5, 0, 7, 3.5], "texture": "#0" },
"down": { "uv": [7, 0, 10.5, 3.5], "texture": "#0" }
}
},
{
"name": "Lid",
"from": [1.0, 10.0, 1.0],
"to": [15.0, 15.0, 15.0],
"from": [1, 10, 1],
"to": [15, 15, 15],
"shade": false,
"faces": {
"north": {
"texture": "#0",
"uv": [3.5, 3.5, 7, 4.75]
},
"east": {
"texture": "#0",
"uv": [0.0, 3.5, 3.5, 4.75]
"uv": [3.5, 3.5, 7, 4.75],
"rotation": 180,
"texture": "#0"
},
"east": { "uv": [0, 3.5, 3.5, 4.75], "rotation": 180, "texture": "#0" },
"south": {
"texture": "#0",
"uv": [10.5, 3.5, 14, 4.75]
"uv": [10.5, 3.5, 14, 4.75],
"rotation": 180,
"texture": "#0"
},
"west": {
"texture": "#0",
"uv": [7, 3.5, 10.5, 4.75]
"uv": [7, 3.5, 10.5, 4.75],
"rotation": 180,
"texture": "#0"
},
"up": {
"texture": "#0",
"uv": [3.5, 0.0, 7, 3.5]
},
"down": {
"texture": "#0",
"uv": [7, 0.0, 10.5, 3.5]
}
"up": { "uv": [7, 0, 10.5, 3.5], "rotation": 270, "texture": "#0" },
"down": { "uv": [7, 0, 10.5, 3.5], "texture": "#0" }
}
},
{
"name": "Knob",
"from": [7.0, 7.0, 0.0],
"to": [9.0, 11.0, 1.0],
"from": [7, 7, 0],
"to": [9, 11, 1],
"shade": false,
"faces": {
"north": {
"texture": "#0",
"uv": [0.25, 0.25, 0.75, 1.25]
},
"east": {
"texture": "#0",
"uv": [0, 0.25, 0.25, 1.25]
},
"west": {
"texture": "#0",
"uv": [0.75, 0.25, 1.5, 1.25]
},
"up": {
"texture": "#0",
"uv": [0.25, 0.0, 0.75, 0.25]
},
"down": {
"texture": "#0",
"uv": [0.75, 0.0, 1.5, 0.25]
}
"north": { "uv": [0.25, 0.25, 0.75, 1.25], "texture": "#0" },
"east": { "uv": [0, 0.25, 0.25, 1.25], "texture": "#0" },
"west": { "uv": [0.75, 0.25, 1.5, 1.25], "texture": "#0" },
"up": { "uv": [0.25, 0, 0.75, 0.25], "texture": "#0" },
"down": { "uv": [0.75, 0, 1.5, 0.25], "texture": "#0" }
}
}
]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB