Moving to source sets

This commit is contained in:
Sebastian Hartte
2020-07-01 23:36:51 +02:00
parent f2e3d81fd7
commit 2642ced86b
2924 changed files with 794 additions and 796 deletions
@@ -0,0 +1,100 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.crafting;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.CraftingCPUContainer;
import appeng.tile.crafting.CraftingBlockEntity;
public abstract class AbstractCraftingUnitBlock<T extends CraftingBlockEntity> extends AEBaseTileBlock<T> {
public static final BooleanProperty FORMED = BooleanProperty.of("formed");
public static final BooleanProperty POWERED = BooleanProperty.of("powered");
public final CraftingUnitType type;
public AbstractCraftingUnitBlock(Settings props, final CraftingUnitType type) {
super(props);
this.type = type;
this.setDefaultState(getDefaultState().with(FORMED, false).with(POWERED, false));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
builder.add(FORMED);
}
@Override
public void neighborUpdate(final BlockState state, final World worldIn, final BlockPos pos, final Block blockIn,
final BlockPos fromPos, boolean isMoving) {
final CraftingBlockEntity cp = this.getBlockEntity(worldIn, pos);
if (cp != null) {
cp.updateMultiBlock();
}
}
@Override
public void onStateReplaced(BlockState state, World w, BlockPos pos, BlockState newState, boolean isMoving) {
if (newState.getBlock() == state.getBlock()) {
return; // Just a block state change
}
final CraftingBlockEntity cp = this.getBlockEntity(w, pos);
if (cp != null) {
cp.breakCluster();
}
super.onStateReplaced(state, w, pos, newState, isMoving);
}
@Override
public ActionResult onUse(BlockState state, World w, BlockPos pos, PlayerEntity p, Hand hand,
BlockHitResult hit) {
final CraftingBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null && !p.isInSneakingPose() && tg.isFormed() && tg.isActive()) {
if (!w.isClient()) {
ContainerOpener.openContainer(CraftingCPUContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return super.onUse(state, w, pos, p, hand, hit);
}
public enum CraftingUnitType {
UNIT, ACCELERATOR, STORAGE_1K, STORAGE_4K, STORAGE_16K, STORAGE_64K, MONITOR
}
}
@@ -0,0 +1,27 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.crafting;
import appeng.tile.crafting.CraftingMonitorBlockEntity;
public class CraftingMonitorBlock extends AbstractCraftingUnitBlock<CraftingMonitorBlockEntity> {
public CraftingMonitorBlock(Settings props) {
super(props, CraftingUnitType.MONITOR);
}
}
@@ -0,0 +1,29 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.crafting;
import appeng.tile.crafting.CraftingStorageBlockEntity;
public class CraftingStorageBlock extends AbstractCraftingUnitBlock<CraftingStorageBlockEntity> {
public CraftingStorageBlock(Settings props, CraftingUnitType type) {
super(props, type);
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.crafting;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlockItem;
import appeng.core.AEConfig;
public class CraftingStorageItem extends AEBaseBlockItem {
public CraftingStorageItem(Block id, Settings props) {
super(id, props);
}
@Override
public ItemStack getRecipeRemainder(final ItemStack itemStack) {
return AEApi.instance().definitions().blocks().craftingUnit().maybeStack(1).orElse(ItemStack.EMPTY);
}
@Override
public boolean hasRecipeRemainder(final ItemStack stack) {
return AEConfig.instance().isFeatureEnabled(AEFeature.ENABLE_DISASSEMBLY_CRAFTING);
}
}
@@ -0,0 +1,29 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.crafting;
import appeng.tile.crafting.CraftingBlockEntity;
public class CraftingUnitBlock extends AbstractCraftingUnitBlock<CraftingBlockEntity> {
public CraftingUnitBlock(Settings props, CraftingUnitType type) {
super(props, type);
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.crafting;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.MolecularAssemblerContainer;
import appeng.tile.crafting.MolecularAssemblerBlockEntity;
public class MolecularAssemblerBlock extends AEBaseTileBlock<MolecularAssemblerBlockEntity> {
public static final BooleanProperty POWERED = BooleanProperty.of("powered");
public MolecularAssemblerBlock(Settings props) {
super(props);
setDefaultState(getDefaultState().with(POWERED, false));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, MolecularAssemblerBlockEntity te) {
return currentState.with(POWERED, te.isPowered());
}
@Override
public ActionResult onUse(BlockState state, World w, BlockPos pos, PlayerEntity p, Hand hand,
BlockHitResult hit) {
final MolecularAssemblerBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null && !p.isInSneakingPose()) {
if (!tg.isClient()) {
ContainerOpener.openContainer(MolecularAssemblerContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return super.onUse(state, w, pos, p, hand, hit);
}
}
@@ -0,0 +1,163 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.grindstone;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import appeng.api.implementations.tiles.ICrankable;
import appeng.block.AEBaseTileBlock;
import appeng.core.stats.AeStats;
import appeng.tile.AEBaseBlockEntity;
import appeng.tile.grindstone.CrankBlockEntity;
public class CrankBlock extends AEBaseTileBlock<CrankBlockEntity> {
public CrankBlock(Settings props) {
super(props);
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (player instanceof FakePlayer || player == null) {
this.dropCrank(w, pos);
return ActionResult.SUCCESS;
}
final CrankBlockEntity tile = this.getBlockEntity(w, pos);
if (tile != null) {
if (tile.power()) {
AeStats.TurnedCranks.addToPlayer(player, 1);
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
private void dropCrank(final World world, final BlockPos pos) {
world.breakBlock(pos, true);
world.updateListeners(pos, this.getDefaultState(), world.getBlockState(pos), 3);
}
@Override
public void onPlaced(final World world, final BlockPos pos, final BlockState state,
final LivingEntity placer, final ItemStack stack) {
final AEBaseBlockEntity tile = this.getBlockEntity(world, pos);
if (tile != null) {
final Direction mnt = this.findCrankable(world, pos);
Direction forward = Direction.UP;
if (mnt == Direction.UP || mnt == Direction.DOWN) {
forward = Direction.SOUTH;
}
tile.setOrientation(forward, mnt.getOpposite());
} else {
this.dropCrank(world, pos);
}
}
@Override
public boolean isValidOrientation(final WorldAccess w, final BlockPos pos, final Direction forward, final Direction up) {
final BlockEntity te = w.getBlockEntity(pos);
return !(te instanceof CrankBlockEntity) || this.isCrankable(w, pos, up.getOpposite());
}
private Direction findCrankable(final BlockView world, final BlockPos pos) {
for (final Direction dir : Direction.values()) {
if (this.isCrankable(world, pos, dir)) {
return dir;
}
}
return null;
}
private boolean isCrankable(final BlockView world, final BlockPos pos, final Direction offset) {
final BlockPos o = pos.offset(offset);
final BlockEntity te = world.getBlockEntity(o);
return te instanceof ICrankable && ((ICrankable) te).canCrankAttach(offset.getOpposite());
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.ENTITYBLOCK_ANIMATED;
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final AEBaseBlockEntity tile = this.getBlockEntity(world, pos);
if (tile != null) {
if (!this.isCrankable(world, pos, tile.getUp().getOpposite())) {
this.dropCrank(world, pos);
}
} else {
this.dropCrank(world, pos);
}
}
@Override
public boolean canPlaceAt(BlockState state, WorldView w, BlockPos pos) {
return this.findCrankable(w, pos) != null;
}
private Direction getUp(BlockView world, BlockPos pos) {
CrankBlockEntity crank = getBlockEntity(world, pos);
return crank != null ? crank.getUp() : null;
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Direction up = getUp(world, pos);
if (up == null) {
return VoxelShapes.empty();
} else {
// FIXME: Cache per direction, and build it 'precise', not just from AABB
final double xOff = -0.15 * up.getOffsetX();
final double yOff = -0.15 * up.getOffsetY();
final double zOff = -0.15 * up.getOffsetZ();
return VoxelShapes.cuboid(
new Box(xOff + 0.15, yOff + 0.15, zOff + 0.15, xOff + 0.85, yOff + 0.85, zOff + 0.85));
}
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.grindstone;
import javax.annotation.Nullable;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.GrinderContainer;
import appeng.tile.grindstone.GrinderBlockEntity;
public class GrinderBlock extends AEBaseTileBlock<GrinderBlockEntity> {
public GrinderBlock(Settings props) {
super(props);
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
final GrinderBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null && !p.isInSneakingPose()) {
if (p instanceof ServerPlayerEntity) {
ContainerOpener.openContainer(GrinderContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,60 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import javax.annotation.Nullable;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.implementations.CellWorkbenchContainer;
import appeng.tile.misc.CellWorkbenchBlockEntity;
import appeng.util.Platform;
public class CellWorkbenchBlock extends AEBaseTileBlock<CellWorkbenchBlockEntity> {
public CellWorkbenchBlock() {
super(defaultProps(Material.METAL));
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final CellWorkbenchBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (Platform.isServer()) {
CellWorkbenchContainer.open(p, ContainerLocator.forTileEntity(tg));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,190 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nullable;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.model.json.Transformation;
import net.minecraft.client.util.math.AffineTransformation;
import net.minecraft.util.math.Box;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import appeng.api.AEApi;
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.AppEng;
import appeng.tile.misc.ChargerBlockEntity;
import appeng.util.Platform;
public class ChargerBlock extends AEBaseTileBlock<ChargerBlockEntity> {
public ChargerBlock() {
super(defaultProps(Material.METAL));
}
@Override
public int getOpacity(BlockState state, BlockView worldIn, BlockPos pos) {
return 2; // FIXME Double check this (esp. value range)
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (player.isInSneakingPose()) {
return ActionResult.PASS;
}
if (Platform.isServer()) {
final ChargerBlockEntity tc = this.getBlockEntity(w, pos);
if (tc != null) {
tc.activate(player);
}
}
return ActionResult.SUCCESS;
}
@Override
@Environment(EnvType.CLIENT)
public void randomDisplayTick(final BlockState state, final World w, final BlockPos pos, final Random r) {
if (!AEConfig.instance().isEnableEffects()) {
return;
}
if (r.nextFloat() < 0.98) {
return;
}
final ChargerBlockEntity tile = this.getBlockEntity(w, pos);
if (tile != null) {
if (AEApi.instance().definitions().materials().certusQuartzCrystalCharged()
.isSameAs(tile.getInternalInventory().getInvStack(0))) {
final double xOff = 0.0;
final double yOff = 0.0;
final double zOff = 0.0;
for (int bolts = 0; bolts < 3; bolts++) {
if (AppEng.instance().shouldAddParticles(r)) {
MinecraftClient.getInstance().particleManager.addParticle(ParticleTypes.LIGHTNING, xOff + 0.5 + pos.getX(),
yOff + 0.5 + pos.getY(), zOff + 0.5 + pos.getZ(), 0.0, 0.0, 0.0);
}
}
}
}
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView w, BlockPos pos, ShapeContext context) {
final ChargerBlockEntity tile = this.getBlockEntity(w, pos);
if (tile != null) {
final double twoPixels = 2.0 / 16.0;
final Direction up = tile.getUp();
final Direction forward = tile.getForward();
final AEAxisAlignedBB bb = new AEAxisAlignedBB(twoPixels, twoPixels, twoPixels, 1.0 - twoPixels,
1.0 - twoPixels, 1.0 - twoPixels);
if (up.getOffsetX() != 0) {
bb.minX = 0;
bb.maxX = 1;
}
if (up.getOffsetY() != 0) {
bb.minY = 0;
bb.maxY = 1;
}
if (up.getOffsetZ() != 0) {
bb.minZ = 0;
bb.maxZ = 1;
}
switch (forward) {
case DOWN:
bb.maxY = 1;
break;
case UP:
bb.minY = 0;
break;
case NORTH:
bb.maxZ = 1;
break;
case SOUTH:
bb.minZ = 0;
break;
case EAST:
bb.minX = 0;
break;
case WEST:
bb.maxX = 1;
break;
default:
break;
}
return VoxelShapes.cuboid(bb.getBoundingBox());
}
return VoxelShapes.cuboid(new Box(0.0, 0, 0.0, 1.0, 1.0, 1.0));
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView worldIn, BlockPos pos,
ShapeContext context) {
return VoxelShapes.cuboid(new Box(0.0, 0.0, 0.0, 1.0, 1.0, 1.0));
}
@Environment(EnvType.CLIENT)
public static Function<BlockEntityRenderDispatcher, BlockEntityRenderer<ChargerBlockEntity>> createTesr() {
return dispatcher -> new ModularTESR<>(dispatcher, new ItemRenderable<>(ChargerBlock::getRenderedItem));
}
@Environment(EnvType.CLIENT)
private static Pair<ItemStack, Transformation> getRenderedItem(ChargerBlockEntity tile) {
Transformation transform = new Transformation(new Vector3f(), new Vector3f(0.5f, 0.375f, 0.5f), new Vector3f(1f, 1f, 1f));
return new ImmutablePair<>(tile.getInternalInventory().getInvStack(0), transform);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import javax.annotation.Nullable;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.CondenserContainer;
import appeng.tile.misc.CondenserBlockEntity;
import appeng.util.Platform;
public class CondenserBlock extends AEBaseTileBlock<CondenserBlockEntity> {
public CondenserBlock() {
super(defaultProps(Material.METAL));
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (player.isInSneakingPose()) {
return ActionResult.PASS;
}
if (Platform.isServer()) {
final CondenserBlockEntity tc = this.getBlockEntity(w, pos);
if (tc != null && !player.isInSneakingPose()) {
ContainerOpener.openContainer(CondenserContainer.TYPE, player,
ContainerLocator.forTileEntitySide(tc, hit.getSide()));
return ActionResult.SUCCESS;
}
}
return ActionResult.SUCCESS;
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.InscriberContainer;
import appeng.tile.misc.InscriberBlockEntity;
public class InscriberBlock extends AEBaseTileBlock<InscriberBlockEntity> {
public InscriberBlock(Settings props) {
super(props);
}
@Override
public int getOpacity(BlockState state, BlockView worldIn, BlockPos pos) {
return 2; // FIXME validate this. a) possibly not required because of getShape b) value
// range. was 2 in 1.10
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (!p.isInSneakingPose()) {
final InscriberBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (!tg.isClient()) {
ContainerOpener.openContainer(InscriberContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,20 @@
package appeng.block.misc;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import appeng.bootstrap.TileEntityRendering;
import appeng.bootstrap.TileEntityRenderingCustomizer;
import appeng.client.render.tesr.InscriberTESR;
import appeng.tile.misc.InscriberBlockEntity;
public class InscriberRendering implements TileEntityRenderingCustomizer<InscriberBlockEntity> {
@Environment(EnvType.CLIENT)
@Override
public void customize(TileEntityRendering<InscriberBlockEntity> rendering) {
rendering.tileEntityRenderer(InscriberTESR::new);
}
}
@@ -0,0 +1,93 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.util.IOrientable;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.InterfaceContainer;
import appeng.tile.misc.InterfaceBlockEntity;
import appeng.util.Platform;
public class InterfaceBlock extends AEBaseTileBlock<InterfaceBlockEntity> {
private static final BooleanProperty OMNIDIRECTIONAL = BooleanProperty.of("omnidirectional");
public InterfaceBlock() {
super(defaultProps(Material.METAL));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(OMNIDIRECTIONAL);
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, InterfaceBlockEntity te) {
return currentState.with(OMNIDIRECTIONAL, te.isOmniDirectional());
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final InterfaceBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (Platform.isServer()) {
ContainerOpener.openContainer(InterfaceContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
@Override
protected boolean hasCustomRotation() {
return true;
}
@Override
protected void customRotateBlock(final IOrientable rotatable, final Direction axis) {
if (rotatable instanceof InterfaceBlockEntity) {
((InterfaceBlockEntity) rotatable).setSide(axis);
}
}
}
@@ -0,0 +1,141 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import java.util.Random;
import net.fabricmc.api.EnvType;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.block.Material;
import net.minecraft.client.MinecraftClient;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.fabricmc.api.Environment;
import appeng.api.util.IOrientableBlock;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.effects.ParticleTypes;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.tile.misc.QuartzGrowthAcceleratorBlockEntity;
import appeng.util.Platform;
public class QuartzGrowthAcceleratorBlock extends AEBaseTileBlock<QuartzGrowthAcceleratorBlockEntity>
implements IOrientableBlock {
private static final BooleanProperty POWERED = BooleanProperty.of("powered");
public QuartzGrowthAcceleratorBlock() {
super(defaultProps(Material.STONE).sounds(BlockSoundGroup.METAL));
this.setDefaultState(this.getDefaultState().with(POWERED, false));
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, QuartzGrowthAcceleratorBlockEntity te) {
return currentState.with(POWERED, te.isPowered());
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
}
@Environment(EnvType.CLIENT)
@Override
public void randomDisplayTick(final BlockState state, final World w, final BlockPos pos, final Random r) {
if (!AEConfig.instance().isEnableEffects()) {
return;
}
final QuartzGrowthAcceleratorBlockEntity cga = this.getBlockEntity(w, pos);
if (cga != null && cga.isPowered() && AppEng.instance().shouldAddParticles(r)) {
final double d0 = r.nextFloat() - 0.5F;
final double d1 = r.nextFloat() - 0.5F;
final Direction up = cga.getUp();
final Direction forward = cga.getForward();
final Direction west = Platform.crossProduct(forward, up);
double rx = 0.5 + pos.getX();
double ry = 0.5 + pos.getY();
double rz = 0.5 + pos.getZ();
rx += up.getOffsetX() * d0;
ry += up.getOffsetY() * d0;
rz += up.getOffsetZ() * d0;
final int x = pos.getX();
final int y = pos.getY();
final int z = pos.getZ();
double dz = 0;
double dx = 0;
BlockPos pt = null;
switch (r.nextInt(4)) {
case 0:
dx = 0.6;
dz = d1;
pt = new BlockPos(x + west.getOffsetX(), y + west.getOffsetY(), z + west.getOffsetZ());
break;
case 1:
dx = d1;
dz += 0.6;
pt = new BlockPos(x + forward.getOffsetX(), y + forward.getOffsetY(), z + forward.getOffsetZ());
break;
case 2:
dx = d1;
dz = -0.6;
pt = new BlockPos(x - forward.getOffsetX(), y - forward.getOffsetY(), z - forward.getOffsetZ());
break;
case 3:
dx = -0.6;
dz = d1;
pt = new BlockPos(x - west.getOffsetX(), y - west.getOffsetY(), z - west.getOffsetZ());
break;
}
if (!w.getBlockState(pt).isAir()) {
return;
}
rx += dx * west.getOffsetX();
ry += dx * west.getOffsetY();
rz += dx * west.getOffsetZ();
rx += dz * forward.getOffsetX();
ry += dz * forward.getOffsetY();
rz += dz * forward.getOffsetZ();
MinecraftClient.getInstance().particleManager.addParticle(ParticleTypes.LIGHTNING, rx, ry, rz, 0.0D, 0.0D, 0.0D);
}
}
}
@@ -0,0 +1,82 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.SecurityStationContainer;
import appeng.tile.misc.SecurityStationBlockEntity;
public class SecurityStationBlock extends AEBaseTileBlock<SecurityStationBlockEntity> {
private static final BooleanProperty POWERED = BooleanProperty.of("powered");
public SecurityStationBlock() {
super(defaultProps(Material.METAL));
this.setDefaultState(this.getDefaultState().with(POWERED, false));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, SecurityStationBlockEntity te) {
return currentState.with(POWERED, te.isActive());
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final SecurityStationBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (w.isClient()) {
return ActionResult.SUCCESS;
}
ContainerOpener.openContainer(SecurityStationContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,41 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import net.fabricmc.api.EnvType;
import net.minecraft.client.render.RenderLayer;
import net.fabricmc.api.Environment;
import appeng.api.util.AEColor;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.client.render.ColorableTileBlockColor;
import appeng.client.render.StaticItemColor;
public class SecurityStationRendering extends BlockRenderingCustomizer {
@Override
@Environment(EnvType.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
rendering.blockColor(ColorableTileBlockColor.INSTANCE);
itemRendering.color(new StaticItemColor(AEColor.TRANSPARENT));
}
}
@@ -0,0 +1,126 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.misc;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.VibrationChamberContainer;
import appeng.core.AEConfig;
import appeng.tile.misc.VibrationChamberBlockEntity;
import appeng.util.Platform;
public final class VibrationChamberBlock extends AEBaseTileBlock<VibrationChamberBlockEntity> {
// Indicates that the vibration chamber is currently working
private static final BooleanProperty ACTIVE = BooleanProperty.of("active");
public VibrationChamberBlock() {
super(defaultProps(Material.METAL).strength(4.2F));
this.setDefaultState(this.getDefaultState().with(ACTIVE, false));
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, VibrationChamberBlockEntity te) {
return currentState.with(ACTIVE, te.isOn);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(ACTIVE);
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (player.isInSneakingPose()) {
return ActionResult.PASS;
}
if (Platform.isServer()) {
final VibrationChamberBlockEntity tc = this.getBlockEntity(w, pos);
if (tc != null && !player.isInSneakingPose()) {
ContainerOpener.openContainer(VibrationChamberContainer.TYPE, player,
ContainerLocator.forTileEntitySide(tc, hit.getSide()));
return ActionResult.SUCCESS;
}
}
return ActionResult.SUCCESS;
}
@Override
public void randomDisplayTick(final BlockState state, final World w, final BlockPos pos, final Random r) {
if (!AEConfig.instance().isEnableEffects()) {
return;
}
final VibrationChamberBlockEntity tile = this.getBlockEntity(w, pos);
if (tile != null && tile.isOn) {
double f1 = pos.getX() + 0.5F;
double f2 = pos.getY() + 0.5F;
double f3 = pos.getZ() + 0.5F;
final Direction forward = tile.getForward();
final Direction up = tile.getUp();
final int west_x = forward.getOffsetY() * up.getOffsetZ() - forward.getOffsetZ() * up.getOffsetY();
final int west_y = forward.getOffsetZ() * up.getOffsetX() - forward.getOffsetX() * up.getOffsetZ();
final int west_z = forward.getOffsetX() * up.getOffsetY() - forward.getOffsetY() * up.getOffsetX();
f1 += forward.getOffsetX() * 0.6;
f2 += forward.getOffsetY() * 0.6;
f3 += forward.getOffsetZ() * 0.6;
final double ox = r.nextDouble();
final double oy = r.nextDouble() * 0.2f;
f1 += up.getOffsetX() * (-0.3 + oy);
f2 += up.getOffsetY() * (-0.3 + oy);
f3 += up.getOffsetZ() * (-0.3 + oy);
f1 += west_x * (0.3 * ox - 0.15);
f2 += west_y * (0.3 * ox - 0.15);
f3 += west_z * (0.3 * ox - 0.15);
w.addParticle(ParticleTypes.SMOKE, f1, f2, f3, 0.0D, 0.0D, 0.0D);
w.addParticle(ParticleTypes.FLAME, f1, f2, f3, 0.0D, 0.0D, 0.0D);
}
}
}
@@ -0,0 +1,140 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.tile.networking.ControllerBlockEntity;
public class ControllerBlock extends AEBaseTileBlock<ControllerBlockEntity> {
public enum ControllerBlockState implements StringIdentifiable {
offline, online, conflicted;
@Override
public String asString() {
return this.name();
}
}
/**
* Controls the rendering of the controller block (connected texture style).
* inside_a and inside_b are alternating patterns for a controller that is
* enclosed by other controllers, and since they are always offline, they do not
* have the usual sub-states.
*/
public enum ControllerRenderType implements StringIdentifiable {
block, column_x, column_y, column_z, inside_a, inside_b;
@Override
public String asString() {
return this.name();
}
}
public static final EnumProperty<ControllerBlockState> CONTROLLER_STATE = EnumProperty.create("state",
ControllerBlockState.class);
public static final EnumProperty<ControllerRenderType> CONTROLLER_TYPE = EnumProperty.create("type",
ControllerRenderType.class);
public ControllerBlock() {
super(defaultProps(Material.METAL).strength(6));
this.setDefaultState(this.getDefaultState().with(CONTROLLER_STATE, ControllerBlockState.offline)
.with(CONTROLLER_TYPE, ControllerRenderType.block));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(CONTROLLER_STATE);
builder.add(CONTROLLER_TYPE);
}
/**
* This will compute the AE_BLOCK_FORWARD, AE_BLOCK_UP and CONTROLLER_TYPE block
* states based on adjacent controllers and the network state of this controller
* (offline, online, conflicted). This is used to get a rudimentary connected
* texture feel for the controller based on how it is placed.
*/
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState facingState, WorldAccess world,
BlockPos pos, BlockPos facingPos) {
// FIXME: this might work, or might _NOT_ work, but needs to be investigated
// Only used for columns, really
ControllerRenderType type = ControllerRenderType.block;
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
// Detect whether controllers are on both sides of the x, y, and z axes
final boolean xx = this.getBlockEntity(world, x - 1, y, z) != null
&& this.getBlockEntity(world, x + 1, y, z) != null;
final boolean yy = this.getBlockEntity(world, x, y - 1, z) != null
&& this.getBlockEntity(world, x, y + 1, z) != null;
final boolean zz = this.getBlockEntity(world, x, y, z - 1) != null
&& this.getBlockEntity(world, x, y, z + 1) != null;
if (xx && !yy && !zz) {
type = ControllerRenderType.column_x;
} else if (!xx && yy && !zz) {
type = ControllerRenderType.column_y;
} else if (!xx && !yy && zz) {
type = ControllerRenderType.column_z;
} else if ((xx ? 1 : 0) + (yy ? 1 : 0) + (zz ? 1 : 0) >= 2) {
final int v = (Math.abs(x) + Math.abs(y) + Math.abs(z)) % 2;
// While i'd like this to be based on the blockstate randomization feature, this
// generates
// an alternating pattern based on world position, so this is not 100% doable
// with blockstates.
if (v == 0) {
type = ControllerRenderType.inside_a;
} else {
type = ControllerRenderType.inside_b;
}
}
return state.with(CONTROLLER_TYPE, type);
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final ControllerBlockEntity tc = this.getBlockEntity(world, pos);
if (tc != null) {
tc.onNeighborChange(false);
}
}
}
@@ -0,0 +1,34 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
import net.minecraft.client.render.RenderLayer;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
public class ControllerRendering extends BlockRenderingCustomizer {
@Override
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
// Disables the default model rotator
rendering.modelCustomizer((loc, model) -> model);
rendering.renderType(RenderLayer.getCutout());
}
}
@@ -0,0 +1,30 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
import appeng.block.AEBaseTileBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.tile.networking.CreativeEnergyCellBlockEntity;
public class CreativeEnergyCellBlock extends AEBaseTileBlock<CreativeEnergyCellBlockEntity> {
public CreativeEnergyCellBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
}
}
@@ -0,0 +1,31 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
public class DenseEnergyCellBlock extends EnergyCellBlock {
public DenseEnergyCellBlock() {
}
@Override
public double getMaxPower() {
return 200000.0 * 8.0;
}
}
@@ -0,0 +1,31 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
import net.minecraft.block.Material;
import appeng.block.AEBaseTileBlock;
import appeng.tile.networking.EnergyAcceptorBlockEntity;
public class EnergyAcceptorBlock extends AEBaseTileBlock<EnergyAcceptorBlockEntity> {
public EnergyAcceptorBlock() {
super(defaultProps(Material.METAL));
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.collection.DefaultedList;
import appeng.block.AEBaseTileBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.tile.networking.EnergyCellBlockEntity;
public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellBlockEntity> {
public static final IntegerProperty ENERGY_STORAGE = IntegerProperty.create("fullness", 0, 7);
public EnergyCellBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
}
@Override
@Environment(EnvType.CLIENT)
public void appendStacks(ItemGroup group, DefaultedList<ItemStack> itemStacks) {
super.appendStacks(group, itemStacks);
final ItemStack charged = new ItemStack(this, 1);
final CompoundTag tag = charged.getOrCreateTag();
tag.putDouble("internalCurrentPower", this.getMaxPower());
tag.putDouble("internalMaxPower", this.getMaxPower());
itemStacks.add(charged);
}
public double getMaxPower() {
return 200000.0;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(ENERGY_STORAGE);
}
}
@@ -0,0 +1,228 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.networking;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.WirelessContainer;
import appeng.helpers.AEGlassMaterial;
import appeng.tile.networking.WirelessBlockEntity;
import appeng.util.Platform;
public class WirelessBlock extends AEBaseTileBlock<WirelessBlockEntity> {
enum State implements StringIdentifiable {
OFF, ON, HAS_CHANNEL;
@Override
public String asString() {
return this.name().toLowerCase();
}
}
public static final EnumProperty<State> STATE = EnumProperty.create("state", State.class);
public WirelessBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE)
.nonOpaque()
.solidBlock((state, world, pos) -> false)
);
this.setDefaultState(this.getDefaultState().with(STATE, State.OFF));
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, WirelessBlockEntity te) {
State teState = State.OFF;
if (te.isActive()) {
teState = State.HAS_CHANNEL;
} else if (te.isPowered()) {
teState = State.ON;
}
return currentState.with(STATE, teState);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(STATE);
}
@Override
public ActionResult onUse(BlockState state, World w, BlockPos pos, PlayerEntity player, Hand hand,
BlockHitResult hit) {
final WirelessBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null && !player.isInSneakingPose()) {
if (Platform.isServer()) {
ContainerOpener.openContainer(WirelessContainer.TYPE, player,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return super.onUse(state, w, pos, player, hand, hit);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView w, BlockPos pos, ShapeContext context) {
final WirelessBlockEntity tile = this.getBlockEntity(w, pos);
if (tile != null) {
final Direction forward = tile.getForward();
double minX = 0;
double minY = 0;
double minZ = 0;
double maxX = 1;
double maxY = 1;
double maxZ = 1;
switch (forward) {
case DOWN:
minZ = minX = 3.0 / 16.0;
maxZ = maxX = 13.0 / 16.0;
maxY = 1.0;
minY = 5.0 / 16.0;
break;
case EAST:
minZ = minY = 3.0 / 16.0;
maxZ = maxY = 13.0 / 16.0;
maxX = 11.0 / 16.0;
minX = 0.0;
break;
case NORTH:
minY = minX = 3.0 / 16.0;
maxY = maxX = 13.0 / 16.0;
maxZ = 1.0;
minZ = 5.0 / 16.0;
break;
case SOUTH:
minY = minX = 3.0 / 16.0;
maxY = maxX = 13.0 / 16.0;
maxZ = 11.0 / 16.0;
minZ = 0.0;
break;
case UP:
minZ = minX = 3.0 / 16.0;
maxZ = maxX = 13.0 / 16.0;
maxY = 11.0 / 16.0;
minY = 0.0;
break;
case WEST:
minZ = minY = 3.0 / 16.0;
maxZ = maxY = 13.0 / 16.0;
maxX = 1.0;
minX = 5.0 / 16.0;
break;
default:
break;
}
return VoxelShapes.cuboid(new Box(minX, minY, minZ, maxX, maxY, maxZ));
}
return VoxelShapes.empty();
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView w, BlockPos pos, ShapeContext context) {
final WirelessBlockEntity tile = this.getBlockEntity(w, pos);
if (tile != null) {
final Direction forward = tile.getForward();
double minX = 0;
double minY = 0;
double minZ = 0;
double maxX = 1;
double maxY = 1;
double maxZ = 1;
switch (forward) {
case DOWN:
minZ = minX = 3.0 / 16.0;
maxZ = maxX = 13.0 / 16.0;
maxY = 1.0;
minY = 5.0 / 16.0;
break;
case EAST:
minZ = minY = 3.0 / 16.0;
maxZ = maxY = 13.0 / 16.0;
maxX = 11.0 / 16.0;
minX = 0.0;
break;
case NORTH:
minY = minX = 3.0 / 16.0;
maxY = maxX = 13.0 / 16.0;
maxZ = 1.0;
minZ = 5.0 / 16.0;
break;
case SOUTH:
minY = minX = 3.0 / 16.0;
maxY = maxX = 13.0 / 16.0;
maxZ = 11.0 / 16.0;
minZ = 0.0;
break;
case UP:
minZ = minX = 3.0 / 16.0;
maxZ = maxX = 13.0 / 16.0;
maxY = 11.0 / 16.0;
minY = 0.0;
break;
case WEST:
minZ = minY = 3.0 / 16.0;
maxZ = maxY = 13.0 / 16.0;
maxX = 1.0;
minX = 5.0 / 16.0;
break;
default:
break;
}
return VoxelShapes.cuboid(new Box(minX, minY, minZ, maxX, maxY, maxZ));
} else {
return VoxelShapes.empty();
}
}
@Override
public boolean isTranslucent(BlockState state, BlockView reader, BlockPos pos) {
return true;
}
}
@@ -0,0 +1,21 @@
package appeng.block.networking;
import net.minecraft.client.render.RenderLayer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import appeng.api.util.AEColor;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.client.render.StaticBlockColor;
public class WirelessRendering extends BlockRenderingCustomizer {
@Override
@Environment(EnvType.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
rendering.blockColor(new StaticBlockColor(AEColor.TRANSPARENT));
}
}
@@ -0,0 +1,27 @@
package appeng.block.paint;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.ImmutableList;
import appeng.helpers.Splotch;
/**
* Used to transfer the state about paint splotches from the game thread to the
* render thread.
*/
public class PaintSplotches {
private final List<Splotch> splotches;
public PaintSplotches(Collection<Splotch> splotches) {
this.splotches = ImmutableList.copyOf(splotches);
}
List<Splotch> getSplotches() {
return this.splotches;
}
}
@@ -0,0 +1,177 @@
package appeng.block.paint;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import net.minecraftforge.client.model.data.IDynamicBakedModel;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.core.AppEng;
import appeng.helpers.Splotch;
import appeng.tile.misc.PaintSplotchesBlockEntity;
/**
* Renders paint blocks, which render multiple "splotches" that have been
* applied to the sides of adjacent blocks using a matter cannon with paint
* balls.
*/
class PaintSplotchesBakedModel implements IDynamicBakedModel {
private static final SpriteIdentifier TEXTURE_PAINT1 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/paint1"));
private static final SpriteIdentifier TEXTURE_PAINT2 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/paint2"));
private static final SpriteIdentifier TEXTURE_PAINT3 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/paint3"));
private final Sprite[] textures;
PaintSplotchesBakedModel(Function<SpriteIdentifier, Sprite> bakedTextureGetter) {
this.textures = new Sprite[] { bakedTextureGetter.apply(TEXTURE_PAINT1),
bakedTextureGetter.apply(TEXTURE_PAINT2), bakedTextureGetter.apply(TEXTURE_PAINT3) };
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@Nonnull IModelData extraData) {
if (side != null) {
return Collections.emptyList();
}
PaintSplotches splotchesState = extraData.getData(PaintSplotchesBlockEntity.SPLOTCHES);
if (splotchesState == null) {
// This is the inventory model which should usually not be used other than in
// special cases
List<BakedQuad> quads = new ArrayList<>(1);
CubeBuilder builder = new CubeBuilder(quads);
builder.setTexture(this.textures[0]);
builder.addCube(0, 0, 0, 16, 16, 16);
return quads;
}
List<Splotch> splotches = splotchesState.getSplotches();
CubeBuilder builder = new CubeBuilder();
float offsetConstant = 0.001f;
for (final Splotch s : splotches) {
if (s.isLumen()) {
builder.setColorRGB(s.getColor().whiteVariant);
builder.setRenderFullBright(true);
} else {
builder.setColorRGB(s.getColor().mediumVariant);
builder.setRenderFullBright(false);
}
float offset = offsetConstant;
offsetConstant += 0.001f;
final float buffer = 0.1f;
float pos_x = s.x();
float pos_y = s.y();
pos_x = Math.max(buffer, Math.min(1.0f - buffer, pos_x));
pos_y = Math.max(buffer, Math.min(1.0f - buffer, pos_y));
Sprite ico = this.textures[s.getSeed() % this.textures.length];
builder.setTexture(ico);
builder.setCustomUv(s.getSide().getOpposite(), 0, 0, 16, 16);
switch (s.getSide()) {
case UP:
offset = 1.0f - offset;
builder.addQuad(Direction.DOWN, pos_x - buffer, offset, pos_y - buffer, pos_x + buffer, offset,
pos_y + buffer);
break;
case DOWN:
builder.addQuad(Direction.UP, pos_x - buffer, offset, pos_y - buffer, pos_x + buffer, offset,
pos_y + buffer);
break;
case EAST:
offset = 1.0f - offset;
builder.addQuad(Direction.WEST, offset, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer,
pos_y + buffer);
break;
case WEST:
builder.addQuad(Direction.EAST, offset, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer,
pos_y + buffer);
break;
case SOUTH:
offset = 1.0f - offset;
builder.addQuad(Direction.NORTH, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer,
pos_y + buffer, offset);
break;
case NORTH:
builder.addQuad(Direction.SOUTH, pos_x - buffer, pos_y - buffer, offset, pos_x + buffer,
pos_y + buffer, offset);
break;
default:
}
}
return builder.getOutput();
}
@Override
public boolean useAmbientOcclusion() {
return false;
}
@Override
public boolean hasDepth() {
return true;
}
@Override
public boolean isBuiltin() {
return false;
}
@Override
public Sprite getSprite() {
return this.textures[0];
}
@Override
public ModelOverrideList getOverrides() {
return ModelOverrideList.EMPTY;
}
@Override
public boolean isSideLit() {
return false;
}
static List<SpriteIdentifier> getRequiredTextures() {
return ImmutableList.of(TEXTURE_PAINT1, TEXTURE_PAINT2, TEXTURE_PAINT3);
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.paint;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import appeng.block.AEBaseTileBlock;
import appeng.tile.misc.PaintSplotchesBlockEntity;
import appeng.util.Platform;
public class PaintSplotchesBlock extends AEBaseTileBlock<PaintSplotchesBlockEntity> {
public PaintSplotchesBlock() {
super(defaultProps(Material.WATER, MaterialColor.CLEAR));
this.setFullSize(false);
this.setOpaque(false);
}
@Override
@Environment(EnvType.CLIENT)
public void appendStacks(ItemGroup group, DefaultedList<ItemStack> itemStacks) {
// do nothing
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView worldIn, BlockPos pos, ShapeContext context) {
return VoxelShapes.empty();
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final PaintSplotchesBlockEntity tp = this.getBlockEntity(world, pos);
if (tp != null) {
tp.neighborUpdate();
}
}
@Override
public void fillWithRain(final World w, final BlockPos pos) {
if (Platform.isServer()) {
w.removeBlock(pos, false);
}
}
@Override
public int getLightValue(final BlockState state, final BlockView w, final BlockPos pos) {
final PaintSplotchesBlockEntity tp = this.getBlockEntity(w, pos);
if (tp != null) {
return tp.getLightLevel();
}
return 0;
}
@Override
public boolean isAir(final BlockState state, final BlockView world, final BlockPos pos) {
return true;
}
@Override
public boolean isReplaceable(BlockState state, ItemPlacementContext useContext) {
return true;
}
@Override
public boolean isReplaceable(BlockState p_225541_1_, Fluid p_225541_2_) {
return true;
}
}
@@ -0,0 +1,36 @@
package appeng.block.paint;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.IModelTransform;
import net.minecraft.client.render.model.IUnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
public class PaintSplotchesModel implements IModelGeometry<PaintSplotchesModel> {
@Override
public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
Function<SpriteIdentifier, Sprite> spriteGetter, IModelTransform modelTransform,
ModelOverrideList overrides, Identifier modelLocation) {
return new PaintSplotchesBakedModel(spriteGetter);
}
@Override
public Collection<SpriteIdentifier> getTextures(IModelConfiguration owner,
Function<Identifier, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
return PaintSplotchesBakedModel.getRequiredTextures();
}
}
@@ -0,0 +1,21 @@
package appeng.block.paint;
import net.minecraft.client.render.RenderLayer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
public class PaintSplotchesRendering extends BlockRenderingCustomizer {
@Override
@Environment(EnvType.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
// Disable auto rotation
rendering.modelCustomizer((location, model) -> model);
}
}
@@ -0,0 +1,227 @@
package appeng.block.qnb;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import net.minecraftforge.client.model.data.IDynamicBakedModel;
import appeng.api.AEApi;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.core.AppEng;
import appeng.tile.qnb.QuantumBridgeBlockEntity;
class QnbFormedBakedModel implements IDynamicBakedModel {
private static final SpriteIdentifier TEXTURE_LINK = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/quantum_link"));
private static final SpriteIdentifier TEXTURE_RING = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/quantum_ring"));
private static final SpriteIdentifier TEXTURE_RING_LIGHT = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/quantum_ring_light"));
private static final SpriteIdentifier TEXTURE_RING_LIGHT_CORNER = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/quantum_ring_light_corner"));
private static final SpriteIdentifier TEXTURE_CABLE_GLASS = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "parts/cable/glass/transparent"));
private static final SpriteIdentifier TEXTURE_COVERED_CABLE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "parts/cable/covered/transparent"));
private static final float DEFAULT_RENDER_MIN = 2.0f;
private static final float DEFAULT_RENDER_MAX = 14.0f;
private static final float CORNER_POWERED_RENDER_MIN = 3.9f;
private static final float CORNER_POWERED_RENDER_MAX = 12.1f;
private static final float CENTER_POWERED_RENDER_MIN = -0.01f;
private static final float CENTER_POWERED_RENDER_MAX = 16.01f;
private final BakedModel baseModel;
private final Block linkBlock;
private final Sprite linkTexture;
private final Sprite ringTexture;
private final Sprite glassCableTexture;
private final Sprite coveredCableTexture;
private final Sprite lightTexture;
private final Sprite lightCornerTexture;
public QnbFormedBakedModel(BakedModel baseModel, Function<SpriteIdentifier, Sprite> bakedTextureGetter) {
this.baseModel = baseModel;
this.linkTexture = bakedTextureGetter.apply(TEXTURE_LINK);
this.ringTexture = bakedTextureGetter.apply(TEXTURE_RING);
this.glassCableTexture = bakedTextureGetter.apply(TEXTURE_CABLE_GLASS);
this.coveredCableTexture = bakedTextureGetter.apply(TEXTURE_COVERED_CABLE);
this.lightTexture = bakedTextureGetter.apply(TEXTURE_RING_LIGHT);
this.lightCornerTexture = bakedTextureGetter.apply(TEXTURE_RING_LIGHT_CORNER);
this.linkBlock = AEApi.instance().definitions().blocks().quantumLink().maybeBlock().orElse(null);
}
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand,
IModelData modelData) {
QnbFormedState formedState = modelData.getData(QuantumBridgeBlockEntity.FORMED_STATE);
if (formedState == null) {
return this.baseModel.getQuads(state, side, rand);
}
if (side != null) {
return Collections.emptyList();
}
return this.getQuads(formedState, state);
}
private List<BakedQuad> getQuads(QnbFormedState formedState, BlockState state) {
CubeBuilder builder = new CubeBuilder();
if (state.getBlock() == this.linkBlock) {
Set<Direction> sides = formedState.getAdjacentQuantumBridges();
this.renderCableAt(builder, 0.11f * 16, this.glassCableTexture, 0.141f * 16, sides);
this.renderCableAt(builder, 0.188f * 16, this.coveredCableTexture, 0.1875f * 16, sides);
builder.setTexture(this.linkTexture);
builder.addCube(DEFAULT_RENDER_MIN, DEFAULT_RENDER_MIN, DEFAULT_RENDER_MIN, DEFAULT_RENDER_MAX,
DEFAULT_RENDER_MAX, DEFAULT_RENDER_MAX);
} else {
if (formedState.isCorner()) {
this.renderCableAt(builder, 0.188f * 16, this.coveredCableTexture, 0.05f * 16,
formedState.getAdjacentQuantumBridges());
builder.setTexture(this.ringTexture);
builder.addCube(DEFAULT_RENDER_MIN, DEFAULT_RENDER_MIN, DEFAULT_RENDER_MIN, DEFAULT_RENDER_MAX,
DEFAULT_RENDER_MAX, DEFAULT_RENDER_MAX);
if (formedState.isPowered()) {
builder.setTexture(this.lightCornerTexture);
builder.setRenderFullBright(true);
for (Direction facing : Direction.values()) {
// Offset the face by a slight amount so that it is drawn over the already drawn
// ring texture
// (avoids z-fighting)
float xOffset = Math.abs(facing.getOffsetX() * 0.01f);
float yOffset = Math.abs(facing.getOffsetY() * 0.01f);
float zOffset = Math.abs(facing.getOffsetZ() * 0.01f);
builder.setDrawFaces(EnumSet.of(facing));
builder.addCube(DEFAULT_RENDER_MIN - xOffset, DEFAULT_RENDER_MIN - yOffset,
DEFAULT_RENDER_MIN - zOffset, DEFAULT_RENDER_MAX + xOffset,
DEFAULT_RENDER_MAX + yOffset, DEFAULT_RENDER_MAX + zOffset);
}
}
} else {
builder.setTexture(this.ringTexture);
builder.addCube(0, DEFAULT_RENDER_MIN, DEFAULT_RENDER_MIN, 16, DEFAULT_RENDER_MAX, DEFAULT_RENDER_MAX);
builder.addCube(DEFAULT_RENDER_MIN, 0, DEFAULT_RENDER_MIN, DEFAULT_RENDER_MAX, 16, DEFAULT_RENDER_MAX);
builder.addCube(DEFAULT_RENDER_MIN, DEFAULT_RENDER_MIN, 0, DEFAULT_RENDER_MAX, DEFAULT_RENDER_MAX, 16);
if (formedState.isPowered()) {
builder.setTexture(this.lightTexture);
builder.setRenderFullBright(true);
for (Direction facing : Direction.values()) {
// Offset the face by a slight amount so that it is drawn over the already drawn
// ring texture
// (avoids z-fighting)
float xOffset = Math.abs(facing.getOffsetX() * 0.01f);
float yOffset = Math.abs(facing.getOffsetY() * 0.01f);
float zOffset = Math.abs(facing.getOffsetZ() * 0.01f);
builder.setDrawFaces(EnumSet.of(facing));
builder.addCube(-xOffset, -yOffset, -zOffset, 16 + xOffset, 16 + yOffset, 16 + zOffset);
}
}
}
}
return builder.getOutput();
}
private void renderCableAt(CubeBuilder builder, float thickness, Sprite texture, float pull,
Set<Direction> connections) {
builder.setTexture(texture);
if (connections.contains(Direction.WEST)) {
builder.addCube(0, 8 - thickness, 8 - thickness, 8 - thickness - pull, 8 + thickness, 8 + thickness);
}
if (connections.contains(Direction.EAST)) {
builder.addCube(8 + thickness + pull, 8 - thickness, 8 - thickness, 16, 8 + thickness, 8 + thickness);
}
if (connections.contains(Direction.NORTH)) {
builder.addCube(8 - thickness, 8 - thickness, 0, 8 + thickness, 8 + thickness, 8 - thickness - pull);
}
if (connections.contains(Direction.SOUTH)) {
builder.addCube(8 - thickness, 8 - thickness, 8 + thickness + pull, 8 + thickness, 8 + thickness, 16);
}
if (connections.contains(Direction.DOWN)) {
builder.addCube(8 - thickness, 0, 8 - thickness, 8 + thickness, 8 - thickness - pull, 8 + thickness);
}
if (connections.contains(Direction.UP)) {
builder.addCube(8 - thickness, 8 + thickness + pull, 8 - thickness, 8 + thickness, 16, 8 + thickness);
}
}
@Override
public boolean useAmbientOcclusion() {
return this.baseModel.useAmbientOcclusion();
}
@Override
public boolean hasDepth() {
return true;
}
@Override
public boolean isSideLit() {
return false;
}
@Override
public boolean isBuiltin() {
return false;
}
@Override
public Sprite getSprite() {
return this.baseModel.getSprite();
}
@Override
public ModelOverrideList getOverrides() {
return this.baseModel.getOverrides();
}
public static List<SpriteIdentifier> getRequiredTextures() {
return ImmutableList.of(TEXTURE_LINK, TEXTURE_RING, TEXTURE_CABLE_GLASS, TEXTURE_COVERED_CABLE,
TEXTURE_RING_LIGHT, TEXTURE_RING_LIGHT_CORNER);
}
}
@@ -0,0 +1,41 @@
package appeng.block.qnb;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.IModelTransform;
import net.minecraft.client.render.model.IUnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import appeng.core.AppEng;
public class QnbFormedModel implements IModelGeometry<QnbFormedModel> {
private static final Identifier MODEL_RING = new Identifier(AppEng.MOD_ID, "block/qnb/ring");
@Override
public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
Function<SpriteIdentifier, Sprite> spriteGetter, IModelTransform modelTransform,
ModelOverrideList overrides, Identifier modelLocation) {
BakedModel ringModel = bakery.getBakedModel(MODEL_RING, modelTransform, spriteGetter);
return new QnbFormedBakedModel(ringModel, spriteGetter);
}
@Override
public Collection<SpriteIdentifier> getTextures(IModelConfiguration owner,
Function<Identifier, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
return QnbFormedBakedModel.getRequiredTextures();
}
}
@@ -0,0 +1,34 @@
package appeng.block.qnb;
import java.util.Set;
import net.minecraft.util.math.Direction;
public class QnbFormedState {
private final Set<Direction> adjacentQuantumBridges;
private final boolean corner;
private final boolean powered;
public QnbFormedState(Set<Direction> adjacentQuantumBridges, boolean corner, boolean powered) {
this.adjacentQuantumBridges = adjacentQuantumBridges;
this.corner = corner;
this.powered = powered;
}
public Set<Direction> getAdjacentQuantumBridges() {
return this.adjacentQuantumBridges;
}
public boolean isCorner() {
return this.corner;
}
public boolean isPowered() {
return this.powered;
}
}
@@ -0,0 +1,92 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.qnb;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.tile.qnb.QuantumBridgeBlockEntity;
public abstract class QuantumBaseBlock extends AEBaseTileBlock<QuantumBridgeBlockEntity> {
public static final BooleanProperty FORMED = BooleanProperty.of("formed");
private static final VoxelShape SHAPE;
static {
final float shave = 2.0f / 16.0f;
SHAPE = VoxelShapes.cuboid(new Box(shave, shave, shave, 1.0f - shave, 1.0f - shave, 1.0f - shave));
}
public QuantumBaseBlock(Settings props) {
super(props);
this.setFullSize(this.setOpaque(false));
this.setDefaultState(this.getDefaultState().with(FORMED, false));
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView worldIn, BlockPos pos, ShapeContext context) {
return SHAPE;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FORMED);
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, QuantumBridgeBlockEntity te) {
return currentState.with(FORMED, te.isFormed());
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final QuantumBridgeBlockEntity bridge = this.getBlockEntity(world, pos);
if (bridge != null) {
bridge.neighborUpdate();
}
}
@Override
public void onStateReplaced(BlockState state, World w, BlockPos pos, BlockState newState, boolean isMoving) {
if (newState.getBlock() == state.getBlock()) {
return; // Just a block state change
}
final QuantumBridgeBlockEntity bridge = this.getBlockEntity(w, pos);
if (bridge != null) {
bridge.breakCluster();
}
super.onStateReplaced(state, w, pos, newState, isMoving);
}
}
@@ -0,0 +1,21 @@
package appeng.block.qnb;
import net.minecraft.client.render.RenderLayer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
public class QuantumBridgeRendering extends BlockRenderingCustomizer {
@Override
@Environment(EnvType.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
// Disable auto rotation
rendering.modelCustomizer((location, model) -> model);
}
}
@@ -0,0 +1,97 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.qnb;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import appeng.client.EffectType;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.QNBContainer;
import appeng.core.AppEng;
import appeng.helpers.AEGlassMaterial;
import appeng.tile.qnb.QuantumBridgeBlockEntity;
import appeng.util.Platform;
public class QuantumLinkChamberBlock extends QuantumBaseBlock {
private static final VoxelShape SHAPE;
static {
final double onePixel = 2.0 / 16.0;
SHAPE = VoxelShapes.cuboid(
new Box(onePixel, onePixel, onePixel, 1.0 - onePixel, 1.0 - onePixel, 1.0 - onePixel));
}
public QuantumLinkChamberBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
}
@Override
public void randomDisplayTick(final BlockState state, final World w, final BlockPos pos, final Random rand) {
final QuantumBridgeBlockEntity bridge = this.getBlockEntity(w, pos);
if (bridge != null) {
if (bridge.hasQES()) {
if (AppEng.instance().shouldAddParticles(rand)) {
AppEng.instance().spawnEffect(EffectType.Energy, w, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5,
null);
}
}
}
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final QuantumBridgeBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (Platform.isServer()) {
ContainerOpener.openContainer(QNBContainer.TYPE, p, ContainerLocator.forTileEntity(tg));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView worldIn, BlockPos pos, ShapeContext context) {
return SHAPE;
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.qnb;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import appeng.tile.qnb.QuantumBridgeBlockEntity;
public class QuantumRingBlock extends QuantumBaseBlock {
private static final VoxelShape SHAPE = createShape(2.0 / 16.0);
private static final VoxelShape SHAPE_CORNER = createShape(4.0 / 16.0);
private static final VoxelShape SHAPE_FORMED = createShape(1.0 / 16.0);
public QuantumRingBlock() {
super(defaultProps(Material.METAL));
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView w, BlockPos pos, ShapeContext context) {
final QuantumBridgeBlockEntity bridge = this.getBlockEntity(w, pos);
if (bridge != null && bridge.isCorner()) {
return SHAPE_CORNER;
} else if (bridge != null && bridge.isFormed()) {
return SHAPE_FORMED;
}
return SHAPE;
}
private static VoxelShape createShape(double onePixel) {
return VoxelShapes.cuboid(
new Box(onePixel, onePixel, onePixel, 1.0 - onePixel, 1.0 - onePixel, 1.0 - onePixel));
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.spatial;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.explosion.Explosion;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldView;
import net.minecraft.world.World;
import net.fabricmc.api.EnvType;
import appeng.block.AEBaseBlock;
/**
* This block is used to fill empty space in spatial dimensions and delinates
* the border of a spatial dimensions's usable space.
*/
public class MatrixFrameBlock extends AEBaseBlock {
private static final Material MATERIAL = new Material(MaterialColor.CLEAR, false, true, true, false, false, false,
false, PistonBehavior.PUSH_ONLY);
public MatrixFrameBlock() {
super(Settings.create(MATERIAL).strength(-1.0F, 6000000.0F).notSolid().noDrops());
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.INVISIBLE;
}
@Override
@Environment(EnvType.CLIENT)
public void appendStacks(ItemGroup group, DefaultedList<ItemStack> itemStacks) {
// do nothing
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView worldIn, BlockPos pos,
ShapeContext context) {
return VoxelShapes.fullCube();
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView worldIn, BlockPos pos, ShapeContext context) {
// This also prevents any blocks from being placed on this block!
return VoxelShapes.empty();
}
@Override
public boolean canPlaceAt(BlockState state, WorldView worldIn, BlockPos pos) {
return false;
}
@Override
public void onExplosionDestroy(final World world, final BlockPos pos, final Explosion explosion) {
// Don't explode.
}
@Override
public boolean isTranslucent(BlockState state, BlockView reader, BlockPos pos) {
return true;
}
@Override
public float getAmbientOcclusionLightValue(BlockState state, BlockView worldIn, BlockPos pos) {
return 1.0f;
}
@Override
public boolean canEntityDestroy(final BlockState state, final BlockView world, final BlockPos pos,
final Entity entity) {
return false;
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.spatial;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.SpatialIOPortContainer;
import appeng.tile.spatial.SpatialIOPortBlockEntity;
import appeng.util.Platform;
public class SpatialIOPortBlock extends AEBaseTileBlock<SpatialIOPortBlockEntity> {
public SpatialIOPortBlock() {
super(defaultProps(Material.METAL));
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final SpatialIOPortBlockEntity te = this.getBlockEntity(world, pos);
if (te != null) {
te.updateRedstoneState();
}
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final SpatialIOPortBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (Platform.isServer()) {
ContainerOpener.openContainer(SpatialIOPortContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,55 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.spatial;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.helpers.AEGlassMaterial;
import appeng.tile.spatial.SpatialPylonBlockEntity;
public class SpatialPylonBlock extends AEBaseTileBlock<SpatialPylonBlockEntity> {
public SpatialPylonBlock() {
super(defaultProps(AEGlassMaterial.INSTANCE));
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final SpatialPylonBlockEntity tsp = this.getBlockEntity(world, pos);
if (tsp != null) {
tsp.neighborUpdate();
}
}
@Override
public int getLightValue(final BlockState state, final BlockView w, final BlockPos pos) {
final SpatialPylonBlockEntity tsp = this.getBlockEntity(w, pos);
if (tsp != null) {
return tsp.getLightValue();
}
return super.getLightValue(state, w, pos);
}
}
@@ -0,0 +1,98 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.ChestContainer;
import appeng.core.localization.PlayerMessages;
import appeng.tile.storage.ChestBlockEntity;
public class ChestBlock extends AEBaseTileBlock<ChestBlockEntity> {
private final static EnumProperty<DriveSlotState> SLOT_STATE = EnumProperty.create("slot_state",
DriveSlotState.class);
public ChestBlock() {
super(defaultProps(Material.METAL));
this.setDefaultState(this.getDefaultState().with(SLOT_STATE, DriveSlotState.EMPTY));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(SLOT_STATE);
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, ChestBlockEntity te) {
DriveSlotState slotState = DriveSlotState.EMPTY;
if (te.getCellCount() >= 1) {
slotState = DriveSlotState.fromCellStatus(te.getCellStatus(0));
}
// Power-state has to be checked separately
if (!te.isPowered() && slotState != DriveSlotState.EMPTY) {
slotState = DriveSlotState.OFFLINE;
}
return currentState.with(SLOT_STATE, slotState);
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
final ChestBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null && !p.isInSneakingPose()) {
if (w.isClient()) {
return ActionResult.SUCCESS;
}
if (hit.getSide() == tg.getUp()) {
if (!tg.openGui(p)) {
p.sendSystemMessage(PlayerMessages.ChestCannotReadStorageCell.get(), Util.NIL_UUID);
}
} else {
ContainerOpener.openContainer(ChestContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.RenderLayer;
import appeng.api.util.AEColor;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.client.render.ColorableTileBlockColor;
import appeng.client.render.StaticItemColor;
public class ChestRendering extends BlockRenderingCustomizer {
@Override
@Environment(EnvType.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
// I checked, the ME chest doesn't keep its color in item form
itemRendering.color(new StaticItemColor(AEColor.TRANSPARENT));
rendering.blockColor(new ColorableTileBlockColor());
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import javax.annotation.Nullable;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.DriveContainer;
import appeng.tile.storage.DriveBlockEntity;
import appeng.util.Platform;
public class DriveBlock extends AEBaseTileBlock<DriveBlockEntity> {
public DriveBlock() {
super(defaultProps(Material.METAL));
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final DriveBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (Platform.isServer()) {
ContainerOpener.openContainer(DriveContainer.TYPE, p, ContainerLocator.forTileEntity(tg));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import net.minecraft.client.render.RenderLayer;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
public class DriveRendering extends BlockRenderingCustomizer {
@Override
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import net.minecraft.util.StringIdentifiable;
/**
* Describes the type of cell present in a slot.
*/
public enum DriveSlotCellType implements StringIdentifiable {
EMPTY("empty"),
ITEM("item"),
FLUID("fluid");
private final String name;
DriveSlotCellType(String name) {
this.name = name;
}
@Override
public String asString() {
return this.name;
}
}
@@ -0,0 +1,72 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import net.minecraft.util.StringIdentifiable;
import appeng.api.storage.cells.CellState;
/**
* Describes the different states a single slot of a BlockDrive can be in in
* terms of rendering.
*/
public enum DriveSlotState implements StringIdentifiable {
// No cell in slot
EMPTY("empty"),
// Cell in slot, but unpowered
OFFLINE("offline"),
// Online and free space
ONLINE("online"),
// Types full, space left
TYPES_FULL("types_full"),
// Completely full
FULL("full");
private final String name;
DriveSlotState(String name) {
this.name = name;
}
@Override
public String asString() {
return this.name;
}
public static DriveSlotState fromCellStatus(CellState cellStatus) {
switch (cellStatus) {
default:
case ABSENT:
return DriveSlotState.EMPTY;
case EMPTY:
case NOT_EMPTY:
return DriveSlotState.ONLINE;
case TYPES_FULL:
return DriveSlotState.TYPES_FULL;
case FULL:
return DriveSlotState.FULL;
}
}
}
@@ -0,0 +1,93 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import com.google.common.base.Preconditions;
import net.minecraft.item.Item;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.storage.cells.CellState;
/**
* Contains the full information about what the state of the slots in a
* BlockDrive is.
*/
public class DriveSlotsState {
private final Item[] cells;
private final DriveSlotState[] states;
public DriveSlotsState(Item[] cells, DriveSlotState[] states) {
Preconditions.checkArgument(cells.length == states.length);
this.cells = cells;
this.states = states;
}
public DriveSlotState getState(int index) {
if (index >= this.states.length) {
return DriveSlotState.EMPTY;
}
return this.states[index];
}
public Item getCell(int index) {
if (index >= this.cells.length) {
return null;
}
return this.cells[index];
}
public int getSlotCount() {
return this.cells.length;
}
/**
* Retrieve an array that describes the state of each slot in this drive or
* chest.
*/
public static DriveSlotsState fromChestOrDrive(IChestOrDrive chestOrDrive) {
DriveSlotState[] states = new DriveSlotState[chestOrDrive.getCellCount()];
Item[] cells = new Item[chestOrDrive.getCellCount()];
for (int i = 0; i < chestOrDrive.getCellCount(); i++) {
cells[i] = chestOrDrive.getCellItem(i);
if (!chestOrDrive.isPowered()) {
if (chestOrDrive.getCellStatus(i) != CellState.EMPTY) {
states[i] = DriveSlotState.OFFLINE;
} else {
states[i] = DriveSlotState.EMPTY;
}
} else {
states[i] = DriveSlotState.fromCellStatus(chestOrDrive.getCellStatus(i));
}
}
return new DriveSlotsState(cells, states);
}
public static DriveSlotsState createEmpty(int slotCount) {
DriveSlotState[] states = new DriveSlotState[slotCount];
Item[] cells = new Item[slotCount];
for (int i = 0; i < slotCount; i++) {
states[i] = DriveSlotState.EMPTY;
}
return new DriveSlotsState(cells, states);
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.block.storage;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.block.AEBaseTileBlock;
import appeng.container.ContainerLocator;
import appeng.container.ContainerOpener;
import appeng.container.implementations.IOPortContainer;
import appeng.tile.storage.IOPortBlockEntity;
import appeng.util.Platform;
public class IOPortBlock extends AEBaseTileBlock<IOPortBlockEntity> {
public IOPortBlock() {
super(defaultProps(Material.METAL));
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
final IOPortBlockEntity te = this.getBlockEntity(world, pos);
if (te != null) {
te.updateRedstoneState();
}
}
@Override
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity p, final Hand hand,
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
if (p.isInSneakingPose()) {
return ActionResult.PASS;
}
final IOPortBlockEntity tg = this.getBlockEntity(w, pos);
if (tg != null) {
if (Platform.isServer()) {
ContainerOpener.openContainer(IOPortContainer.TYPE, p,
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
}
@@ -0,0 +1,83 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.capabilities;
import net.minecraft.nbt.INBT;
import net.minecraft.util.math.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.energy.IEnergyStorage;
import appeng.api.storage.ISpatialDimension;
import appeng.api.storage.IStorageMonitorableAccessor;
/**
* Utility class that holds various capabilities, both by AE2 and other Mods.
*/
public final class Capabilities {
private Capabilities() {
}
public static Capability<IStorageMonitorableAccessor> STORAGE_MONITORABLE_ACCESSOR;
public static Capability<ISpatialDimension> SPATIAL_DIMENSION;
public static Capability<IEnergyStorage> FORGE_ENERGY;
/**
* Register AE2 provided capabilities.
*/
public static void register() {
CapabilityManager.INSTANCE.register(IStorageMonitorableAccessor.class, createNullStorage(),
NullMENetworkAccessor::new);
CapabilityManager.INSTANCE.register(ISpatialDimension.class, createNullStorage(), NullSpatialDimension::new);
}
@CapabilityInject(IStorageMonitorableAccessor.class)
private static void capIStorageMonitorableAccessorRegistered(Capability<IStorageMonitorableAccessor> cap) {
STORAGE_MONITORABLE_ACCESSOR = cap;
}
@CapabilityInject(ISpatialDimension.class)
private static void capISpatialDimensionRegistered(Capability<ISpatialDimension> cap) {
SPATIAL_DIMENSION = cap;
}
@CapabilityInject(IEnergyStorage.class)
private static void capIEnergyStorageRegistered(Capability<IEnergyStorage> cap) {
FORGE_ENERGY = cap;
}
// Create a storage implementation that does not do anything
private static <T> Capability.IStorage<T> createNullStorage() {
return new Capability.IStorage<T>() {
@Override
public INBT writeNBT(Capability<T> capability, T instance, Direction side) {
return null;
}
@Override
public void readNBT(Capability<T> capability, T instance, Direction side, INBT nbt) {
}
};
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.capabilities;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.IStorageMonitorableAccessor;
class NullMENetworkAccessor implements IStorageMonitorableAccessor {
@Override
public IStorageMonitorable getInventory(IActionSource src) {
return null;
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.capabilities;
import java.util.List;
import net.minecraft.util.math.BlockPos;
import net.minecraft.text.Text;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.server.world.ServerWorld;
import appeng.api.storage.ISpatialDimension;
class NullSpatialDimension implements ISpatialDimension {
@Override
public DimensionType createNewCellDimension(BlockPos size) {
return null;
}
@Override
public void deleteCellDimension(DimensionType cellStorageId) {
}
@Override
public BlockPos getCellDimensionOrigin(DimensionType cellStorageId) {
return null;
}
@Override
public BlockPos getCellDimensionSize(DimensionType cellDim) {
return BlockPos.ORIGIN;
}
@Override
public void addCellDimensionTooltip(DimensionType cellDim, List<Text> tooltip) {
}
@Override
public ServerWorld getWorld(DimensionType cellStorageId) {
return null;
}
@Override
public boolean isCellDimension(DimensionType cellDimID) {
return false;
}
}
@@ -0,0 +1,184 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Random;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.util.InputMappings;
import net.minecraft.client.util.InputUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import appeng.api.parts.CableRenderMode;
import appeng.block.AEBaseBlock;
import appeng.client.render.effects.*;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.helpers.IMouseWheelItem;
import appeng.server.ServerHelper;
import appeng.util.Platform;
public class ClientHelper extends ServerHelper {
private final static String KEY_CATEGORY = "key.appliedenergistics2.category";
private final EnumMap<ActionKey, KeyBinding> bindings = new EnumMap<>(ActionKey.class);
public void clientInit() {
MinecraftForge.EVENT_BUS.addListener(this::postPlayerRender);
MinecraftForge.EVENT_BUS.addListener(this::wheelEvent);
for (ActionKey key : ActionKey.values()) {
final KeyBinding binding = new KeyBinding(key.getTranslationKey(), key.getDefaultKey(), KEY_CATEGORY);
ClientRegistry.registerKeyBinding(binding);
this.bindings.put(key, binding);
}
}
@Override
public void bindTileEntitySpecialRenderer(final Class<? extends BlockEntity> tile, final AEBaseBlock blk) {
}
@Override
public List<? extends PlayerEntity> getPlayers() {
if (Platform.isClient()) {
return Collections.singletonList(MinecraftClient.getInstance().player);
} else {
return super.getPlayers();
}
}
// FIXME: Instead of doing a custom packet and this dispatcher, we can use the
// vanilla particle system
@Override
public void spawnEffect(final EffectType effect, final World world, final double posX, final double posY,
final double posZ, final Object o) {
if (AEConfig.instance().isEnableEffects()) {
switch (effect) {
case Vibrant:
this.spawnVibrant(world, posX, posY, posZ);
return;
case Energy:
this.spawnEnergy(world, posX, posY, posZ);
return;
case LightningArc:
this.spawnLightningArc(world, posX, posY, posZ, (Vec3d) o);
return;
default:
}
}
}
@Override
public boolean shouldAddParticles(final Random r) {
switch (MinecraftClient.getInstance().options.particles) {
default:
case ALL:
return true;
case DECREASED:
return r.nextBoolean();
case MINIMAL:
return false;
}
}
@Override
public void postInit() {
}
private void postPlayerRender(final RenderLivingEvent.Pre p) {
// FIXME final PlayerColor player = TickHandler.INSTANCE.getPlayerColors().get( p.getEntity().getEntityId() );
// FIXME if( player != null )
// FIXME {
// FIXME final AEColor col = player.myColor;
// FIXME final float r = 0xff & ( col.mediumVariant >> 16 );
// FIXME final float g = 0xff & ( col.mediumVariant >> 8 );
// FIXME final float b = 0xff & ( col.mediumVariant );
// FIXME // FIXME: This is most certainly not going to work!
// FIXME GlStateManager.color4f( r / 255.0f, g / 255.0f, b / 255.0f, 1.0f );
// FIXME }
}
private void spawnVibrant(final World w, final double x, final double y, final double z) {
if (AppEng.instance().shouldAddParticles(Platform.getRandom())) {
final double d0 = (Platform.getRandomFloat() - 0.5F) * 0.26D;
final double d1 = (Platform.getRandomFloat() - 0.5F) * 0.26D;
final double d2 = (Platform.getRandomFloat() - 0.5F) * 0.26D;
MinecraftClient.getInstance().particleManager.addParticle(ParticleTypes.VIBRANT, x + d0, y + d1, z + d2, 0.0D, 0.0D,
0.0D);
}
}
private void spawnEnergy(final World w, final double posX, final double posY, final double posZ) {
final float x = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
final float y = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
final float z = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
MinecraftClient.getInstance().particleManager.addParticle(EnergyParticleData.FOR_BLOCK, posX + x, posY + y, posZ + z,
-x * 0.1, -y * 0.1, -z * 0.1);
}
private void spawnLightningArc(final World world, final double posX, final double posY, final double posZ,
final Vec3d second) {
final LightningFX fx = new LightningArcFX(world, posX, posY, posZ, second.x, second.y, second.z, 0.0f, 0.0f,
0.0f);
MinecraftClient.getInstance().particleManager.addParticle(fx);
}
private void wheelEvent(final InputEvent.MouseScrollEvent me) {
if (me.getScrollDelta() == 0) {
return;
}
final MinecraftClient mc = MinecraftClient.getInstance();
final PlayerEntity player = mc.player;
if (player.isInSneakingPose()) {
final boolean mainHand = player.getStackInHand(Hand.MAIN_HAND).getItem() instanceof IMouseWheelItem;
final boolean offHand = player.getStackInHand(Hand.OFF_HAND).getItem() instanceof IMouseWheelItem;
if (mainHand || offHand) {
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("Item", me.getScrollDelta() > 0 ? "WheelUp" : "WheelDown"));
me.setCanceled(true);
}
}
}
@Override
public boolean isActionKey(ActionKey key, InputUtil.Key pressedKey) {
return this.bindings.get(key).isActiveAndMatches(pressedKey);
}
}
@@ -0,0 +1,95 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui;
import java.text.NumberFormat;
import java.util.List;
import java.util.Locale;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.me.SlotME;
import appeng.container.AEBaseContainer;
import appeng.core.AEConfig;
import appeng.core.localization.ButtonToolTips;
public abstract class AEBaseMEScreen<T extends AEBaseContainer> extends AEBaseScreen<T> {
public AEBaseMEScreen(T container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
}
@Override
protected void renderTooltip(final ItemStack stack, final int x, final int y) {
final Slot s = this.getSlot(x, y);
if (s instanceof SlotME && !stack.isEmpty()) {
final int bigNumber = AEConfig.instance().isUseLargeFonts() ? 999 : 9999;
IAEItemStack myStack = null;
final List<String> currentToolTip = this.getTooltipFromItem(stack);
try {
final SlotME theSlotField = (SlotME) s;
myStack = theSlotField.getAEStack();
} catch (final Throwable ignore) {
}
if (myStack != null) {
if (myStack.getStackSize() > bigNumber || (myStack.getStackSize() > 1 && stack.isDamaged())) {
final String local = ButtonToolTips.ItemsStored.getLocal();
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US)
.format(myStack.getStackSize());
final String format = String.format(local, formattedAmount);
currentToolTip.add(Formatting.GRAY + format);
}
if (myStack.getCountRequestable() > 0) {
final String local = ButtonToolTips.ItemsRequestable.getLocal();
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US)
.format(myStack.getCountRequestable());
final String format = String.format(local, formattedAmount);
currentToolTip.add(format);
}
this.renderTooltip(currentToolTip, x, y, this.font);
return;
} else if (stack.getCount() > bigNumber) {
final String local = ButtonToolTips.ItemsStored.getLocal();
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US).format(stack.getCount());
final String format = String.format(local, formattedAmount);
currentToolTip.add(Formatting.GRAY + format);
this.renderTooltip(currentToolTip, x, y, this.font);
return;
}
}
super.renderTooltip(stack, x, y);
}
}
@@ -0,0 +1,785 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.Formatting;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.fluid.Fluid;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.text.Text;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.widgets.CustomSlotWidget;
import appeng.client.gui.widgets.ITooltip;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.InternalSlotME;
import appeng.client.me.SlotDisconnected;
import appeng.client.me.SlotME;
import appeng.client.render.StackSizeRenderer;
import appeng.container.AEBaseContainer;
import appeng.container.slot.AppEngCraftingSlot;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.AppEngSlot.CalculatedValidity;
import appeng.container.slot.CraftingTermSlot;
import appeng.container.slot.DisabledSlot;
import appeng.container.slot.FakeSlot;
import appeng.container.slot.IOptionalSlot;
import appeng.container.slot.InaccessibleSlot;
import appeng.container.slot.OutputSlot;
import appeng.container.slot.PatternTermSlot;
import appeng.container.slot.RestrictedInputSlot;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.InventoryActionPacket;
import appeng.core.sync.packets.SwapSlotsPacket;
import appeng.fluids.client.render.FluidStackSizeRenderer;
import appeng.fluids.container.slots.IMEFluidSlot;
import appeng.helpers.InventoryAction;
public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerScreen<T> {
private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y
private final Set<Slot> drag_click = new HashSet<>();
private final StackSizeRenderer stackSizeRenderer = new StackSizeRenderer();
private final FluidStackSizeRenderer fluidStackSizeRenderer = new FluidStackSizeRenderer();
private Scrollbar myScrollBar = null;
private boolean disableShiftClick = false;
private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
private ItemStack dbl_whichItem = ItemStack.EMPTY;
private Slot bl_clicked;
protected final List<CustomSlotWidget> guiSlots = new ArrayList<>();
public AEBaseScreen(T container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
}
@Override
public void init() {
super.init();
final List<Slot> slots = this.getInventorySlots();
slots.removeIf(slot -> slot instanceof SlotME);
for (final InternalSlotME me : this.meSlots) {
slots.add(new SlotME(me));
}
}
private List<Slot> getInventorySlots() {
return this.container.inventorySlots;
}
@Override
public void render(final int mouseX, final int mouseY, final float partialTicks) {
super.renderBackground();
super.render(mouseX, mouseY, partialTicks);
RenderSystem.pushMatrix();
RenderSystem.translatef(this.guiLeft, this.guiTop, 0.0F);
RenderSystem.enableDepthTest();
for (final CustomSlotWidget c : this.guiSlots) {
this.drawGuiSlot(c, mouseX, mouseY, partialTicks);
}
RenderSystem.disableDepthTest();
for (final CustomSlotWidget c : this.guiSlots) {
this.drawTooltip(c, mouseX - this.guiLeft, mouseY - this.guiTop);
}
RenderSystem.popMatrix();
RenderSystem.enableDepthTest();
this.renderHoveredToolTip(mouseX, mouseY);
for (final Object c : this.buttons) {
if (c instanceof ITooltip) {
this.drawTooltip((ITooltip) c, mouseX, mouseY);
}
}
}
protected void drawGuiSlot(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();
slot.drawContent(getMinecraft(), mouseX, mouseY, partialTicks);
if (this.isPointInRegion(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY)
&& slot.canClick(getPlayer())) {
RenderSystem.colorMask(true, true, true, false);
this.fillGradient(left, top, right, bottom, -2130706433, -2130706433);
RenderSystem.colorMask(true, true, true, true);
}
}
}
private void drawTooltip(ITooltip tooltip, int mouseX, int mouseY) {
final int x = tooltip.xPos(); // ((GuiImgButton) c).x;
int y = tooltip.yPos(); // ((GuiImgButton) c).y;
if (x < mouseX && x + tooltip.getWidth() > mouseX && tooltip.isVisible()) {
if (y < mouseY && y + tooltip.getHeight() > mouseY) {
if (y < 15) {
y = 15;
}
final String msg = tooltip.getMessage();
if (msg != null) {
this.drawTooltip(x + 11, y + 4, msg);
}
}
}
}
protected void drawTooltip(int x, int y, String message) {
String[] lines = message.split("\n");
this.drawTooltip(x, y, Arrays.asList(lines));
}
protected void drawTooltip(int x, int y, List<String> lines) {
if (lines.isEmpty()) {
return;
}
// For an explanation of the formatting codes, see
// http://minecraft.gamepedia.com/Formatting_codes
lines = Lists.newArrayList(lines); // Make a copy
// Make the first line white
lines.set(0, Formatting.WHITE + lines.get(0));
// All lines after the first are colored gray
for (int i = 1; i < lines.size(); i++) {
lines.set(i, Formatting.GRAY + lines.get(i));
}
this.renderTooltip(lines, x, y, this.font);
}
@Override
protected final void drawGuiContainerForegroundLayer(final int x, final int y) {
final int ox = this.guiLeft; // (width - xSize) / 2;
final int oy = this.guiTop; // (height - ySize) / 2;
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
if (this.getScrollBar() != null) {
this.getScrollBar().draw(this);
}
this.drawFG(ox, oy, x, y);
}
public abstract void drawFG(int offsetX, int offsetY, int mouseX, int mouseY);
@Override
protected final void drawGuiContainerBackgroundLayer(final float f, final int x, final int y) {
final int ox = this.guiLeft; // (width - xSize) / 2;
final int oy = this.guiTop; // (height - ySize) / 2;
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
this.drawBG(ox, oy, x, y, f);
final List<Slot> slots = this.getInventorySlots();
for (final Slot slot : slots) {
if (slot instanceof IOptionalSlot) {
final IOptionalSlot optionalSlot = (IOptionalSlot) slot;
if (optionalSlot.isRenderDisabled()) {
final AppEngSlot aeSlot = (AppEngSlot) slot;
if (aeSlot.isSlotEnabled()) {
GuiUtils.drawTexturedModalRect(ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1,
optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18, getBlitOffset());
} else {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F);
RenderSystem.enableBlend();
GuiUtils.drawTexturedModalRect(ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1,
optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18, getBlitOffset());
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
}
}
}
}
for (final CustomSlotWidget slot : this.guiSlots) {
slot.drawBackground(ox, oy, getBlitOffset());
}
}
@Override
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
this.drag_click.clear();
if (btn == 1) {
for (final Object o : this.buttons) {
final Widget widget = (Widget) o;
if (widget.isMouseOver(xCoord, yCoord)) {
return super.mouseClicked(xCoord, yCoord, 0);
}
}
}
for (CustomSlotWidget slot : this.guiSlots) {
if (this.isPointInRegion(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord)
&& slot.canClick(getPlayer())) {
slot.slotClicked(getPlayer().inventory.getItemStack(), btn);
}
}
if (this.getScrollBar() != null) {
this.getScrollBar().click(xCoord - this.guiLeft, yCoord - this.guiTop);
}
return super.mouseClicked(xCoord, yCoord, btn);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double dragX, double dragY) {
final Slot slot = this.getSlot((int) mouseX, (int) mouseY);
final ItemStack itemstack = getPlayer().inventory.getItemStack();
if (this.getScrollBar() != null) {
// FIXME: Coordinate system of mouseX/mouseY is unclear
this.getScrollBar().click((int) mouseX - this.guiLeft, (int) mouseY - this.guiTop);
}
if (slot instanceof FakeSlot && !itemstack.isEmpty()) {
this.drag_click.add(slot);
if (this.drag_click.size() > 1) {
for (final Slot dr : this.drag_click) {
final InventoryActionPacket p = new InventoryActionPacket(
mouseButton == 0 ? InventoryAction.PICKUP_OR_SET_DOWN : InventoryAction.PLACE_SINGLE,
dr.slotNumber, 0);
NetworkHandler.instance().sendToServer(p);
}
}
return true;
} else {
return super.mouseDragged(mouseX, mouseY, mouseButton, dragX, dragY);
}
}
// TODO 1.9.4 aftermath - Whole ClickType thing, to be checked.
@Override
protected void handleMouseClick(final Slot slot, final int slotIdx, final int mouseButton,
final ClickType clickType) {
final PlayerEntity player = getPlayer();
if (slot instanceof FakeSlot) {
final InventoryAction action = mouseButton == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE
: InventoryAction.PICKUP_OR_SET_DOWN;
if (this.drag_click.size() > 1) {
return;
}
final InventoryActionPacket p = new InventoryActionPacket(action, slotIdx, 0);
NetworkHandler.instance().sendToServer(p);
return;
}
if (slot instanceof PatternTermSlot) {
if (mouseButton == 6) {
return; // prevent weird double clicks..
}
NetworkHandler.instance().sendToServer(((PatternTermSlot) slot).getRequest(hasShiftDown()));
} else if (slot instanceof CraftingTermSlot) {
if (mouseButton == 6) {
return; // prevent weird double clicks..
}
InventoryAction action;
if (hasShiftDown()) {
action = InventoryAction.CRAFT_SHIFT;
} else {
// Craft stack on right-click, craft single on left-click
action = (mouseButton == 1) ? InventoryAction.CRAFT_STACK : InventoryAction.CRAFT_ITEM;
}
final InventoryActionPacket p = new InventoryActionPacket(action, slotIdx, 0);
NetworkHandler.instance().sendToServer(p);
return;
}
if (InputMappings.isKeyDown(MinecraftClient.getInstance().getMainWindow().getHandle(), GLFW.GLFW_KEY_SPACE)) {
if (this.enableSpaceClicking()) {
IAEItemStack stack = null;
if (slot instanceof SlotME) {
stack = ((SlotME) slot).getAEStack();
}
int slotNum = this.getInventorySlots().size();
if (!(slot instanceof SlotME) && slot != null) {
slotNum = slot.slotNumber;
}
((AEBaseContainer) this.container).setTargetStack(stack);
final InventoryActionPacket p = new InventoryActionPacket(InventoryAction.MOVE_REGION, slotNum, 0);
NetworkHandler.instance().sendToServer(p);
return;
}
}
if (slot instanceof SlotDisconnected) {
InventoryAction action = null;
switch (clickType) {
case PICKUP: // pickup / set-down.
action = (mouseButton == 1) ? InventoryAction.SPLIT_OR_PLACE_SINGLE
: InventoryAction.PICKUP_OR_SET_DOWN;
break;
case QUICK_MOVE:
action = (mouseButton == 1) ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
break;
case CLONE: // creative dupe:
if (player.abilities.isCreativeMode) {
action = InventoryAction.CREATIVE_DUPLICATE;
}
break;
default:
case THROW: // drop item:
}
if (action != null) {
final InventoryActionPacket p = new InventoryActionPacket(action, slot.getSlotIndex(),
((SlotDisconnected) slot).getSlot().getId());
NetworkHandler.instance().sendToServer(p);
}
return;
}
if (slot instanceof SlotME) {
InventoryAction action = null;
IAEItemStack stack = null;
switch (clickType) {
case PICKUP: // pickup / set-down.
action = (mouseButton == 1) ? InventoryAction.SPLIT_OR_PLACE_SINGLE
: InventoryAction.PICKUP_OR_SET_DOWN;
stack = ((SlotME) slot).getAEStack();
if (stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN && stack.getStackSize() == 0
&& player.inventory.getItemStack().isEmpty()) {
action = InventoryAction.AUTO_CRAFT;
}
break;
case QUICK_MOVE:
action = (mouseButton == 1) ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
stack = ((SlotME) slot).getAEStack();
break;
case CLONE: // creative dupe:
stack = ((SlotME) slot).getAEStack();
if (stack != null && stack.isCraftable()) {
action = InventoryAction.AUTO_CRAFT;
} else if (player.abilities.isCreativeMode) {
final IAEItemStack slotItem = ((SlotME) slot).getAEStack();
if (slotItem != null) {
action = InventoryAction.CREATIVE_DUPLICATE;
}
}
break;
default:
case THROW: // drop item:
}
if (action != null) {
this.container.setTargetStack(stack);
final InventoryActionPacket p = new InventoryActionPacket(action, this.getInventorySlots().size(), 0);
NetworkHandler.instance().sendToServer(p);
}
return;
}
if (!this.disableShiftClick && hasShiftDown() && mouseButton == 0) {
this.disableShiftClick = true;
if (this.dbl_whichItem.isEmpty() || this.bl_clicked != slot
|| this.dbl_clickTimer.elapsed(TimeUnit.MILLISECONDS) > 250) {
// some simple double click logic.
this.bl_clicked = slot;
this.dbl_clickTimer = Stopwatch.createStarted();
if (slot != null) {
this.dbl_whichItem = slot.getHasStack() ? slot.getStack().copy() : ItemStack.EMPTY;
} else {
this.dbl_whichItem = ItemStack.EMPTY;
}
} else if (!this.dbl_whichItem.isEmpty()) {
// a replica of the weird broken vanilla feature.
final List<Slot> slots = this.getInventorySlots();
for (final Slot inventorySlot : slots) {
if (inventorySlot != null && inventorySlot.canTakeStack(getPlayer()) && inventorySlot.getHasStack()
&& inventorySlot.isSameInventory(slot)
&& Container.canAddItemToSlot(inventorySlot, this.dbl_whichItem, true)) {
this.handleMouseClick(inventorySlot, inventorySlot.slotNumber, 0, ClickType.QUICK_MOVE);
}
}
this.dbl_whichItem = ItemStack.EMPTY;
}
this.disableShiftClick = false;
}
super.handleMouseClick(slot, slotIdx, mouseButton, clickType);
}
protected boolean func_195363_d(int keyCode, int scanCode) {
return checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode));
}
protected ClientPlayerEntity getPlayer() {
// Our UIs are usually not opened when not in-game, so this should not be a
// problem
return Preconditions.checkNotNull(getMinecraft().player);
}
protected boolean checkHotbarKeys(final InputUtil.Key input) {
final Slot theSlot = this.getSlotUnderMouse();
if (getPlayer().inventory.getItemStack().isEmpty() && theSlot != null) {
for (int j = 0; j < 9; ++j) {
if (getMinecraft().options.keyBindsHotbar[j].isActiveAndMatches(input)) {
final List<Slot> slots = this.getInventorySlots();
for (final Slot s : slots) {
if (s.getSlotIndex() == j && s.inventory == ((AEBaseContainer) this.container).getPlayerInv()) {
if (!s.canTakeStack(((AEBaseContainer) this.container).getPlayerInv().player)) {
return false;
}
}
}
if (theSlot.getSlotStackLimit() == 64) {
this.handleMouseClick(theSlot, theSlot.slotNumber, j, ClickType.SWAP);
return true;
} else {
for (final Slot s : slots) {
if (s.getSlotIndex() == j
&& s.inventory == ((AEBaseContainer) this.container).getPlayerInv()) {
NetworkHandler.instance()
.sendToServer(new SwapSlotsPacket(s.slotNumber, theSlot.slotNumber));
return true;
}
}
}
}
}
}
return false;
}
@Override
public void removed() {
super.removed();
}
protected Slot getSlot(final int mouseX, final int mouseY) {
final List<Slot> slots = this.getInventorySlots();
for (final Slot slot : slots) {
// isPointInRegion
if (this.isPointInRegion(slot.xPos, slot.yPos, 16, 16, mouseX, mouseY)) {
return slot;
}
}
return null;
}
public abstract void drawBG(int offsetX, int offsetY, int mouseX, int mouseY, float partialTicks);
@Override
public boolean mouseScrolled(double x, double y, double wheelDelta) {
if (wheelDelta != 0 && hasShiftDown()) {
this.mouseWheelEvent(x, y, wheelDelta / Math.abs(wheelDelta));
return true;
} else if (wheelDelta != 0 && this.getScrollBar() != null) {
this.getScrollBar().wheel(wheelDelta);
return true;
}
return false;
}
private void mouseWheelEvent(final double x, final double y, final double wheel) {
final Slot slot = this.getSlot((int) x, (int) y);
if (slot instanceof SlotME) {
final IAEItemStack item = ((SlotME) slot).getAEStack();
if (item != null) {
((AEBaseContainer) this.container).setTargetStack(item);
final InventoryAction direction = wheel > 0 ? InventoryAction.ROLL_DOWN : InventoryAction.ROLL_UP;
final int times = (int) Math.abs(wheel);
final int inventorySize = this.getInventorySlots().size();
for (int h = 0; h < times; h++) {
final InventoryActionPacket p = new InventoryActionPacket(direction, inventorySize, 0);
NetworkHandler.instance().sendToServer(p);
}
}
}
}
protected boolean enableSpaceClicking() {
return true;
}
public void bindTexture(final String base, final String file) {
final Identifier loc = new Identifier(base, "textures/" + file);
getMinecraft().getTextureManager().bindTexture(loc);
}
protected void drawItem(final int x, final int y, final ItemStack is) {
this.itemRenderer.zLevel = 100.0F;
// FIXME I dont think this is needed anymore...
RenderHelper.enableStandardItemLighting();
this.itemRenderer.renderItemAndEffectIntoGUI(is, x, y);
RenderHelper.disableStandardItemLighting();
this.itemRenderer.zLevel = 0.0F;
}
protected String getGuiDisplayName(final String in) {
return this.hasCustomInventoryName() ? this.getInventoryName() : in;
}
private boolean hasCustomInventoryName() {
return this.container.getCustomName() != null;
}
private String getInventoryName() {
return this.container.getCustomName();
}
/**
* This overrides the base-class method through some access transformer
* hackery...
*/
@Override
public void drawSlot(Slot s) {
if (s instanceof SlotME) {
try {
if (!this.isPowered()) {
fill(s.xPos, s.yPos, 16 + s.xPos, 16 + s.yPos, 0x66111111);
}
// Annoying but easier than trying to splice into render item
super.drawSlot(new Size1Slot((SlotME) s));
this.stackSizeRenderer.renderStackSize(this.font, ((SlotME) s).getAEStack(), s.xPos, s.yPos);
} catch (final Exception err) {
AELog.warn("[AppEng] AE prevented crash while drawing slot: " + err.toString());
}
return;
} else if (s instanceof IMEFluidSlot && ((IMEFluidSlot) s).shouldRenderAsFluid()) {
final IMEFluidSlot slot = (IMEFluidSlot) s;
final IAEFluidStack fs = slot.getAEFluidStack();
if (fs != null && this.isPowered()) {
RenderSystem.disableBlend();
final Fluid fluid = fs.getFluid();
FluidAttributes fluidAttributes = fluid.getAttributes();
bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX);
Identifier fluidStillTexture = fluidAttributes.getStillTexture(fs.getFluidStack());
final Sprite sprite = getMinecraft()
.getAtlasSpriteGetter(SpriteAtlasTexture.BLOCK_ATLAS_TEX).apply(fluidStillTexture);
// Set color for dynamic fluids
// Convert int color to RGB
float red = (fluidAttributes.getColor() >> 16 & 255) / 255.0F;
float green = (fluidAttributes.getColor() >> 8 & 255) / 255.0F;
float blue = (fluidAttributes.getColor() & 255) / 255.0F;
RenderSystem.color3f(red, green, blue);
blit(s.xPos, s.yPos, 0 /* FIXME: Validate this was previous the controls zindex */, 16, 16, sprite);
RenderSystem.enableBlend();
this.fluidStackSizeRenderer.renderStackSize(this.font, fs, s.xPos, s.yPos);
} else if (!this.isPowered()) {
fill(s.xPos, s.yPos, 16 + s.xPos, 16 + s.yPos, 0x66111111);
}
return;
} else {
try {
final ItemStack is = s.getStack();
if (s instanceof AppEngSlot && (((AppEngSlot) s).renderIconWithItem() || is.isEmpty())
&& (((AppEngSlot) s).shouldDisplay())) {
final AppEngSlot aes = (AppEngSlot) s;
if (aes.getIcon() >= 0) {
this.bindTexture("guis/states.png");
try {
final int uv_y = aes.getIcon() / 16;
final int uv_x = aes.getIcon() - uv_y * 16;
RenderSystem.enableBlend();
RenderSystem.enableTexture();
RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
final float par1 = aes.xPos;
final float par2 = aes.yPos;
final float par3 = uv_x * 16;
final float par4 = uv_y * 16;
final Tessellator tessellator = Tessellator.getInstance();
final BufferBuilder vb = tessellator.getBuffer();
vb.begin(GL11.GL_QUADS, VertexFormats.POSITION_TEX_COLOR);
final float f1 = 0.00390625F;
final float f = 0.00390625F;
final float par6 = 16;
vb.pos(par1 + 0, par2 + par6, getBlitOffset()).tex((par3 + 0) * f, (par4 + par6) * f1)
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon()).endVertex();
final float par5 = 16;
vb.pos(par1 + par5, par2 + par6, getBlitOffset()).tex((par3 + par5) * f, (par4 + par6) * f1)
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon()).endVertex();
vb.pos(par1 + par5, par2 + 0, getBlitOffset()).tex((par3 + par5) * f, (par4 + 0) * f1)
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon()).endVertex();
vb.pos(par1 + 0, par2 + 0, getBlitOffset()).tex((par3 + 0) * f, (par4 + 0) * f1)
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon()).endVertex();
tessellator.draw();
} catch (final Exception err) {
err.printStackTrace();
}
}
}
if (!is.isEmpty() && s instanceof AppEngSlot) {
AppEngSlot aeSlot = (AppEngSlot) s;
if (aeSlot.getIsValid() == CalculatedValidity.NotAvailable) {
boolean isValid = s.isItemValid(is) || s instanceof OutputSlot
|| s instanceof AppEngCraftingSlot || s instanceof DisabledSlot
|| s instanceof InaccessibleSlot || s instanceof FakeSlot
|| s instanceof RestrictedInputSlot || s instanceof SlotDisconnected;
if (isValid && s instanceof RestrictedInputSlot) {
try {
isValid = ((RestrictedInputSlot) s).isValid(is, getMinecraft().world);
} catch (final Exception err) {
AELog.debug(err);
}
}
aeSlot.setIsValid(isValid ? CalculatedValidity.Valid : CalculatedValidity.Invalid);
}
if (aeSlot.getIsValid() == CalculatedValidity.Invalid) {
setBlitOffset(100);
this.itemRenderer.zLevel = 100.0F;
fill(s.xPos, s.yPos, 16 + s.xPos, 16 + s.yPos, 0x66ff6666);
setBlitOffset(0);
this.itemRenderer.zLevel = 0.0F;
}
}
if (s instanceof AppEngSlot) {
((AppEngSlot) s).setDisplay(true);
super.drawSlot(s);
} else {
super.drawSlot(s);
}
return;
} catch (final Exception err) {
AELog.warn("[AppEng] AE prevented crash while drawing slot: " + err.toString());
}
}
// do the usual for non-ME Slots.
super.drawSlot(s);
}
protected boolean isPowered() {
return true;
}
public void bindTexture(final String file) {
final Identifier loc = new Identifier(AppEng.MOD_ID, "textures/" + file);
getMinecraft().getTextureManager().bindTexture(loc);
}
public void bindTexture(final Identifier loc) {
getMinecraft().getTextureManager().bindTexture(loc);
}
protected Scrollbar getScrollBar() {
return this.myScrollBar;
}
protected void setScrollBar(final Scrollbar myScrollBar) {
this.myScrollBar = myScrollBar;
}
protected List<InternalSlotME> getMeSlots() {
return this.meSlots;
}
}
@@ -0,0 +1,75 @@
package appeng.client.gui;
import javax.annotation.Nonnull;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraftforge.items.SlotItemHandler;
/**
* A proxy for a slot that will always return an itemstack with size 1, if there
* is an item in the slot. Used to prevent the default item count from
* rendering.
*/
class Size1Slot extends SlotItemHandler {
private final SlotItemHandler delegate;
public Size1Slot(SlotItemHandler delegate) {
super(delegate.getItemHandler(), delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
this.delegate = delegate;
}
@Override
@Nonnull
public ItemStack getStack() {
ItemStack orgStack = this.delegate.getStack();
if (!orgStack.isEmpty()) {
ItemStack modifiedStack = orgStack.copy();
modifiedStack.setCount(1);
return modifiedStack;
}
return ItemStack.EMPTY;
}
@Override
public boolean getHasStack() {
return this.delegate.getHasStack();
}
@Override
public int getSlotStackLimit() {
return this.delegate.getSlotStackLimit();
}
@Override
public int getItemStackLimit(ItemStack stack) {
return this.delegate.getItemStackLimit(stack);
}
@Override
public boolean canTakeStack(PlayerEntity playerIn) {
return this.delegate.canTakeStack(playerIn);
}
@Override
@Environment(EnvType.CLIENT)
public boolean isEnabled() {
return this.delegate.isEnabled();
}
@Override
public int getSlotIndex() {
return this.delegate.getSlotIndex();
}
@Override
public boolean isSameInventory(Slot other) {
return this.delegate.isSameInventory(other);
}
}
@@ -0,0 +1,113 @@
package appeng.client.gui.implementations;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IParts;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.TabButton;
import appeng.container.implementations.ChestContainer;
import appeng.container.implementations.CraftingTermContainer;
import appeng.container.implementations.MEMonitorableContainer;
import appeng.container.implementations.PatternTermContainer;
import appeng.container.implementations.WirelessTermContainer;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.SwitchGuisPacket;
import appeng.helpers.IPriorityHost;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.parts.reporting.CraftingTerminalPart;
import appeng.parts.reporting.PatternTerminalPart;
import appeng.parts.reporting.TerminalPart;
import appeng.tile.storage.ChestBlockEntity;
/**
* Utility class for sub-screens of other containers that allow returning to the
* primary container UI.
*/
final class AESubScreen {
private final AEBaseScreen<?> gui;
private final ScreenHandlerType<?> previousContainerType;
private final ItemStack previousContainerIcon;
/**
* Based on the container we're opening for, try to determine what it's
* "primary" GUI would be so that we can go back to it.
*/
public AESubScreen(AEBaseScreen<?> gui, Object containerTarget) {
this.gui = gui;
final IDefinitions definitions = AEApi.instance().definitions();
final IParts parts = definitions.parts();
if (containerTarget instanceof ChestBlockEntity) {
// A chest is also a priority host, but the priority _interface_ can only be
// opened from the
// chest ui that doesn't actually show the contents of the inserted cell.
IPriorityHost priorityHost = (IPriorityHost) containerTarget;
this.previousContainerIcon = priorityHost.getItemStackRepresentation();
this.previousContainerType = ChestContainer.TYPE;
}
else if (containerTarget instanceof IPriorityHost) {
IPriorityHost priorityHost = (IPriorityHost) containerTarget;
this.previousContainerIcon = priorityHost.getItemStackRepresentation();
this.previousContainerType = priorityHost.getContainerType();
}
else if (containerTarget instanceof WirelessTerminalGuiObject) {
this.previousContainerIcon = definitions.items().wirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = WirelessTermContainer.TYPE;
}
else if (containerTarget instanceof TerminalPart) {
this.previousContainerIcon = parts.terminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = MEMonitorableContainer.TYPE;
}
else if (containerTarget instanceof CraftingTerminalPart) {
this.previousContainerIcon = parts.craftingTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = CraftingTermContainer.TYPE;
}
else if (containerTarget instanceof PatternTerminalPart) {
this.previousContainerIcon = parts.patternTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = PatternTermContainer.TYPE;
}
else {
this.previousContainerIcon = null;
this.previousContainerType = null;
}
}
public final TabButton addBackButton(Consumer<TabButton> buttonAdder, int x, int y) {
return addBackButton(buttonAdder, x, y, null);
}
public final TabButton addBackButton(Consumer<TabButton> buttonAdder, int x, int y, @Nullable String label) {
if (this.previousContainerType != null && !previousContainerIcon.isEmpty()) {
if (label == null) {
label = previousContainerIcon.getName().getString();
}
ItemRenderer itemRenderer = gui.getMinecraft().getItemRenderer();
TabButton button = new TabButton(gui.getGuiLeft() + x, gui.getGuiTop() + y, previousContainerIcon, label,
itemRenderer, btn -> goBack());
buttonAdder.accept(button);
return button;
}
return null;
}
public final void goBack() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(this.previousContainerType));
}
}
@@ -0,0 +1,157 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import appeng.api.config.ActionItems;
import appeng.api.config.CopyMode;
import appeng.api.config.FuzzyMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.implementations.items.IUpgradeModule;
import appeng.client.gui.widgets.ActionButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.ToggleButton;
import appeng.container.implementations.CellWorkbenchContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class CellWorkbenchScreen extends UpgradeableScreen<CellWorkbenchContainer> {
private ToggleButton copyMode;
public CellWorkbenchScreen(CellWorkbenchContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.ySize = 251;
}
@Override
protected void addButtons() {
this.fuzzyMode = this.addButton(new SettingToggleButton<>(this.guiLeft - 18, this.guiTop + 68,
Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL, this::toggleFuzzyMode));
this.addButton(
new ActionButton(this.guiLeft - 18, this.guiTop + 28, ActionItems.WRENCH, act1 -> action("Partition")));
this.addButton(new ActionButton(this.guiLeft - 18, this.guiTop + 8, ActionItems.CLOSE, act -> action("Clear")));
this.copyMode = this.addButton(new ToggleButton(this.guiLeft - 18, this.guiTop + 48, 11 * 16 + 5, 12 * 16 + 5,
GuiText.CopyMode.getLocal(), GuiText.CopyModeDesc.getLocal(), act -> action("CopyMode")));
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.handleButtonVisibility();
this.bindTexture(this.getBackground());
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, 211 - 34, this.ySize, getBlitOffset());
if (this.drawUpgrades()) {
if (this.container.availableUpgrades() <= 8) {
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35,
7 + this.container.availableUpgrades() * 18, getBlitOffset());
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY + (7 + (this.container.availableUpgrades()) * 18),
177, 151, 35, 7, getBlitOffset());
} else if (this.container.availableUpgrades() <= 16) {
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35, 7 + 8 * 18, getBlitOffset());
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY + (7 + (8) * 18), 177, 151, 35, 7,
getBlitOffset());
final int dx = this.container.availableUpgrades() - 8;
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27, offsetY, 186, 0, 35 - 8, 7 + dx * 18,
getBlitOffset());
if (dx == 8) {
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27, offsetY + (7 + (dx) * 18), 186, 151, 35 - 8, 7,
getBlitOffset());
} else {
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27 + 4, offsetY + (7 + (dx) * 18), 186 + 4, 151,
35 - 8, 7, getBlitOffset());
}
} else {
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35, 7 + 8 * 18, getBlitOffset());
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY + (7 + (8) * 18), 177, 151, 35, 7,
getBlitOffset());
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27, offsetY, 186, 0, 35 - 8, 7 + 8 * 18,
getBlitOffset());
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27, offsetY + (7 + (8) * 18), 186, 151, 35 - 8, 7,
getBlitOffset());
final int dx = this.container.availableUpgrades() - 16;
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27 + 18, offsetY, 186, 0, 35 - 8, 7 + dx * 18,
getBlitOffset());
if (dx == 8) {
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27 + 18, offsetY + (7 + (dx) * 18), 186, 151, 35 - 8,
7, getBlitOffset());
} else {
GuiUtils.drawTexturedModalRect(offsetX + 177 + 27 + 18 + 4, offsetY + (7 + (dx) * 18), 186 + 4, 151,
35 - 8, 7, getBlitOffset());
}
}
}
if (this.hasToolbox()) {
GuiUtils.drawTexturedModalRect(offsetX + 178, offsetY + this.ySize - 90, 178, 161, 68, 68, getBlitOffset());
}
}
@Override
protected void handleButtonVisibility() {
this.copyMode.setState(this.container.getCopyMode() == CopyMode.CLEAR_ON_REMOVE);
boolean hasFuzzy = false;
final FixedItemInv inv = this.container.getCellUpgradeInventory();
for (int x = 0; x < inv.getSlotCount(); x++) {
final ItemStack is = inv.getInvStack(x);
if (!is.isEmpty() && is.getItem() instanceof IUpgradeModule) {
if (((IUpgradeModule) is.getItem()).getType(is) == Upgrades.FUZZY) {
hasFuzzy = true;
}
}
}
this.fuzzyMode.setVisibility(hasFuzzy);
}
@Override
protected String getBackground() {
return "guis/cellworkbench.png";
}
@Override
protected boolean drawUpgrades() {
return this.container.availableUpgrades() > 0;
}
@Override
protected GuiText getName() {
return GuiText.CellWorkbench;
}
private void action(String type) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("CellWorkbench.Action", type));
}
private void toggleFuzzyMode(SettingToggleButton<FuzzyMode> button, boolean backwards) {
FuzzyMode fz = button.getNextValue(backwards);
NetworkHandler.instance().sendToServer(new ConfigValuePacket("CellWorkbench.Fuzzy", fz.name()));
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.TabButton;
import appeng.container.implementations.ChestContainer;
import appeng.container.implementations.PriorityContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.SwitchGuisPacket;
public class ChestScreen extends AEBaseScreen<ChestContainer> {
public ChestScreen(ChestContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 166;
}
@Override
public void init() {
super.init();
this.addButton(new TabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(),
this.itemRenderer, btn -> openPriority()));
}
private void openPriority() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(PriorityContainer.TYPE));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.Chest.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/chest.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,71 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.config.CondenserOutput;
import appeng.api.config.Settings;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.ProgressBar;
import appeng.client.gui.widgets.ProgressBar.Direction;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.CondenserContainer;
import appeng.core.localization.GuiText;
public class CondenserScreen extends AEBaseScreen<CondenserContainer> {
private SettingToggleButton<CondenserOutput> mode;
public CondenserScreen(CondenserContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 197;
}
@Override
public void init() {
super.init();
this.mode = new ServerSettingToggleButton<>(128 + this.guiLeft, 52 + this.guiTop, Settings.CONDENSER_OUTPUT,
this.container.getOutput());
this.addButton(new ProgressBar(this.container, "guis/condenser.png", 120 + this.guiLeft, 25 + this.guiTop, 178,
25, 6, 18, Direction.VERTICAL, GuiText.StoredEnergy.getLocal()));
this.addButton(this.mode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.Condenser.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
this.mode.set(this.container.getOutput());
this.mode.setFillVar(String.valueOf(this.container.getOutput().requiredPower));
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/condenser.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,193 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.container.implementations.CraftAmountContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.CraftRequestPacket;
public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
private final AESubScreen subGui;
private NumberBox amountToCraft;
private Button next;
public CraftAmountScreen(CraftAmountContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.subGui = new AESubScreen(this, container.getTarget());
}
@Override
public void init() {
super.init();
final int a = AEConfig.instance().craftItemsByStackAmounts(0);
final int b = AEConfig.instance().craftItemsByStackAmounts(1);
final int c = AEConfig.instance().craftItemsByStackAmounts(2);
final int d = AEConfig.instance().craftItemsByStackAmounts(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 26, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 26, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 26, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 26, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 75, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 75, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 75, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 75, 38, 20, "-" + d, btn -> addQty(-d)));
this.next = this.addButton(
new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.getLocal(), this::confirm));
subGui.addBackButton(this::addButton, 154, 0);
this.amountToCraft = new NumberBox(this.font, this.guiLeft + 62, this.guiTop + 57, 59, this.font.FONT_HEIGHT,
Integer.class);
this.amountToCraft.setEnableBackgroundDrawing(false);
this.amountToCraft.setMaxStringLength(16);
this.amountToCraft.setTextColor(0xFFFFFF);
this.amountToCraft.setVisible(true);
this.amountToCraft.setFocused2(true);
this.amountToCraft.setText("1");
}
private void confirm(Button button) {
NetworkHandler.instance()
.sendToServer(new CraftRequestPacket(Integer.parseInt(this.amountToCraft.getText()), hasShiftDown()));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(GuiText.SelectAmount.getLocal(), 8, 6, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.next.setMessage(hasShiftDown() ? GuiText.Start.getLocal() : GuiText.Next.getLocal());
this.bindTexture("guis/craft_amt.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
try {
Long.parseLong(this.amountToCraft.getText());
this.next.active = !this.amountToCraft.getText().isEmpty();
} catch (final NumberFormatException e) {
this.next.active = false;
}
this.amountToCraft.render(offsetX, offsetY, partialTicks);
}
@Override
public boolean charTyped(char ch, int p_charTyped_2_) {
// Forward entered text to the craft amount text-field
return this.amountToCraft.charTyped(ch, p_charTyped_2_);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 28) {
this.next.onPress();
}
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.amountToCraft.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
try {
String out = this.amountToCraft.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.amountToCraft.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
final long result = Long.parseLong(out);
if (result < 0) {
this.amountToCraft.setText("1");
}
} catch (final NumberFormatException e) {
// :P
}
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
private void addQty(final int i) {
try {
String out = this.amountToCraft.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.amountToCraft.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
long result = Integer.parseInt(out);
if (result == 1 && i > 1) {
result = 0;
}
result += i;
if (result < 1) {
result = 1;
}
out = Long.toString(result);
Integer.parseInt(out);
this.amountToCraft.setText(out);
} catch (final NumberFormatException e) {
// :P
}
}
protected String getBackground() {
return "guis/craftAmt.png";
}
}
@@ -0,0 +1,460 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.google.common.base.Joiner;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.Scrollbar;
import appeng.container.implementations.CraftConfirmContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.util.Platform;
public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
private final AESubScreen subGui;
private final int rows = 5;
private final IItemList<IAEItemStack> storage = AEApi.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final IItemList<IAEItemStack> pending = AEApi.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final IItemList<IAEItemStack> missing = AEApi.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final List<IAEItemStack> visual = new ArrayList<>();
private Button start;
private Button selectCPU;
private int tooltip = -1;
public CraftConfirmScreen(CraftConfirmContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.subGui = new AESubScreen(this, container.getTarget());
this.xSize = 238;
this.ySize = 206;
final Scrollbar scrollbar = new Scrollbar();
this.setScrollBar(scrollbar);
}
boolean isAutoStart() {
return this.container.isAutoStart();
}
@Override
public void init() {
super.init();
this.start = new Button(this.guiLeft + 162, this.guiTop + this.ySize - 25, 50, 20, GuiText.Start.getLocal(),
btn -> start());
this.start.active = false;
this.addButton(this.start);
this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20,
GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic, btn -> selectNextCpu());
this.selectCPU.active = false;
this.addButton(this.selectCPU);
addButton(new Button(this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.getLocal(),
btn -> subGui.goBack()));
}
@Override
public void render(final int mouseX, final int mouseY, final float btn) {
this.updateCPUButtonText();
this.start.active = !(this.container.hasNoCPU() || this.isSimulation());
this.selectCPU.active = !this.isSimulation();
final int gx = (this.width - this.xSize) / 2;
final int gy = (this.height - this.ySize) / 2;
this.tooltip = -1;
final int offY = 23;
int y = 0;
int x = 0;
for (int z = 0; z <= 4 * 5; z++) {
final int minX = gx + 9 + x * 67;
final int minY = gy + 22 + y * offY;
if (minX < mouseX && minX + 67 > mouseX) {
if (minY < mouseY && minY + offY - 2 > mouseY) {
this.tooltip = z;
break;
}
}
x++;
if (x > 2) {
y++;
x = 0;
}
}
super.render(mouseX, mouseY, btn);
}
private void updateCPUButtonText() {
String btnTextText = GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic.getLocal();
if (this.container.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() )
{
if (this.container.getName() != null) {
final String name = this.container.getName().getStringTruncated(20);
btnTextText = GuiText.CraftingCPU.getLocal() + ": " + name;
} else {
btnTextText = GuiText.CraftingCPU.getLocal() + ": #" + this.container.getSelectedCpu();
}
}
if (this.container.hasNoCPU()) {
btnTextText = GuiText.NoCraftingCPUs.getLocal();
}
this.selectCPU.setMessage(btnTextText);
}
private boolean isSimulation() {
return this.container.isSimulation();
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
final long BytesUsed = this.container.getUsedBytes();
final String byteUsed = NumberFormat.getInstance().format(BytesUsed);
final String Add = BytesUsed > 0 ? (byteUsed + ' ' + GuiText.BytesUsed.getLocal())
: GuiText.CalculatingWait.getLocal();
this.font.drawString(GuiText.CraftingPlan.getLocal() + " - " + Add, 8, 7, 4210752);
String dsp = null;
if (this.isSimulation()) {
dsp = GuiText.Simulation.getLocal();
} else {
dsp = this.container.getCpuAvailableBytes() > 0
? (GuiText.Bytes.getLocal() + ": " + this.container.getCpuAvailableBytes() + " : "
+ GuiText.CoProcessors.getLocal() + ": " + this.container.getCpuCoProcessors())
: GuiText.Bytes.getLocal() + ": N/A : " + GuiText.CoProcessors.getLocal() + ": N/A";
}
final int offset = (219 - this.font.getStringWidth(dsp)) / 2;
this.font.drawString(dsp, offset, 165, 4210752);
final int sectionLength = 67;
int x = 0;
int y = 0;
final int xo = 9;
final int yo = 22;
final int viewStart = this.getScrollBar().getCurrentScroll() * 3;
final int viewEnd = viewStart + 3 * this.rows;
String dspToolTip = "";
final List<String> lineList = new ArrayList<>();
int toolPosX = 0;
int toolPosY = 0;
final int offY = 23;
for (int z = viewStart; z < Math.min(viewEnd, this.visual.size()); z++) {
final IAEItemStack refStack = this.visual.get(z);// repo.getReferenceItem( z );
if (refStack != null) {
RenderSystem.pushMatrix();
RenderSystem.scalef(0.5f, 0.5f, 0.5f);
final IAEItemStack stored = this.storage.findPrecise(refStack);
final IAEItemStack pendingStack = this.pending.findPrecise(refStack);
final IAEItemStack missingStack = this.missing.findPrecise(refStack);
int lines = 0;
if (stored != null && stored.getStackSize() > 0) {
lines++;
}
if (missingStack != null && missingStack.getStackSize() > 0) {
lines++;
}
if (pendingStack != null && pendingStack.getStackSize() > 0) {
lines++;
}
final int negY = ((lines - 1) * 5) / 2;
int downY = 0;
if (stored != null && stored.getStackSize() > 0) {
String str = Long.toString(stored.getStackSize());
if (stored.getStackSize() >= 10000) {
str = Long.toString(stored.getStackSize() / 1000) + 'k';
}
if (stored.getStackSize() >= 10000000) {
str = Long.toString(stored.getStackSize() / 1000000) + 'm';
}
str = GuiText.FromStorage.getLocal() + ": " + str;
final int w = 4 + this.font.getStringWidth(str);
this.font.drawString(str,
(int) ((x * (1 + sectionLength) + xo + sectionLength - 19 - (w * 0.5)) * 2),
(y * offY + yo + 6 - negY + downY) * 2, 4210752);
if (this.tooltip == z - viewStart) {
lineList.add(GuiText.FromStorage.getLocal() + ": " + Long.toString(stored.getStackSize()));
}
downY += 5;
}
boolean red = false;
if (missingStack != null && missingStack.getStackSize() > 0) {
String str = Long.toString(missingStack.getStackSize());
if (missingStack.getStackSize() >= 10000) {
str = Long.toString(missingStack.getStackSize() / 1000) + 'k';
}
if (missingStack.getStackSize() >= 10000000) {
str = Long.toString(missingStack.getStackSize() / 1000000) + 'm';
}
str = GuiText.Missing.getLocal() + ": " + str;
final int w = 4 + this.font.getStringWidth(str);
this.font.drawString(str,
(int) ((x * (1 + sectionLength) + xo + sectionLength - 19 - (w * 0.5)) * 2),
(y * offY + yo + 6 - negY + downY) * 2, 4210752);
if (this.tooltip == z - viewStart) {
lineList.add(GuiText.Missing.getLocal() + ": " + Long.toString(missingStack.getStackSize()));
}
red = true;
downY += 5;
}
if (pendingStack != null && pendingStack.getStackSize() > 0) {
String str = Long.toString(pendingStack.getStackSize());
if (pendingStack.getStackSize() >= 10000) {
str = Long.toString(pendingStack.getStackSize() / 1000) + 'k';
}
if (pendingStack.getStackSize() >= 10000000) {
str = Long.toString(pendingStack.getStackSize() / 1000000) + 'm';
}
str = GuiText.ToCraft.getLocal() + ": " + str;
final int w = 4 + this.font.getStringWidth(str);
this.font.drawString(str,
(int) ((x * (1 + sectionLength) + xo + sectionLength - 19 - (w * 0.5)) * 2),
(y * offY + yo + 6 - negY + downY) * 2, 4210752);
if (this.tooltip == z - viewStart) {
lineList.add(GuiText.ToCraft.getLocal() + ": " + Long.toString(pendingStack.getStackSize()));
}
}
RenderSystem.popMatrix();
final int posX = x * (1 + sectionLength) + xo + sectionLength - 19;
final int posY = y * offY + yo;
final ItemStack is = refStack.asItemStackRepresentation();
if (this.tooltip == z - viewStart) {
dspToolTip = Platform.getItemDisplayName(refStack).getFormattedText();
if (lineList.size() > 0) {
dspToolTip = dspToolTip + '\n' + Joiner.on("\n").join(lineList);
}
toolPosX = x * (1 + sectionLength) + xo + sectionLength - 8;
toolPosY = y * offY + yo;
}
this.drawItem(posX, posY, is);
if (red) {
final int startX = x * (1 + sectionLength) + xo;
final int startY = posY - 4;
fill(startX, startY, startX + sectionLength, startY + offY, 0x1AFF0000);
}
x++;
if (x > 2) {
y++;
x = 0;
}
}
}
if (this.tooltip >= 0 && !dspToolTip.isEmpty()) {
this.drawTooltip(toolPosX, toolPosY + 10, dspToolTip);
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.setScrollBar();
this.bindTexture("guis/craftingreport.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
private void setScrollBar() {
final int size = this.visual.size();
this.getScrollBar().setTop(19).setLeft(218).setHeight(114);
this.getScrollBar().setRange(0, (size + 2) / 3 - this.rows, 1);
}
public void postUpdate(final List<IAEItemStack> list, final byte ref) {
switch (ref) {
case 0:
for (final IAEItemStack l : list) {
this.handleInput(this.storage, l);
}
break;
case 1:
for (final IAEItemStack l : list) {
this.handleInput(this.pending, l);
}
break;
case 2:
for (final IAEItemStack l : list) {
this.handleInput(this.missing, l);
}
break;
}
for (final IAEItemStack l : list) {
final long amt = this.getTotal(l);
if (amt <= 0) {
this.deleteVisualStack(l);
} else {
final IAEItemStack is = this.findVisualStack(l);
is.setStackSize(amt);
}
}
this.setScrollBar();
}
private void handleInput(final IItemList<IAEItemStack> s, final IAEItemStack l) {
IAEItemStack a = s.findPrecise(l);
if (l.getStackSize() <= 0) {
if (a != null) {
a.reset();
}
} else {
if (a == null) {
s.add(l.copy());
a = s.findPrecise(l);
}
if (a != null) {
a.setStackSize(l.getStackSize());
}
}
}
private long getTotal(final IAEItemStack is) {
final IAEItemStack a = this.storage.findPrecise(is);
final IAEItemStack c = this.pending.findPrecise(is);
final IAEItemStack m = this.missing.findPrecise(is);
long total = 0;
if (a != null) {
total += a.getStackSize();
}
if (c != null) {
total += c.getStackSize();
}
if (m != null) {
total += m.getStackSize();
}
return total;
}
private void deleteVisualStack(final IAEItemStack l) {
final Iterator<IAEItemStack> i = this.visual.iterator();
while (i.hasNext()) {
final IAEItemStack o = i.next();
if (o.equals(l)) {
i.remove();
return;
}
}
}
private IAEItemStack findVisualStack(final IAEItemStack l) {
for (final IAEItemStack o : this.visual) {
if (o.equals(l)) {
return o;
}
}
final IAEItemStack stack = l.copy();
this.visual.add(stack);
return stack;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 28) {
this.start();
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
private void selectNextCpu() {
final boolean backwards = minecraft.mouseHelper.isRightDown();
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
}
private void start() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Start", "Start"));
}
}
@@ -0,0 +1,429 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Joiner;
import com.mojang.blaze3d.systems.RenderSystem;
import org.apache.commons.lang3.time.DurationFormatUtils;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.AEApi;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AEColor;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.Scrollbar;
import appeng.container.implementations.CraftingCPUContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.util.Platform;
import appeng.util.ReadableNumberConverter;
public class CraftingCPUScreen<T extends CraftingCPUContainer> extends AEBaseScreen<T> implements ISortSource {
private static final int GUI_HEIGHT = 184;
private static final int GUI_WIDTH = 238;
private static final int DISPLAYED_ROWS = 6;
private static final int TEXT_COLOR = 0x404040;
private static final int BACKGROUND_ALPHA = 0x5A000000;
private static final int SECTION_LENGTH = 67;
private static final int SCROLLBAR_TOP = 19;
private static final int SCROLLBAR_LEFT = 218;
private static final int SCROLLBAR_HEIGHT = 137;
private static final int CANCEL_LEFT_OFFSET = 163;
private static final int CANCEL_TOP_OFFSET = 25;
private static final int CANCEL_HEIGHT = 20;
private static final int CANCEL_WIDTH = 50;
private static final int TITLE_TOP_OFFSET = 7;
private static final int TITLE_LEFT_OFFSET = 8;
private static final int ITEMSTACK_LEFT_OFFSET = 9;
private static final int ITEMSTACK_TOP_OFFSET = 22;
private IItemList<IAEItemStack> storage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private IItemList<IAEItemStack> active = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private IItemList<IAEItemStack> pending = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private List<IAEItemStack> visual = new ArrayList<>();
private Button cancel;
private int tooltip = -1;
public CraftingCPUScreen(T container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = GUI_HEIGHT;
this.xSize = GUI_WIDTH;
final Scrollbar scrollbar = new Scrollbar();
this.setScrollBar(scrollbar);
}
public void clearItems() {
this.storage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.active = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.pending = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.visual = new ArrayList<>();
}
private void cancel() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("TileCrafting.Cancel", "Cancel"));
}
@Override
public void init() {
super.init();
this.setScrollBar();
this.cancel = new Button(this.guiLeft + CANCEL_LEFT_OFFSET, this.guiTop + this.ySize - CANCEL_TOP_OFFSET,
CANCEL_WIDTH, CANCEL_HEIGHT, GuiText.Cancel.getLocal(), btn -> cancel());
this.addButton(this.cancel);
}
private void setScrollBar() {
final int size = this.visual.size();
this.getScrollBar().setTop(SCROLLBAR_TOP).setLeft(SCROLLBAR_LEFT).setHeight(SCROLLBAR_HEIGHT);
this.getScrollBar().setRange(0, (size + 2) / 3 - DISPLAYED_ROWS, 1);
}
@Override
public void render(final int mouseX, final int mouseY, final float btn) {
this.cancel.active = !this.visual.isEmpty();
final int gx = (this.width - this.xSize) / 2;
final int gy = (this.height - this.ySize) / 2;
this.tooltip = -1;
final int offY = 23;
int y = 0;
int x = 0;
for (int z = 0; z <= 4 * 5; z++) {
final int minX = gx + 9 + x * 67;
final int minY = gy + 22 + y * offY;
if (minX < mouseX && minX + 67 > mouseX) {
if (minY < mouseY && minY + offY - 2 > mouseY) {
this.tooltip = z;
break;
}
}
x++;
if (x > 2) {
y++;
x = 0;
}
}
super.render(mouseX, mouseY, btn);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
String title = this.getGuiDisplayName(GuiText.CraftingStatus.getLocal());
if (this.container.getEstimatedTime() > 0 && !this.visual.isEmpty()) {
final long etaInMilliseconds = TimeUnit.MILLISECONDS.convert(this.container.getEstimatedTime(),
TimeUnit.NANOSECONDS);
final String etaTimeText = DurationFormatUtils.formatDuration(etaInMilliseconds,
GuiText.ETAFormat.getLocal());
title += " - " + etaTimeText;
}
this.font.drawString(title, TITLE_LEFT_OFFSET, TITLE_TOP_OFFSET, TEXT_COLOR);
int x = 0;
int y = 0;
final int viewStart = this.getScrollBar().getCurrentScroll() * 3;
final int viewEnd = viewStart + 3 * 6;
String dspToolTip = "";
final List<String> lineList = new ArrayList<>();
int toolPosX = 0;
int toolPosY = 0;
final int offY = 23;
final ReadableNumberConverter converter = ReadableNumberConverter.INSTANCE;
for (int z = viewStart; z < Math.min(viewEnd, this.visual.size()); z++) {
final IAEItemStack refStack = this.visual.get(z);// repo.getReferenceItem( z );
if (refStack != null) {
RenderSystem.pushMatrix();
RenderSystem.scalef(0.5f, 0.5f, 0.5f);
final IAEItemStack stored = this.storage.findPrecise(refStack);
final IAEItemStack activeStack = this.active.findPrecise(refStack);
final IAEItemStack pendingStack = this.pending.findPrecise(refStack);
int lines = 0;
if (stored != null && stored.getStackSize() > 0) {
lines++;
}
boolean active = false;
if (activeStack != null && activeStack.getStackSize() > 0) {
lines++;
active = true;
}
boolean scheduled = false;
if (pendingStack != null && pendingStack.getStackSize() > 0) {
lines++;
scheduled = true;
}
if (AEConfig.instance().isUseColoredCraftingStatus() && (active || scheduled)) {
final int bgColor = (active ? AEColor.GREEN.blackVariant : AEColor.YELLOW.blackVariant)
| BACKGROUND_ALPHA;
final int startX = (x * (1 + SECTION_LENGTH) + ITEMSTACK_LEFT_OFFSET) * 2;
final int startY = ((y * offY + ITEMSTACK_TOP_OFFSET) - 3) * 2;
fill(startX, startY, startX + (SECTION_LENGTH * 2), startY + (offY * 2) - 2, bgColor);
}
final int negY = ((lines - 1) * 5) / 2;
int downY = 0;
if (stored != null && stored.getStackSize() > 0) {
final String str = GuiText.Stored.getLocal() + ": "
+ converter.toWideReadableForm(stored.getStackSize());
final int w = 4 + this.font.getStringWidth(str);
this.font.drawString(str,
(int) ((x * (1 + SECTION_LENGTH) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19 - (w * 0.5))
* 2),
(y * offY + ITEMSTACK_TOP_OFFSET + 6 - negY + downY) * 2, TEXT_COLOR);
if (this.tooltip == z - viewStart) {
lineList.add(GuiText.Stored.getLocal() + ": " + Long.toString(stored.getStackSize()));
}
downY += 5;
}
if (activeStack != null && activeStack.getStackSize() > 0) {
final String str = GuiText.Crafting.getLocal() + ": "
+ converter.toWideReadableForm(activeStack.getStackSize());
final int w = 4 + this.font.getStringWidth(str);
this.font.drawString(str,
(int) ((x * (1 + SECTION_LENGTH) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19 - (w * 0.5))
* 2),
(y * offY + ITEMSTACK_TOP_OFFSET + 6 - negY + downY) * 2, TEXT_COLOR);
if (this.tooltip == z - viewStart) {
lineList.add(GuiText.Crafting.getLocal() + ": " + Long.toString(activeStack.getStackSize()));
}
downY += 5;
}
if (pendingStack != null && pendingStack.getStackSize() > 0) {
final String str = GuiText.Scheduled.getLocal() + ": "
+ converter.toWideReadableForm(pendingStack.getStackSize());
final int w = 4 + this.font.getStringWidth(str);
this.font.drawString(str,
(int) ((x * (1 + SECTION_LENGTH) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19 - (w * 0.5))
* 2),
(y * offY + ITEMSTACK_TOP_OFFSET + 6 - negY + downY) * 2, TEXT_COLOR);
if (this.tooltip == z - viewStart) {
lineList.add(GuiText.Scheduled.getLocal() + ": " + Long.toString(pendingStack.getStackSize()));
}
}
RenderSystem.popMatrix();
final int posX = x * (1 + SECTION_LENGTH) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 19;
final int posY = y * offY + ITEMSTACK_TOP_OFFSET;
final ItemStack is = refStack.asItemStackRepresentation();
if (this.tooltip == z - viewStart) {
dspToolTip = Platform.getItemDisplayName(refStack).getFormattedText();
if (lineList.size() > 0) {
dspToolTip = dspToolTip + '\n' + Joiner.on("\n").join(lineList);
}
toolPosX = x * (1 + SECTION_LENGTH) + ITEMSTACK_LEFT_OFFSET + SECTION_LENGTH - 8;
toolPosY = y * offY + ITEMSTACK_TOP_OFFSET;
}
this.drawItem(posX, posY, is);
x++;
if (x > 2) {
y++;
x = 0;
}
}
}
if (this.tooltip >= 0 && !dspToolTip.isEmpty()) {
this.drawTooltip(toolPosX, toolPosY + 10, dspToolTip);
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/craftingcpu.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
public void postUpdate(final List<IAEItemStack> list, final byte ref) {
switch (ref) {
case 0:
for (final IAEItemStack l : list) {
this.handleInput(this.storage, l);
}
break;
case 1:
for (final IAEItemStack l : list) {
this.handleInput(this.active, l);
}
break;
case 2:
for (final IAEItemStack l : list) {
this.handleInput(this.pending, l);
}
break;
}
for (final IAEItemStack l : list) {
final long amt = this.getTotal(l);
if (amt <= 0) {
this.deleteVisualStack(l);
} else {
final IAEItemStack is = this.findVisualStack(l);
is.setStackSize(amt);
}
}
this.setScrollBar();
}
private void handleInput(final IItemList<IAEItemStack> s, final IAEItemStack l) {
IAEItemStack a = s.findPrecise(l);
if (l.getStackSize() <= 0) {
if (a != null) {
a.reset();
}
} else {
if (a == null) {
s.add(l.copy());
a = s.findPrecise(l);
}
if (a != null) {
a.setStackSize(l.getStackSize());
}
}
}
private long getTotal(final IAEItemStack is) {
final IAEItemStack a = this.storage.findPrecise(is);
final IAEItemStack b = this.active.findPrecise(is);
final IAEItemStack c = this.pending.findPrecise(is);
long total = 0;
if (a != null) {
total += a.getStackSize();
}
if (b != null) {
total += b.getStackSize();
}
if (c != null) {
total += c.getStackSize();
}
return total;
}
private void deleteVisualStack(final IAEItemStack l) {
final Iterator<IAEItemStack> i = this.visual.iterator();
while (i.hasNext()) {
final IAEItemStack o = i.next();
if (o.equals(l)) {
i.remove();
return;
}
}
}
private IAEItemStack findVisualStack(final IAEItemStack l) {
for (final IAEItemStack o : this.visual) {
if (o.equals(l)) {
return o;
}
}
final IAEItemStack stack = l.copy();
this.visual.add(stack);
return stack;
}
@Override
public SortOrder getSortBy() {
return SortOrder.NAME;
}
@Override
public SortDir getSortDir() {
return SortDir.ASCENDING;
}
@Override
public ViewItems getSortDisplay() {
return ViewItems.ALL;
}
}
@@ -0,0 +1,97 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
/**
*
*/
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.container.implementations.CraftingStatusContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContainer> {
private final AESubScreen subGui;
private Button selectCPU;
public CraftingStatusScreen(CraftingStatusContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.subGui = new AESubScreen(this, container.getTarget());
}
@Override
public void init() {
super.init();
this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20,
GuiText.CraftingCPU.getLocal() + ": " + GuiText.NoCraftingCPUs, btn -> selectNextCpu());
this.addButton(this.selectCPU);
subGui.addBackButton(btn -> {
addButton(btn);
btn.setHideEdge(13);
}, 213, -4);
}
@Override
public void render(final int mouseX, final int mouseY, final float btn) {
this.updateCPUButtonText();
super.render(mouseX, mouseY, btn);
}
private void updateCPUButtonText() {
String btnTextText = GuiText.NoCraftingJobs.getLocal();
if (this.container.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
{
if (this.container.myName != null) {
final String name = this.container.myName.getStringTruncated(20);
btnTextText = GuiText.CPUs.getLocal() + ": " + name;
} else {
btnTextText = GuiText.CPUs.getLocal() + ": #" + this.container.selectedCpu;
}
}
if (this.container.noCPU) {
btnTextText = GuiText.NoCraftingJobs.getLocal();
}
this.selectCPU.setMessage(btnTextText);
}
@Override
protected String getGuiDisplayName(final String in) {
return in; // the cup name is on the button
}
// FIXME: Extract to separate class? Shared with GuiCraftConfirm
private void selectNextCpu() {
final boolean backwards = minecraft.mouseHelper.isRightDown();
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
}
}
@@ -0,0 +1,74 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.text.Text;
import appeng.api.config.ActionItems;
import appeng.client.gui.widgets.ActionButton;
import appeng.container.implementations.CraftingTermContainer;
import appeng.container.slot.CraftingMatrixSlot;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.InventoryActionPacket;
import appeng.helpers.InventoryAction;
public class CraftingTermScreen extends MEMonitorableScreen<CraftingTermContainer> {
public CraftingTermScreen(CraftingTermContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.setReservedSpace(73);
}
private void clear() {
Slot s = null;
for (final Object j : this.container.inventorySlots) {
if (j instanceof CraftingMatrixSlot) {
s = (Slot) j;
}
}
if (s != null) {
final InventoryActionPacket p = new InventoryActionPacket(InventoryAction.MOVE_REGION, s.slotNumber, 0);
NetworkHandler.instance().sendToServer(p);
}
}
@Override
public void init() {
super.init();
ActionButton clearBtn = this.addButton(
new ActionButton(this.guiLeft + 92, this.guiTop + this.ySize - 156, ActionItems.STASH, btn -> clear()));
clearBtn.setHalfSize(true);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
super.drawFG(offsetX, offsetY, mouseX, mouseY);
this.font.drawString(GuiText.CraftingTerminal.getLocal(), 8, this.ySize - 96 + 1 - this.getReservedSpace(),
4210752);
}
@Override
protected String getBackground() {
return "guis/crafting.png";
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.TabButton;
import appeng.container.implementations.DriveContainer;
import appeng.container.implementations.PriorityContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.SwitchGuisPacket;
public class DriveScreen extends AEBaseScreen<DriveContainer> {
public DriveScreen(DriveContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 199;
}
@Override
public void init() {
super.init();
this.addButton(new TabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(),
this.itemRenderer, btn -> openPriorityGui()));
}
private void openPriorityGui() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(PriorityContainer.TYPE));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.Drive.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/drive.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,83 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.config.FuzzyMode;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton;
import appeng.container.implementations.FormationPlaneContainer;
import appeng.container.implementations.PriorityContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.SwitchGuisPacket;
public class FormationPlaneScreen extends UpgradeableScreen<FormationPlaneContainer> {
private SettingToggleButton<YesNo> placeMode;
public FormationPlaneScreen(FormationPlaneContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.ySize = 251;
}
@Override
protected void addButtons() {
this.placeMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28, Settings.PLACE_BLOCK,
YesNo.YES);
this.fuzzyMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48, Settings.FUZZY_MODE,
FuzzyMode.IGNORE_ALL);
this.addButton(new TabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(),
this.itemRenderer, btn -> openPriorityGui()));
this.addButton(this.placeMode);
this.addButton(this.fuzzyMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.FormationPlane.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
if (this.fuzzyMode != null) {
this.fuzzyMode.set(this.cvb.getFuzzyMode());
}
if (this.placeMode != null) {
this.placeMode.set(((FormationPlaneContainer) this.cvb).getPlaceMode());
}
}
@Override
protected String getBackground() {
return "guis/storagebus.png";
}
private void openPriorityGui() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(PriorityContainer.TYPE));
}
}
@@ -0,0 +1,47 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.container.implementations.GrinderContainer;
import appeng.core.localization.GuiText;
public class GrinderScreen extends AEBaseScreen<GrinderContainer> {
public GrinderScreen(GrinderContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 176;
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.GrindStone.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/grinder.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,95 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.config.FullnessMode;
import appeng.api.config.OperationMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.definitions.IDefinitions;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.IOPortContainer;
import appeng.core.localization.GuiText;
public class IOPortScreen extends UpgradeableScreen<IOPortContainer> {
private SettingToggleButton<FullnessMode> fullMode;
private SettingToggleButton<OperationMode> operationMode;
public IOPortScreen(IOPortContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 166;
}
@Override
protected void addButtons() {
this.fullMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8, Settings.FULLNESS_MODE,
FullnessMode.EMPTY);
this.operationMode = new ServerSettingToggleButton<>(this.guiLeft + 80, this.guiTop + 17,
Settings.OPERATION_MODE, OperationMode.EMPTY);
this.addButton(this.operationMode);
this.addButton(this.fullMode);
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28,
Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE);
addButton(this.redstoneMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.IOPort.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
if (this.redstoneMode != null) {
this.redstoneMode.set(this.cvb.getRedStoneMode());
}
if (this.operationMode != null) {
this.operationMode.set(((IOPortContainer) this.cvb).getOperationMode());
}
if (this.fullMode != null) {
this.fullMode.set(((IOPortContainer) this.cvb).getFullMode());
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
super.drawBG(offsetX, offsetY, mouseX, mouseY, partialTicks);
final IDefinitions definitions = AEApi.instance().definitions();
definitions.items().cell1k().maybeStack(1)
.ifPresent(cell1kStack -> this.drawItem(offsetX + 66 - 8, offsetY + 17, cell1kStack));
definitions.blocks().drive().maybeStack(1)
.ifPresent(driveStack -> this.drawItem(offsetX + 94 + 8, offsetY + 17, driveStack));
}
@Override
protected String getBackground() {
return "guis/io_port.png";
}
}
@@ -0,0 +1,82 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.ProgressBar;
import appeng.client.gui.widgets.ProgressBar.Direction;
import appeng.container.implementations.InscriberContainer;
import appeng.core.localization.GuiText;
public class InscriberScreen extends AEBaseScreen<InscriberContainer> {
private ProgressBar pb;
public InscriberScreen(InscriberContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 176;
this.xSize = this.hasToolbox() ? 246 : 211;
}
private boolean hasToolbox() {
return this.container.hasToolbox();
}
@Override
public void init() {
super.init();
this.pb = new ProgressBar(this.container, "guis/inscriber.png", 135, 39, 135, 177, 6, 18, Direction.VERTICAL);
this.addButton(this.pb);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.pb.setFullMsg(this.container.getCurrentProgress() * 100 / this.container.getMaxProgress() + "%");
this.font.drawString(this.getGuiDisplayName(GuiText.Inscriber.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/inscriber.png");
this.pb.x = 135 + this.guiLeft;
this.pb.y = 39 + this.guiTop;
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, 211 - 34, this.ySize, getBlitOffset());
if (this.drawUpgrades()) {
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35,
14 + this.container.availableUpgrades() * 18, getBlitOffset());
}
if (this.hasToolbox()) {
GuiUtils.drawTexturedModalRect(offsetX + 178, offsetY + this.ySize - 90, 178, this.ySize - 90, 68, 68,
getBlitOffset());
}
}
private boolean drawUpgrades() {
return true;
}
}
@@ -0,0 +1,94 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton;
import appeng.client.gui.widgets.ToggleButton;
import appeng.container.implementations.InterfaceContainer;
import appeng.container.implementations.PriorityContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigButtonPacket;
import appeng.core.sync.packets.SwitchGuisPacket;
public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
private SettingToggleButton<YesNo> blockMode;
private ToggleButton interfaceMode;
public InterfaceScreen(InterfaceContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 211;
}
@Override
protected void addButtons() {
this.addButton(new TabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(),
this.itemRenderer, btn -> openPriorityGui()));
this.blockMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO);
this.addButton(this.blockMode);
this.interfaceMode = new ToggleButton(this.guiLeft - 18, this.guiTop + 26, 84, 85,
GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal(),
btn -> selectNextInterfaceMode());
this.addButton(this.interfaceMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
if (this.blockMode != null) {
this.blockMode.set(((InterfaceContainer) this.cvb).getBlockingMode());
}
if (this.interfaceMode != null) {
this.interfaceMode.setState(((InterfaceContainer) this.cvb).getInterfaceTerminalMode() == YesNo.YES);
}
this.font.drawString(this.getGuiDisplayName(GuiText.Interface.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.Config.getLocal(), 8, 6 + 11 + 7, 4210752);
this.font.drawString(GuiText.StoredItems.getLocal(), 8, 6 + 60 + 7, 4210752);
this.font.drawString(GuiText.Patterns.getLocal(), 8, 6 + 73 + 7, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
protected String getBackground() {
return "guis/interface.png";
}
private void openPriorityGui() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(PriorityContainer.TYPE));
}
private void selectNextInterfaceMode() {
final boolean backwards = getMinecraft().mouseHelper.isRightDown();
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
}
}
@@ -0,0 +1,381 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import com.google.common.collect.HashMultimap;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.util.InputUtil;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.AETextField;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.ClientDCInternalInv;
import appeng.client.me.SlotDisconnected;
import appeng.container.implementations.InterfaceTerminalContainer;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalContainer> {
private static final int LINES_ON_PAGE = 6;
private final HashMap<Long, ClientDCInternalInv> byId = new HashMap<>();
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
private final ArrayList<String> names = new ArrayList<>();
private final ArrayList<Object> lines = new ArrayList<>();
private final Map<String, Set<Object>> cachedSearches = new WeakHashMap<>();
private boolean refreshList = false;
private AETextField searchField;
public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
final Scrollbar scrollbar = new Scrollbar();
this.setScrollBar(scrollbar);
this.xSize = 195;
this.ySize = 222;
}
@Override
public void init() {
super.init();
this.getScrollBar().setLeft(175);
this.getScrollBar().setHeight(106);
this.getScrollBar().setTop(18);
this.searchField = new AETextField(this.font, this.guiLeft + 104, this.guiTop + 4, 65, 12);
this.searchField.setEnableBackgroundDrawing(false);
this.searchField.setMaxStringLength(25);
this.searchField.setTextColor(0xFFFFFF);
this.searchField.setVisible(true);
this.searchField.setFocused2(true);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.InterfaceTerminal.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
final int ex = this.getScrollBar().getCurrentScroll();
this.container.inventorySlots.removeIf(slot -> slot instanceof SlotDisconnected);
int offset = 17;
for (int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++) {
final Object lineObj = this.lines.get(ex + x);
if (lineObj instanceof ClientDCInternalInv) {
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
for (int z = 0; z < inv.getInventory().getSlotCount(); z++) {
this.container.inventorySlots.add(new SlotDisconnected(inv, z, z * 18 + 8, 1 + offset));
}
} else if (lineObj instanceof String) {
String name = (String) lineObj;
final int rows = this.byName.get(name).size();
if (rows > 1) {
name = name + " (" + rows + ')';
}
while (name.length() > 2 && this.font.getStringWidth(name) > 155) {
name = name.substring(0, name.length() - 1);
}
this.font.drawString(name, 10, 6 + offset, 4210752);
}
offset += 18;
}
}
@Override
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
this.refreshList();
}
return true;
}
return super.mouseClicked(xCoord, yCoord, btn);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/interfaceterminal.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
int offset = 17;
final int ex = this.getScrollBar().getCurrentScroll();
for (int x = 0; x < LINES_ON_PAGE && ex + x < this.lines.size(); x++) {
final Object lineObj = this.lines.get(ex + x);
if (lineObj instanceof ClientDCInternalInv) {
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
RenderSystem.color4f(1, 1, 1, 1);
final int width = inv.getInventory().getSlotCount() * 18;
GuiUtils.drawTexturedModalRect(offsetX + 7, offsetY + offset, 7, 139, width, 18, getBlitOffset());
}
offset += 18;
}
if (this.searchField != null) {
this.searchField.render(mouseX, mouseY, partialTicks);
}
}
@Override
public boolean charTyped(char character, int key) {
if (character == ' ' && this.searchField.getText().isEmpty()) {
return true;
}
if (this.searchField.charTyped(character, key)) {
this.refreshList();
return true;
}
return false;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
InputUtil.Key input = InputMappings.getInputByCode(keyCode, scanCode);
if (keyCode != GLFW.GLFW_KEY_ESCAPE) {
if (AppEng.instance().isActionKey(ActionKey.TOGGLE_FOCUS, input)) {
this.searchField.setFocused2(!this.searchField.isFocused());
return true;
}
// Forward keypresses to the search field
if (this.searchField.isFocused()) {
if (keyCode == GLFW.GLFW_KEY_ENTER) {
this.searchField.setFocused2(false);
return true;
}
this.searchField.keyPressed(keyCode, scanCode, p_keyPressed_3_);
// We need to swallow key presses if the field is focused because typing 'e'
// would otherwise close the screen
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
public void postUpdate(final CompoundTag in) {
if (in.getBoolean("clear")) {
this.byId.clear();
this.refreshList = true;
}
for (final Object oKey : in.getKeys()) {
final String key = (String) oKey;
if (key.startsWith("=")) {
try {
final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX);
final CompoundTag invData = in.getCompound(key);
Text un = Text.Serializer.fromJson(invData.getString("un"));
final ClientDCInternalInv current = this.getById(id, invData.getLong("sortBy"), un);
for (int x = 0; x < current.getInventory().getSlotCount(); x++) {
final String which = Integer.toString(x);
if (invData.contains(which)) {
current.getInventory().setInvStack(x, ItemStack.fromTag(invData.getCompound(which)));
}
}
} catch (final NumberFormatException ignored) {
}
}
}
if (this.refreshList) {
this.refreshList = false;
// invalid caches on refresh
this.cachedSearches.clear();
this.refreshList();
}
}
/**
* Rebuilds the list of interfaces.
*
* Respects a search term if present (ignores case) and adding only matching
* patterns.
*/
private void refreshList() {
this.byName.clear();
final String searchFilterLowerCase = this.searchField.getText().toLowerCase();
final Set<Object> cachedSearch = this.getCacheForSearchTerm(searchFilterLowerCase);
final boolean rebuild = cachedSearch.isEmpty();
for (final ClientDCInternalInv entry : this.byId.values()) {
// ignore inventory if not doing a full rebuild or cache already marks it as
// miss.
if (!rebuild && !cachedSearch.contains(entry)) {
continue;
}
// Shortcut to skip any filter if search term is ""/empty
boolean found = searchFilterLowerCase.isEmpty();
// Search if the current inventory holds a pattern containing the search term.
if (!found && !searchFilterLowerCase.isEmpty()) {
for (final ItemStack itemStack : entry.getInventory()) {
found = this.itemStackMatchesSearchTerm(itemStack, searchFilterLowerCase);
if (found) {
break;
}
}
}
// if found, filter skipped or machine name matching the search term, add it
if (found || entry.getSearchName().contains(searchFilterLowerCase)) {
this.byName.put(entry.getFormattedName(), entry);
cachedSearch.add(entry);
} else {
cachedSearch.remove(entry);
}
}
this.names.clear();
this.names.addAll(this.byName.keySet());
Collections.sort(this.names);
this.lines.clear();
this.lines.ensureCapacity(this.getMaxRows());
for (final String n : this.names) {
this.lines.add(n);
List<ClientDCInternalInv> clientInventories = new ArrayList<>(this.byName.get(n));
Collections.sort(clientInventories);
this.lines.addAll(clientInventories);
}
this.getScrollBar().setRange(0, this.lines.size() - LINES_ON_PAGE, 2);
}
private boolean itemStackMatchesSearchTerm(final ItemStack itemStack, final String searchTerm) {
if (itemStack.isEmpty()) {
return false;
}
final CompoundTag encodedValue = itemStack.getTag();
if (encodedValue == null) {
return false;
}
// Potential later use to filter by input
// ListNBT inTag = encodedValue.getTagList( "in", 10 );
final ListTag outTag = encodedValue.getList("out", 10);
for (int i = 0; i < outTag.size(); i++) {
final ItemStack parsedItemStack = ItemStack.fromTag(outTag.getCompound(i));
if (!parsedItemStack.isEmpty()) {
final String displayName = Platform.getItemDisplayName(AEApi.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createStack(parsedItemStack)).getString()
.toLowerCase();
if (displayName.contains(searchTerm)) {
return true;
}
}
}
return false;
}
/**
* Tries to retrieve a cache for a with search term as keyword.
*
* If this cache should be empty, it will populate it with an earlier cache if
* available or at least the cache for the empty string.
*
* @param searchTerm the corresponding search
*
* @return a Set matching a superset of the search term
*/
private Set<Object> getCacheForSearchTerm(final String searchTerm) {
if (!this.cachedSearches.containsKey(searchTerm)) {
this.cachedSearches.put(searchTerm, new HashSet<>());
}
final Set<Object> cache = this.cachedSearches.get(searchTerm);
if (cache.isEmpty() && searchTerm.length() > 1) {
cache.addAll(this.getCacheForSearchTerm(searchTerm.substring(0, searchTerm.length() - 1)));
return cache;
}
return cache;
}
/**
* The max amount of unique names and each inv row. Not affected by the
* filtering.
*
* @return max amount of unique names and each inv row
*/
private int getMaxRows() {
return this.names.size() + this.byId.size();
}
private ClientDCInternalInv getById(final long id, final long sortBy, final Text name) {
ClientDCInternalInv o = this.byId.get(id);
if (o == null) {
this.byId.put(id, o = new ClientDCInternalInv(9, id, sortBy, name));
this.refreshList = true;
}
return o;
}
}
@@ -0,0 +1,229 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.NumberBox;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.LevelEmitterContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
private NumberBox level;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
private SettingToggleButton<LevelType> levelMode;
private SettingToggleButton<YesNo> craftingMode;
public LevelEmitterScreen(LevelEmitterContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
}
@Override
public void init() {
super.init();
this.level = new NumberBox(this.font, this.guiLeft + 24, this.guiTop + 43, 79, this.font.FONT_HEIGHT,
Long.class);
this.level.setEnableBackgroundDrawing(false);
this.level.setMaxStringLength(16);
this.level.setTextColor(0xFFFFFF);
this.level.setVisible(true);
this.level.setFocused2(true);
container.setTextField(this.level);
}
@Override
protected void addButtons() {
this.levelMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8, Settings.LEVEL_TYPE,
LevelType.ITEM_LEVEL);
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28,
Settings.REDSTONE_EMITTER, RedstoneMode.LOW_SIGNAL);
this.fuzzyMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48, Settings.FUZZY_MODE,
FuzzyMode.IGNORE_ALL);
this.craftingMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48,
Settings.CRAFT_VIA_REDSTONE, YesNo.NO);
final int a = AEConfig.instance().levelByStackAmounts(0);
final int b = AEConfig.instance().levelByStackAmounts(1);
final int c = AEConfig.instance().levelByStackAmounts(2);
final int d = AEConfig.instance().levelByStackAmounts(3);
this.addButton(this.plus1 = new Button(this.guiLeft + 20, this.guiTop + 17, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(
this.plus10 = new Button(this.guiLeft + 48, this.guiTop + 17, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(
this.plus100 = new Button(this.guiLeft + 82, this.guiTop + 17, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(
this.plus1000 = new Button(this.guiLeft + 120, this.guiTop + 17, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(
this.minus1 = new Button(this.guiLeft + 20, this.guiTop + 59, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(
this.minus10 = new Button(this.guiLeft + 48, this.guiTop + 59, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(
this.minus100 = new Button(this.guiLeft + 82, this.guiTop + 59, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(
this.minus1000 = new Button(this.guiLeft + 120, this.guiTop + 59, 38, 20, "-" + d, btn -> addQty(-d)));
this.addButton(this.levelMode);
this.addButton(this.redstoneMode);
this.addButton(this.craftingMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
final boolean notCraftingMode = this.bc.getInstalledUpgrades(Upgrades.CRAFTING) == 0;
// configure enabled status...
this.level.setEnabled(notCraftingMode);
this.plus1.active = notCraftingMode;
this.plus10.active = notCraftingMode;
this.plus100.active = notCraftingMode;
this.plus1000.active = notCraftingMode;
this.minus1.active = notCraftingMode;
this.minus10.active = notCraftingMode;
this.minus100.active = notCraftingMode;
this.minus1000.active = notCraftingMode;
this.levelMode.active = notCraftingMode;
this.redstoneMode.active = notCraftingMode;
super.drawFG(offsetX, offsetY, mouseX, mouseY);
if (this.craftingMode != null) {
this.craftingMode.set(this.cvb.getCraftingMode());
}
if (this.levelMode != null) {
this.levelMode.set(((LevelEmitterContainer) this.cvb).getLevelMode());
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
super.drawBG(offsetX, offsetY, mouseX, mouseY, partialTicks);
this.level.render(mouseX, mouseY, partialTicks);
}
@Override
protected void handleButtonVisibility() {
this.craftingMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.CRAFTING) > 0);
this.fuzzyMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.FUZZY) > 0);
}
@Override
protected String getBackground() {
return "guis/lvlemitter.png";
}
@Override
protected GuiText getName() {
return GuiText.LevelEmitter;
}
private void addQty(final long i) {
try {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
long result = Long.parseLong(Out);
result += i;
if (result < 0) {
result = 0;
}
this.level.setText(Out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", Out));
} catch (final NumberFormatException e) {
// nope..
this.level.setText("0");
}
}
@Override
public boolean charTyped(char character, int key) {
// Forward entered characters to the number-text-field
return level.charTyped(character, key);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14) {
String Out = this.level.getText();
boolean Fixed = false;
while (Out.startsWith("0") && Out.length() > 1) {
Out = Out.substring(1);
Fixed = true;
}
if (Fixed) {
this.level.setText(Out);
}
if (Out.isEmpty()) {
Out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", Out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
@@ -0,0 +1,512 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import java.util.List;
import net.minecraft.client.util.InputUtil;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import appeng.api.config.*;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.api.implementations.tiles.IMEChest;
import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseMEScreen;
import appeng.client.gui.widgets.*;
import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo;
import appeng.container.implementations.CraftingStatusContainer;
import appeng.container.implementations.MEMonitorableContainer;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.CraftingMatrixSlot;
import appeng.container.slot.FakeCraftingMatrixSlot;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.SwitchGuisPacket;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.integration.abstraction.JEIFacade;
import appeng.parts.reporting.AbstractTerminalPart;
import appeng.tile.misc.SecurityStationBlockEntity;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBaseMEScreen<T>
implements ISortSource, IConfigManagerHost {
private static int craftingGridOffsetX;
private static int craftingGridOffsetY;
private static String memoryText = "";
private final ItemRepo repo;
private final int offsetX = 9;
private final int lowerTextureOffset = 0;
private final IConfigManager configSrc;
private final boolean viewCell;
private final ItemStack[] myCurrentViewCells = new ItemStack[5];
private TabButton craftingStatusBtn;
private AETextField searchField;
private GuiText myName;
private int perRow = 9;
private int reservedSpace = 0;
private boolean customSortOrder = true;
private int rows = 0;
private int maxRows = Integer.MAX_VALUE;
private int standardSize;
private SettingToggleButton<ViewItems> viewModeToggle;
private SettingToggleButton<SortOrder> sortByToggle;
private SettingToggleButton<SortDir> sortDirToggle;
private boolean isAutoFocus = false;
private int currentMouseX = 0;
private int currentMouseY = 0;
public MEMonitorableScreen(T container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
final Scrollbar scrollbar = new Scrollbar();
this.setScrollBar(scrollbar);
this.repo = new ItemRepo(scrollbar, this);
setScrollBar();
this.xSize = 185;
this.ySize = 204;
Object te = container.getTarget();
if (te instanceof IViewCellStorage) {
this.xSize += 33;
}
this.standardSize = this.xSize;
this.configSrc = ((IConfigurableObject) this.container).getConfigManager();
this.container.setGui(this);
this.viewCell = te instanceof IViewCellStorage;
if (te instanceof SecurityStationBlockEntity) {
this.myName = GuiText.Security;
} else if (te instanceof WirelessTerminalGuiObject) {
this.myName = GuiText.WirelessTerminal;
} else if (te instanceof IPortableCell) {
this.myName = GuiText.PortableCell;
} else if (te instanceof IMEChest) {
this.myName = GuiText.Chest;
} else if (te instanceof AbstractTerminalPart) {
this.myName = GuiText.Terminal;
} else {
throw new IllegalArgumentException("Invalid GUI target given: " + te);
}
}
public void postUpdate(final List<IAEItemStack> list) {
for (final IAEItemStack is : list) {
this.repo.postUpdate(is);
}
this.repo.updateView();
this.setScrollBar();
}
private void setScrollBar() {
this.getScrollBar().setTop(18).setLeft(175).setHeight(this.rows * 18 - 2);
this.getScrollBar().setRange(0, (this.repo.size() + this.perRow - 1) / this.perRow - this.rows,
Math.max(1, this.rows / 6));
}
private void showCraftingStatus() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(CraftingStatusContainer.TYPE));
}
@Override
public void init() {
getMinecraft().keyboardListener.enableRepeatEvents(true);
this.maxRows = this.getMaxRows();
TerminalStyle terminalStyle = AEConfig.instance().getTerminalStyle();
if (terminalStyle != TerminalStyle.FULL) {
this.perRow = 9;
} else {
this.perRow = 9 + ((this.width - this.standardSize) / 18);
}
this.xSize = this.standardSize + ((this.perRow - 9) * 18);
final int magicNumber = 114 + 1;
final int extraSpace = this.height - magicNumber - this.reservedSpace;
this.rows = extraSpace / 18;
if (this.rows > this.maxRows) {
this.rows = this.maxRows;
}
if (this.rows < 3) {
this.rows = 3;
}
// Size the container according to the number of rows we decided to have
this.ySize = magicNumber + this.rows * 18 + this.reservedSpace;
this.getMeSlots().clear();
for (int y = 0; y < this.rows; y++) {
for (int x = 0; x < this.perRow; x++) {
this.getMeSlots()
.add(new InternalSlotME(this.repo, x + y * this.perRow, this.offsetX + x * 18, 18 + y * 18));
}
}
super.init();
// full size : 204
// extra slots : 72
// slot 18
int offset = this.guiTop + 8;
if (this.customSortOrder) {
this.sortByToggle = this.addButton(new SettingToggleButton<>(this.guiLeft - 18, offset, Settings.SORT_BY,
getSortBy(), Platform::isSortOrderAvailable, this::toggleServerSetting));
offset += 20;
}
if (this.viewCell || this instanceof WirelessTermScreen) {
this.viewModeToggle = this.addButton(new SettingToggleButton<>(this.guiLeft - 18, offset,
Settings.VIEW_MODE, getSortDisplay(), this::toggleServerSetting));
offset += 20;
}
this.addButton(this.sortDirToggle = new SettingToggleButton<>(this.guiLeft - 18, offset,
Settings.SORT_DIRECTION, getSortDir(), this::toggleServerSetting));
offset += 20;
SearchBoxMode searchMode = AEConfig.instance().getTerminalSearchMode();
this.addButton(new SettingToggleButton<>(this.guiLeft - 18, offset, Settings.SEARCH_MODE, searchMode,
Platform::isSearchModeAvailable, this::toggleTerminalSearchMode));
offset += 20;
if (!(this instanceof MEPortableCellScreen) || this instanceof WirelessTermScreen) {
this.addButton(new SettingToggleButton<>(this.guiLeft - 18, offset, Settings.TERMINAL_STYLE, terminalStyle,
this::toggleTerminalStyle));
}
this.searchField = new AETextField(this.font, this.guiLeft + Math.max(80, this.offsetX), this.guiTop + 4, 90,
12);
this.searchField.setEnableBackgroundDrawing(false);
this.searchField.setMaxStringLength(25);
this.searchField.setTextColor(0xFFFFFF);
this.searchField.setSelectionColor(0xFF008000);
this.searchField.setVisible(true);
if (this.viewCell || this instanceof WirelessTermScreen) {
this.craftingStatusBtn = this.addButton(new TabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16,
GuiText.CraftingStatus.getLocal(), this.itemRenderer, btn -> showCraftingStatus()));
this.craftingStatusBtn.setHideEdge(13);
}
this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode
|| SearchBoxMode.AUTOSEARCH_KEEP == searchMode || SearchBoxMode.JEI_AUTOSEARCH_KEEP == searchMode;
final boolean isKeepFilter = SearchBoxMode.AUTOSEARCH_KEEP == searchMode
|| SearchBoxMode.JEI_AUTOSEARCH_KEEP == searchMode || SearchBoxMode.MANUAL_SEARCH_KEEP == searchMode
|| SearchBoxMode.JEI_MANUAL_SEARCH_KEEP == searchMode;
final boolean isJEIEnabled = SearchBoxMode.JEI_AUTOSEARCH == searchMode
|| SearchBoxMode.JEI_MANUAL_SEARCH == searchMode;
this.searchField.setFocused2(this.isAutoFocus);
if (isJEIEnabled) {
memoryText = JEIFacade.instance().getSearchText();
}
if (isKeepFilter && memoryText != null && !memoryText.isEmpty()) {
this.searchField.setText(memoryText);
this.searchField.selectAll();
this.repo.setSearchString(memoryText);
this.repo.updateView();
this.setScrollBar();
}
craftingGridOffsetX = Integer.MAX_VALUE;
craftingGridOffsetY = Integer.MAX_VALUE;
for (final Slot s : this.container.inventorySlots) {
if (s instanceof AppEngSlot) {
if (s.xPos < 197) {
this.repositionSlot((AppEngSlot) s);
}
}
if (s instanceof CraftingMatrixSlot || s instanceof FakeCraftingMatrixSlot) {
if (s.xPos > 0 && s.yPos > 0) {
craftingGridOffsetX = Math.min(craftingGridOffsetX, s.xPos);
craftingGridOffsetY = Math.min(craftingGridOffsetY, s.yPos);
}
}
}
craftingGridOffsetX -= 25;
craftingGridOffsetY -= 6;
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(this.myName.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
this.currentMouseX = mouseX;
this.currentMouseY = mouseY;
}
@Override
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
this.repo.setSearchString("");
this.repo.updateView();
this.setScrollBar();
}
return true;
}
return super.mouseClicked(xCoord, yCoord, btn);
}
@Override
public void removed() {
super.removed();
getMinecraft().keyboardListener.enableRepeatEvents(false);
memoryText = this.searchField.getText();
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture(this.getBackground());
final int x_width = 197;
blit(offsetX, offsetY, 0, 0, x_width, 18);
if (this.viewCell || (this instanceof SecurityStationScreen)) {
blit(offsetX + x_width, offsetY, x_width, 0, 46, 128);
}
for (int x = 0; x < this.rows; x++) {
blit(offsetX, offsetY + 18 + x * 18, 0, 18, x_width, 18);
}
blit(offsetX, offsetY + 16 + this.rows * 18 + this.lowerTextureOffset, 0, 106 - 18 - 18, x_width,
99 + this.reservedSpace - this.lowerTextureOffset);
if (this.viewCell) {
boolean update = false;
for (int i = 0; i < 5; i++) {
if (this.myCurrentViewCells[i] != this.container.getCellViewSlot(i).getStack()) {
update = true;
this.myCurrentViewCells[i] = this.container.getCellViewSlot(i).getStack();
}
}
if (update) {
this.repo.setViewCell(this.myCurrentViewCells);
}
}
if (this.searchField != null) {
this.searchField.render(mouseX, mouseY, partialTicks);
}
}
protected String getBackground() {
return "guis/terminal.png";
}
@Override
protected boolean isPowered() {
return this.repo.hasPower();
}
int getMaxRows() {
return AEConfig.instance().getTerminalStyle() == TerminalStyle.SMALL ? 6 : Integer.MAX_VALUE;
}
protected void repositionSlot(final AppEngSlot s) {
s.yPos = s.getY() + this.ySize - 78 - 5;
}
@Override
public boolean charTyped(char character, int p_charTyped_2_) {
if (character == ' ' && this.searchField.getText().isEmpty()) {
return true;
}
if (this.isAutoFocus && !this.searchField.isFocused() && isHovered()) {
this.searchField.setFocused2(true);
}
if (this.searchField.isFocused() && this.searchField.charTyped(character, p_charTyped_2_)) {
this.repo.setSearchString(this.searchField.getText());
this.repo.updateView();
this.setScrollBar();
return true;
}
return false;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
InputUtil.Key input = InputMappings.getInputByCode(keyCode, scanCode);
if (keyCode != GLFW.GLFW_KEY_ESCAPE && !this.checkHotbarKeys(input)) {
if (AppEng.instance().isActionKey(ActionKey.TOGGLE_FOCUS, input)) {
this.searchField.setFocused2(!this.searchField.isFocused());
return true;
}
if (!this.searchField.isFocused() && this.isAutoFocus && isHovered()) {
this.searchField.setFocused2(true);
}
if (this.searchField.isFocused()) {
if (keyCode == GLFW.GLFW_KEY_ENTER) {
this.searchField.setFocused2(false);
return true;
}
if (this.searchField.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
this.repo.setSearchString(this.searchField.getText());
this.repo.updateView();
this.setScrollBar();
}
// We need to swallow key presses if the field is focused because typing 'e'
// would otherwise close
// the screen
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
private boolean isHovered() {
return isPointInRegion(0, 0, this.xSize, this.ySize, currentMouseX, currentMouseY);
}
@Override
public void tick() {
this.repo.setPower(this.container.isPowered());
super.tick();
}
@Override
public SortOrder getSortBy() {
return (SortOrder) this.configSrc.getSetting(Settings.SORT_BY);
}
@Override
public SortDir getSortDir() {
return (SortDir) this.configSrc.getSetting(Settings.SORT_DIRECTION);
}
@Override
public ViewItems getSortDisplay() {
return (ViewItems) this.configSrc.getSetting(Settings.VIEW_MODE);
}
@Override
public void updateSetting(final IConfigManager manager, final Settings settingName, final Enum<?> newValue) {
if (this.sortByToggle != null) {
this.sortByToggle.set(getSortBy());
}
if (this.sortDirToggle != null) {
this.sortDirToggle.set(getSortDir());
}
if (this.viewModeToggle != null) {
this.viewModeToggle.set(getSortDisplay());
}
this.repo.updateView();
}
int getReservedSpace() {
return this.reservedSpace;
}
void setReservedSpace(final int reservedSpace) {
this.reservedSpace = reservedSpace;
}
public boolean isCustomSortOrder() {
return this.customSortOrder;
}
void setCustomSortOrder(final boolean customSortOrder) {
this.customSortOrder = customSortOrder;
}
public int getStandardSize() {
return this.standardSize;
}
void setStandardSize(final int standardSize) {
this.standardSize = standardSize;
}
private void toggleTerminalSearchMode(SettingToggleButton<SearchBoxMode> btn, boolean backwards) {
SearchBoxMode next = btn.getNextValue(backwards);
AEConfig.instance().setTerminalSearchMode(next);
btn.set(next);
this.reinitalize();
}
private void toggleTerminalStyle(SettingToggleButton<TerminalStyle> btn, boolean backwards) {
TerminalStyle next = btn.getNextValue(backwards);
AEConfig.instance().setTerminalStyle(next);
btn.set(next);
this.reinitalize();
}
private <S extends Enum<S>> void toggleServerSetting(SettingToggleButton<S> btn, boolean backwards) {
S next = btn.getNextValue(backwards);
NetworkHandler.instance().sendToServer(new ConfigValuePacket(btn.getSetting().name(), next.name()));
btn.set(next);
}
private void reinitalize() {
this.children.removeAll(this.buttons);
this.buttons.clear();
this.init();
}
}
@@ -0,0 +1,37 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.container.implementations.MEPortableCellContainer;
public class MEPortableCellScreen extends MEMonitorableScreen<MEPortableCellContainer> {
public MEPortableCellScreen(MEPortableCellContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
}
@Override
int getMaxRows() {
return 3;
}
}
@@ -0,0 +1,80 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.client.gui.widgets.ProgressBar;
import appeng.client.gui.widgets.ProgressBar.Direction;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.container.implementations.MolecularAssemblerContainer;
import appeng.core.localization.GuiText;
public class MolecularAssemblerScreen extends UpgradeableScreen<MolecularAssemblerContainer> {
private ProgressBar pb;
public MolecularAssemblerScreen(MolecularAssemblerContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.ySize = 197;
}
@Override
public void init() {
super.init();
this.pb = new ProgressBar(this.container, "guis/molecular_assembler.png", 139, 36, 148, 201, 6, 18,
Direction.VERTICAL);
this.addButton(this.pb);
}
@Override
protected void addButtons() {
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8,
Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE);
addButton(this.redstoneMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.pb.setFullMsg(this.container.getCurrentProgress() + "%");
super.drawFG(offsetX, offsetY, mouseX, mouseY);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.pb.x = 148 + this.guiLeft;
this.pb.y = 48 + this.guiTop;
super.drawBG(offsetX, offsetY, mouseX, mouseY, partialTicks);
}
@Override
protected String getBackground() {
return "guis/molecular_assembler.png";
}
@Override
protected GuiText getName() {
return GuiText.MolecularAssembler;
}
}
@@ -0,0 +1,248 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import java.util.List;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.CommonButtons;
import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.ItemRepo;
import appeng.client.me.SlotME;
import appeng.container.implementations.NetworkStatusContainer;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
public class NetworkStatusScreen extends AEBaseScreen<NetworkStatusContainer> implements ISortSource {
private final ItemRepo repo;
private final int rows = 4;
private int tooltip = -1;
public NetworkStatusScreen(NetworkStatusContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
final Scrollbar scrollbar = new Scrollbar();
this.setScrollBar(scrollbar);
this.repo = new ItemRepo(scrollbar, this);
this.ySize = 153;
this.xSize = 195;
this.repo.setRowSize(5);
}
@Override
public void init() {
super.init();
this.addButton(CommonButtons.togglePowerUnit(this.guiLeft - 18, this.guiTop + 8));
}
@Override
public void render(final int mouseX, final int mouseY, final float btn) {
final int gx = (this.width - this.xSize) / 2;
final int gy = (this.height - this.ySize) / 2;
this.tooltip = -1;
int y = 0;
int x = 0;
for (int z = 0; z <= 4 * 5; z++) {
final int minX = gx + 14 + x * 31;
final int minY = gy + 41 + y * 18;
if (minX < mouseX && minX + 28 > mouseX) {
if (minY < mouseY && minY + 20 > mouseY) {
this.tooltip = z;
break;
}
}
x++;
if (x > 4) {
y++;
x = 0;
}
}
super.render(mouseX, mouseY, btn);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(GuiText.NetworkDetails.getLocal(), 8, 6, 4210752);
this.font.drawString(
GuiText.StoredPower.getLocal() + ": " + Platform.formatPowerLong(container.getCurrentPower(), false),
13, 16, 4210752);
this.font.drawString(
GuiText.MaxPower.getLocal() + ": " + Platform.formatPowerLong(container.getMaxPower(), false), 13, 26,
4210752);
this.font.drawString(GuiText.PowerInputRate.getLocal() + ": "
+ Platform.formatPowerLong(container.getAverageAddition(), true), 13, 143 - 10, 4210752);
this.font.drawString(
GuiText.PowerUsageRate.getLocal() + ": " + Platform.formatPowerLong(container.getPowerUsage(), true),
13, 143 - 20, 4210752);
final int sectionLength = 30;
int x = 0;
int y = 0;
final int xo = 12;
final int yo = 42;
final int viewStart = 0;// myScrollBar.getCurrentScroll() * 5;
final int viewEnd = viewStart + 5 * 4;
String toolTip = "";
int toolPosX = 0;
int toolPosY = 0;
for (int z = viewStart; z < Math.min(viewEnd, this.repo.size()); z++) {
final IAEItemStack refStack = this.repo.getReferenceItem(z);
if (refStack != null) {
RenderSystem.pushMatrix();
RenderSystem.scalef(0.5f, 0.5f, 0.5f);
String str = Long.toString(refStack.getStackSize());
if (refStack.getStackSize() >= 10000) {
str = Long.toString(refStack.getStackSize() / 1000) + 'k';
}
final int w = this.font.getStringWidth(str);
this.font.drawString(str, (int) ((x * sectionLength + xo + sectionLength - 19 - (w * 0.5)) * 2),
(y * 18 + yo + 6) * 2, 4210752);
RenderSystem.popMatrix();
final int posX = x * sectionLength + xo + sectionLength - 18;
final int posY = y * 18 + yo;
if (this.tooltip == z - viewStart) {
toolTip = Platform.getItemDisplayName(refStack).getFormattedText();
toolTip += ('\n' + GuiText.Installed.getLocal() + ": " + (refStack.getStackSize()));
if (refStack.getCountRequestable() > 0) {
toolTip += ('\n' + GuiText.EnergyDrain.getLocal() + ": "
+ Platform.formatPowerLong(refStack.getCountRequestable(), true));
}
toolPosX = x * sectionLength + xo + sectionLength - 8;
toolPosY = y * 18 + yo;
}
this.drawItem(posX, posY, refStack.asItemStackRepresentation());
x++;
if (x > 4) {
y++;
x = 0;
}
}
}
if (this.tooltip >= 0 && toolTip.length() > 0) {
this.drawTooltip(toolPosX, toolPosY + 10, toolTip);
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/networkstatus.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
public void postUpdate(final List<IAEItemStack> list) {
this.repo.clear();
for (final IAEItemStack is : list) {
this.repo.postUpdate(is);
}
this.repo.updateView();
this.setScrollBar();
}
private void setScrollBar() {
final int size = this.repo.size();
this.getScrollBar().setTop(39).setLeft(175).setHeight(78);
this.getScrollBar().setRange(0, (size + 4) / 5 - this.rows, 1);
}
@Override
protected void renderTooltip(final ItemStack stack, final int x, final int y) {
final Slot s = this.getSlot(x, y);
if (s instanceof SlotME && !stack.isEmpty()) {
IAEItemStack myStack = null;
try {
final SlotME theSlotField = (SlotME) s;
myStack = theSlotField.getAEStack();
} catch (final Throwable ignore) {
}
if (myStack != null) {
List<String> currentToolTip = getTooltipFromItem(stack);
while (currentToolTip.size() > 1) {
currentToolTip.remove(1);
}
currentToolTip.add(GuiText.Installed.getLocal() + ": " + (myStack.getStackSize()));
currentToolTip.add(GuiText.EnergyDrain.getLocal() + ": "
+ Platform.formatPowerLong(myStack.getCountRequestable(), true));
this.drawTooltip(x, y, currentToolTip);
}
}
super.renderTooltip(stack, x, y);
}
@Override
public SortOrder getSortBy() {
return SortOrder.NAME;
}
@Override
public SortDir getSortDir() {
return SortDir.ASCENDING;
}
@Override
public ViewItems getSortDisplay() {
return ViewItems.ALL;
}
}
@@ -0,0 +1,71 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.ToggleButton;
import appeng.container.implementations.NetworkToolContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class NetworkToolScreen extends AEBaseScreen<NetworkToolContainer> {
private ToggleButton tFacades;
public NetworkToolScreen(NetworkToolContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 166;
}
@Override
public void init() {
super.init();
this.tFacades = new ToggleButton(this.guiLeft - 18, this.guiTop + 8, 23, 22,
GuiText.TransparentFacades.getLocal(), GuiText.TransparentFacadesHint.getLocal(),
btn -> toggleFacades());
this.addButton(this.tFacades);
}
private void toggleFacades() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("NetworkTool", "Toggle"));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
if (this.tFacades != null) {
this.tFacades.setState(container.isFacadeMode());
}
this.font.drawString(this.getGuiDisplayName(GuiText.NetworkTool.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/toolbox.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,147 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import appeng.api.config.ActionItems;
import appeng.client.gui.widgets.ActionButton;
import appeng.client.gui.widgets.TabButton;
import appeng.container.implementations.PatternTermContainer;
import appeng.container.slot.AppEngSlot;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class PatternTermScreen extends MEMonitorableScreen<PatternTermContainer> {
private static final String BACKGROUND_CRAFTING_MODE = "guis/pattern.png";
private static final String BACKGROUND_PROCESSING_MODE = "guis/pattern2.png";
private static final String SUBSITUTION_DISABLE = "0";
private static final String SUBSITUTION_ENABLE = "1";
private static final String CRAFTMODE_CRFTING = "1";
private static final String CRAFTMODE_PROCESSING = "0";
private TabButton tabCraftButton;
private TabButton tabProcessButton;
private ActionButton substitutionsEnabledBtn;
private ActionButton substitutionsDisabledBtn;
public PatternTermScreen(PatternTermContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.setReservedSpace(81);
}
@Override
public void init() {
super.init();
this.tabCraftButton = new TabButton(this.guiLeft + 173, this.guiTop + this.ySize - 177,
new ItemStack(Blocks.CRAFTING_TABLE), GuiText.CraftingPattern.getLocal(), this.itemRenderer,
btn -> toggleCraftMode(CRAFTMODE_PROCESSING));
this.addButton(this.tabCraftButton);
this.tabProcessButton = new TabButton(this.guiLeft + 173, this.guiTop + this.ySize - 177,
new ItemStack(Blocks.FURNACE), GuiText.ProcessingPattern.getLocal(), this.itemRenderer,
btn -> toggleCraftMode(CRAFTMODE_CRFTING));
this.addButton(this.tabProcessButton);
this.substitutionsEnabledBtn = new ActionButton(this.guiLeft + 84, this.guiTop + this.ySize - 163,
ActionItems.ENABLE_SUBSTITUTION, act -> toggleSubstitutions(SUBSITUTION_DISABLE));
this.substitutionsEnabledBtn.setHalfSize(true);
this.addButton(this.substitutionsEnabledBtn);
this.substitutionsDisabledBtn = new ActionButton(this.guiLeft + 84, this.guiTop + this.ySize - 163,
ActionItems.DISABLE_SUBSTITUTION, act -> toggleSubstitutions(SUBSITUTION_ENABLE));
this.substitutionsDisabledBtn.setHalfSize(true);
this.addButton(this.substitutionsDisabledBtn);
ActionButton clearBtn = new ActionButton(this.guiLeft + 74, this.guiTop + this.ySize - 163, ActionItems.CLOSE,
act -> clear());
clearBtn.setHalfSize(true);
this.addButton(clearBtn);
ActionButton encodeBtn = new ActionButton(this.guiLeft + 147, this.guiTop + this.ySize - 142,
ActionItems.ENCODE, act -> encode());
this.addButton(encodeBtn);
}
private void toggleCraftMode(String mode) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PatternTerminal.CraftMode", mode));
}
private void toggleSubstitutions(String mode) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PatternTerminal.Substitute", mode));
}
private void encode() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PatternTerminal.Encode", "1"));
}
private void clear() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PatternTerminal.Clear", "1"));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
if (this.container.isCraftingMode()) {
this.tabCraftButton.visible = true;
this.tabProcessButton.visible = false;
if (this.container.substitute) {
this.substitutionsEnabledBtn.visible = true;
this.substitutionsDisabledBtn.visible = false;
} else {
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = true;
}
} else {
this.tabCraftButton.visible = false;
this.tabProcessButton.visible = true;
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = false;
}
super.drawFG(offsetX, offsetY, mouseX, mouseY);
this.font.drawString(GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.getReservedSpace(),
4210752);
}
@Override
protected String getBackground() {
if (this.container.isCraftingMode()) {
return BACKGROUND_CRAFTING_MODE;
}
return BACKGROUND_PROCESSING_MODE;
}
@Override
protected void repositionSlot(final AppEngSlot s) {
final int offsetPlayerSide = s.isPlayerSide() ? 5 : 3;
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
}
}
@@ -0,0 +1,176 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.NumberBox;
import appeng.container.implementations.PriorityContainer;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
private final AESubScreen subGui;
private NumberBox priority;
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.subGui = new AESubScreen(this, container.getPriorityHost());
}
@Override
public void init() {
super.init();
final int a = AEConfig.instance().priorityByStacksAmounts(0);
final int b = AEConfig.instance().priorityByStacksAmounts(1);
final int c = AEConfig.instance().priorityByStacksAmounts(2);
final int d = AEConfig.instance().priorityByStacksAmounts(3);
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 32, 22, 20, "+" + a, btn -> addQty(a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 32, 28, 20, "+" + b, btn -> addQty(b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 32, 32, 20, "+" + c, btn -> addQty(c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 32, 38, 20, "+" + d, btn -> addQty(d)));
this.addButton(new Button(this.guiLeft + 20, this.guiTop + 69, 22, 20, "-" + a, btn -> addQty(-a)));
this.addButton(new Button(this.guiLeft + 48, this.guiTop + 69, 28, 20, "-" + b, btn -> addQty(-b)));
this.addButton(new Button(this.guiLeft + 82, this.guiTop + 69, 32, 20, "-" + c, btn -> addQty(-c)));
this.addButton(new Button(this.guiLeft + 120, this.guiTop + 69, 38, 20, "-" + d, btn -> addQty(-d)));
this.subGui.addBackButton(this::addButton, 154, 0);
this.priority = new NumberBox(this.font, this.guiLeft + 62, this.guiTop + 57, 59, this.font.FONT_HEIGHT,
Long.class);
this.priority.setEnableBackgroundDrawing(false);
this.priority.setMaxStringLength(16);
this.priority.setTextColor(0xFFFFFF);
this.priority.setVisible(true);
this.priority.setFocused2(true);
container.setTextField(this.priority);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(GuiText.Priority.getLocal(), 8, 6, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture(getBackground());
blit(offsetX, offsetY, 0, 0, this.xSize, this.ySize);
this.priority.render(mouseX, mouseY, partialTicks);
}
private void addQty(final int i) {
try {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
long result = Long.parseLong(out);
result += i;
this.priority.setText(out = Long.toString(result));
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
} catch (final NumberFormatException e) {
// nope..
this.priority.setText("0");
}
}
@Override
public boolean charTyped(char character, int key) {
if (priority.charTyped(character, key)) {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
return true;
}
return false;
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if ((keyCode == 211 || keyCode == 205 || keyCode == 203 || keyCode == 14)
&& this.priority.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
String out = this.priority.getText();
boolean fixed = false;
while (out.startsWith("0") && out.length() > 1) {
out = out.substring(1);
fixed = true;
}
if (fixed) {
this.priority.setText(out);
}
if (out.isEmpty()) {
out = "0";
}
NetworkHandler.instance().sendToServer(new ConfigValuePacket("PriorityHost.Priority", out));
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
protected String getBackground() {
return "guis/priority.png";
}
}
@@ -0,0 +1,47 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.container.implementations.QNBContainer;
import appeng.core.localization.GuiText;
public class QNBScreen extends AEBaseScreen<QNBContainer> {
public QNBScreen(QNBContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 166;
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.QuantumLinkChamber.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/chest.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,117 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.client.util.InputUtil;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseScreen;
import appeng.container.implementations.QuartzKnifeContainer;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class QuartzKnifeScreen extends AEBaseScreen<QuartzKnifeContainer> {
private TextFieldWidget name;
public QuartzKnifeScreen(QuartzKnifeContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 184;
}
@Override
public void init() {
super.init();
this.name = new TextFieldWidget(this.font, this.guiLeft + 24, this.guiTop + 32, 79, this.font.FONT_HEIGHT, "");
this.name.setEnableBackgroundDrawing(false);
this.name.setMaxStringLength(32);
this.name.setTextColor(0xFFFFFF);
this.name.setVisible(true);
this.name.setFocused2(true);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.QuartzCuttingKnife.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/quartzknife.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
this.name.render(mouseX, mouseY, partialTicks);
}
@Override
public boolean charTyped(char character, int key) {
if (this.name.isFocused() && this.name.charTyped(character, key)) {
final String Out = this.name.getText();
container.setName(Out);
NetworkHandler.instance().sendToServer(new ConfigValuePacket("QuartzKnife.Name", Out));
return true;
}
return super.charTyped(character, key);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
InputUtil.Key input = InputMappings.getInputByCode(keyCode, scanCode);
if (keyCode != GLFW.GLFW_KEY_ESCAPE && !this.checkHotbarKeys(input)) {
if (AppEng.instance().isActionKey(ActionKey.TOGGLE_FOCUS, input)) {
this.name.setFocused2(!this.name.isFocused());
return true;
}
if (this.name.isFocused()) {
if (keyCode == GLFW.GLFW_KEY_ENTER) {
this.name.setFocused2(false);
return true;
}
if (this.name.keyPressed(keyCode, scanCode, p_keyPressed_3_)) {
final String Out = this.name.getText();
container.setName(Out);
NetworkHandler.instance().sendToServer(new ConfigValuePacket("QuartzKnife.Name", Out));
return true;
}
// We need to swallow key presses if the field is focused because typing 'e'
// would otherwise close
// the screen
return true;
}
}
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.SortOrder;
import appeng.client.gui.widgets.ToggleButton;
import appeng.container.implementations.SecurityStationContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class SecurityStationScreen extends MEMonitorableScreen<SecurityStationContainer> {
private ToggleButton inject;
private ToggleButton extract;
private ToggleButton craft;
private ToggleButton build;
private ToggleButton security;
public SecurityStationScreen(SecurityStationContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.setCustomSortOrder(false);
this.setReservedSpace(33);
// increase size so that the slot is over the gui.
this.xSize += 56;
this.setStandardSize(this.xSize);
}
private void toggleOption(SecurityPermissions permission) {
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("TileSecurityStation.ToggleOption", permission.name()));
}
@Override
public void init() {
super.init();
final int top = this.guiTop + this.ySize - 116;
this.inject = this.addButton(new ToggleButton(this.guiLeft + 56, top, 11 * 16, 12 * 16,
SecurityPermissions.INJECT.getTranslatedName(), SecurityPermissions.INJECT.getTranslatedTip(),
btn -> toggleOption(SecurityPermissions.INJECT)));
this.extract = this.addButton(new ToggleButton(this.guiLeft + 56 + 18, top, 11 * 16 + 1, 12 * 16 + 1,
SecurityPermissions.EXTRACT.getTranslatedName(), SecurityPermissions.EXTRACT.getTranslatedTip(),
btn -> toggleOption(SecurityPermissions.EXTRACT)));
this.craft = this.addButton(new ToggleButton(this.guiLeft + 56 + 18 * 2, top, 11 * 16 + 2, 12 * 16 + 2,
SecurityPermissions.CRAFT.getTranslatedName(), SecurityPermissions.CRAFT.getTranslatedTip(),
btn -> toggleOption(SecurityPermissions.CRAFT)));
this.build = this.addButton(new ToggleButton(this.guiLeft + 56 + 18 * 3, top, 11 * 16 + 3, 12 * 16 + 3,
SecurityPermissions.BUILD.getTranslatedName(), SecurityPermissions.BUILD.getTranslatedTip(),
btn -> toggleOption(SecurityPermissions.BUILD)));
this.security = this.addButton(new ToggleButton(this.guiLeft + 56 + 18 * 4, top, 11 * 16 + 4, 12 * 16 + 4,
SecurityPermissions.SECURITY.getTranslatedName(), SecurityPermissions.SECURITY.getTranslatedTip(),
btn -> toggleOption(SecurityPermissions.SECURITY)));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
super.drawFG(offsetX, offsetY, mouseX, mouseY);
this.font.drawString(GuiText.SecurityCardEditor.getLocal(), 8, this.ySize - 96 + 1 - this.getReservedSpace(),
4210752);
}
@Override
protected String getBackground() {
this.inject.setState((container.getPermissionMode() & (1 << SecurityPermissions.INJECT.ordinal())) > 0);
this.extract.setState((container.getPermissionMode() & (1 << SecurityPermissions.EXTRACT.ordinal())) > 0);
this.craft.setState((container.getPermissionMode() & (1 << SecurityPermissions.CRAFT.ordinal())) > 0);
this.build.setState((container.getPermissionMode() & (1 << SecurityPermissions.BUILD.ordinal())) > 0);
this.security.setState((container.getPermissionMode() & (1 << SecurityPermissions.SECURITY.ordinal())) > 0);
return "guis/security_station.png";
}
@Override
public SortOrder getSortBy() {
return SortOrder.NAME;
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.Identifier;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.container.implementations.SkyChestContainer;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
public class SkyChestScreen extends AEBaseScreen<SkyChestContainer> {
private static final Identifier TEXTURE = new Identifier(AppEng.MOD_ID, "textures/guis/skychest.png");
public SkyChestScreen(SkyChestContainer container, PlayerInventory playerInv, Text title) {
super(container, playerInv, title);
this.ySize = 195;
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.SkyChest.getLocal()), 8, 8, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 2, 4210752);
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
bindTexture(TEXTURE);
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, 0);
}
@Override
protected boolean enableSpaceClicking() {
// NOTE: previously checked for inventory tweaks mod (which no longer exists)
return true;
}
}
@@ -0,0 +1,76 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.CommonButtons;
import appeng.container.implementations.SpatialIOPortContainer;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
public class SpatialIOPortScreen extends AEBaseScreen<SpatialIOPortContainer> {
public SpatialIOPortScreen(SpatialIOPortContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.ySize = 199;
}
@Override
public void init() {
super.init();
this.addButton(CommonButtons.togglePowerUnit(this.guiLeft - 18, this.guiTop + 8));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(GuiText.StoredPower.getLocal() + ": "
+ Platform.formatPowerLong(this.container.getCurrentPower(), false), 13, 21, 4210752);
this.font.drawString(
GuiText.MaxPower.getLocal() + ": " + Platform.formatPowerLong(this.container.getMaxPower(), false), 13,
31, 4210752);
this.font.drawString(GuiText.RequiredPower.getLocal() + ": "
+ Platform.formatPowerLong(this.container.getRequiredPower(), false), 13, 73, 4210752);
this.font.drawString(
GuiText.Efficiency.getLocal() + ": " + (((float) this.container.getEfficency()) / 100) + '%', 13, 83,
4210752);
this.font.drawString(this.getGuiDisplayName(GuiText.SpatialIOPort.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96, 4210752);
if (this.container.xSize != 0 && this.container.ySize != 0 && this.container.zSize != 0) {
final String text = GuiText.SCSSize.getLocal() + ": " + this.container.xSize + "x" + this.container.ySize
+ "x" + this.container.zSize;
this.font.drawString(text, 13, 93, 4210752);
} else {
this.font.drawString(GuiText.SCSSize.getLocal() + ": " + GuiText.SCSInvalid.getLocal(), 13, 93, 4210752);
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/spatialio.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,104 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.config.AccessRestriction;
import appeng.api.config.ActionItems;
import appeng.api.config.FuzzyMode;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.client.gui.widgets.ActionButton;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton;
import appeng.container.implementations.PriorityContainer;
import appeng.container.implementations.StorageBusContainer;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.SwitchGuisPacket;
public class StorageBusScreen extends UpgradeableScreen<StorageBusContainer> {
private SettingToggleButton<AccessRestriction> rwMode;
private SettingToggleButton<StorageFilter> storageFilter;
public StorageBusScreen(StorageBusContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 251;
}
@Override
protected void addButtons() {
addButton(new ActionButton(this.guiLeft - 18, this.guiTop + 8, ActionItems.CLOSE, btn -> clear()));
addButton(new ActionButton(this.guiLeft - 18, this.guiTop + 28, ActionItems.WRENCH, btn -> partition()));
this.rwMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48, Settings.ACCESS,
AccessRestriction.READ_WRITE);
this.storageFilter = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 68,
Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY);
this.fuzzyMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 88, Settings.FUZZY_MODE,
FuzzyMode.IGNORE_ALL);
this.addButton(new TabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(),
this.itemRenderer, btn -> openPriorityGui()));
this.addButton(this.storageFilter);
this.addButton(this.fuzzyMode);
this.addButton(this.rwMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.StorageBus.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
if (this.fuzzyMode != null) {
this.fuzzyMode.set(this.cvb.getFuzzyMode());
}
if (this.storageFilter != null) {
this.storageFilter.set(((StorageBusContainer) this.cvb).getStorageFilter());
}
if (this.rwMode != null) {
this.rwMode.set(((StorageBusContainer) this.cvb).getReadWriteMode());
}
}
@Override
protected String getBackground() {
return "guis/storagebus.png";
}
private void partition() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("StorageBus.Action", "Partition"));
}
private void clear() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("StorageBus.Action", "Clear"));
}
private void openPriorityGui() {
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(PriorityContainer.TYPE));
}
}
@@ -0,0 +1,150 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.api.config.FuzzyMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SchedulingMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.implementations.IUpgradeableHost;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.UpgradeableContainer;
import appeng.core.localization.GuiText;
import appeng.parts.automation.ExportBusPart;
import appeng.parts.automation.ImportBusPart;
public class UpgradeableScreen<T extends UpgradeableContainer> extends AEBaseScreen<T> {
protected final UpgradeableContainer cvb;
protected final IUpgradeableHost bc;
protected SettingToggleButton<RedstoneMode> redstoneMode;
protected SettingToggleButton<FuzzyMode> fuzzyMode;
protected SettingToggleButton<YesNo> craftMode;
protected SettingToggleButton<SchedulingMode> schedulingMode;
public UpgradeableScreen(T container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.cvb = container;
this.bc = (IUpgradeableHost) container.getTarget();
this.xSize = this.hasToolbox() ? 246 : 211;
this.ySize = 184;
}
protected boolean hasToolbox() {
return (this.container).hasToolbox();
}
@Override
public void init() {
super.init();
this.addButtons();
}
protected void addButtons() {
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 8,
Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE);
addButton(this.redstoneMode);
this.fuzzyMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28, Settings.FUZZY_MODE,
FuzzyMode.IGNORE_ALL);
addButton(this.fuzzyMode);
this.craftMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 48, Settings.CRAFT_ONLY,
YesNo.NO);
addButton(this.craftMode);
this.schedulingMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 68,
Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT);
addButton(this.schedulingMode);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(this.getName().getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
if (this.redstoneMode != null) {
this.redstoneMode.set(this.cvb.getRedStoneMode());
}
if (this.fuzzyMode != null) {
this.fuzzyMode.set(this.cvb.getFuzzyMode());
}
if (this.craftMode != null) {
this.craftMode.set(this.cvb.getCraftingMode());
}
if (this.schedulingMode != null) {
this.schedulingMode.set(this.cvb.getSchedulingMode());
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.handleButtonVisibility();
this.bindTexture(this.getBackground());
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, 211 - 34, this.ySize, getBlitOffset());
if (this.drawUpgrades()) {
GuiUtils.drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35, 14 + this.cvb.availableUpgrades() * 18,
getBlitOffset());
}
if (this.hasToolbox()) {
GuiUtils.drawTexturedModalRect(offsetX + 178, offsetY + this.ySize - 90, 178, this.ySize - 90, 68, 68,
getBlitOffset());
}
}
protected void handleButtonVisibility() {
if (this.redstoneMode != null) {
this.redstoneMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.REDSTONE) > 0);
}
if (this.fuzzyMode != null) {
this.fuzzyMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.FUZZY) > 0);
}
if (this.craftMode != null) {
this.craftMode.setVisibility(this.bc.getInstalledUpgrades(Upgrades.CRAFTING) > 0);
}
if (this.schedulingMode != null) {
this.schedulingMode.setVisibility(
this.bc.getInstalledUpgrades(Upgrades.CAPACITY) > 0 && this.bc instanceof ExportBusPart);
}
}
protected String getBackground() {
return "guis/bus.png";
}
protected boolean drawUpgrades() {
return true;
}
protected GuiText getName() {
return this.bc instanceof ImportBusPart ? GuiText.ImportBus : GuiText.ExportBus;
}
}
@@ -0,0 +1,77 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.ProgressBar;
import appeng.client.gui.widgets.ProgressBar.Direction;
import appeng.container.implementations.VibrationChamberContainer;
import appeng.core.localization.GuiText;
import appeng.tile.misc.VibrationChamberBlockEntity;
public class VibrationChamberScreen extends AEBaseScreen<VibrationChamberContainer> {
private ProgressBar pb;
public VibrationChamberScreen(VibrationChamberContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
this.ySize = 166;
}
@Override
public void init() {
super.init();
this.pb = new ProgressBar(this.container, "guis/vibchamber.png", 99, 36, 176, 14, 6, 18, Direction.VERTICAL);
this.addButton(this.pb);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.VibrationChamber.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
this.pb.setFullMsg(VibrationChamberBlockEntity.POWER_PER_TICK * this.container.getCurrentProgress()
/ VibrationChamberBlockEntity.DILATION_SCALING + " AE/t");
if (this.container.getRemainingBurnTime() > 0) {
final int i1 = this.container.getRemainingBurnTime() * 12 / 100;
this.bindTexture("guis/vibchamber.png");
RenderSystem.color3f(1, 1, 1);
final int l = -15;
final int k = 25;
GuiUtils.drawTexturedModalRect(k + 56, l + 36 + 12 - i1, 176, 12 - i1, 14, i1 + 2, getBlitOffset());
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/vibchamber.png");
this.pb.x = 99 + this.guiLeft;
this.pb.y = 36 + this.guiTop;
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.CommonButtons;
import appeng.container.implementations.WirelessContainer;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
public class WirelessScreen extends AEBaseScreen<WirelessContainer> {
public WirelessScreen(WirelessContainer container, PlayerInventory playerInventory, Text title) {
super(container, playerInventory, title);
this.ySize = 166;
}
@Override
public void init() {
super.init();
this.addButton(CommonButtons.togglePowerUnit(this.guiLeft - 18, this.guiTop + 8));
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.font.drawString(this.getGuiDisplayName(GuiText.Wireless.getLocal()), 8, 6, 4210752);
this.font.drawString(GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752);
if (container.getRange() > 0) {
final String firstMessage = GuiText.Range.getLocal() + ": " + (container.getRange() / 10.0) + " m";
final String secondMessage = GuiText.PowerUsageRate.getLocal() + ": "
+ Platform.formatPowerLong(container.getDrain(), true);
final int strWidth = Math.max(this.font.getStringWidth(firstMessage),
this.font.getStringWidth(secondMessage));
final int cOffset = (this.xSize / 2) - (strWidth / 2);
this.font.drawString(firstMessage, cOffset, 20, 4210752);
this.font.drawString(secondMessage, cOffset, 20 + 12, 4210752);
}
}
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
this.bindTexture("guis/wireless.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
}
}
@@ -0,0 +1,34 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.implementations;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.container.implementations.MEPortableCellContainer;
// FIXME: Extended from GuiPortableCell before... Why?
public class WirelessTermScreen extends MEMonitorableScreen<MEPortableCellContainer> {
public WirelessTermScreen(MEPortableCellContainer container, PlayerInventory playerInventory,
Text title) {
super(container, playerInventory, title);
}
}
@@ -0,0 +1,152 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
/**
* A modified version of the Minecraft text field. You can initialize it over
* the full element span. The mouse click area is increased to the full element
* subtracted with the defined padding.
*
* The rendering does pay attention to the size of the '_' caret.
*/
public class AETextField extends TextFieldWidget {
private static final int PADDING = 2;
private final int _fontPad;
private int selectionColor = 0xFF00FF00;
/**
* Uses the values to instantiate a padded version of a text field. Pays
* attention to the '_' caret.
*
* @param fontRenderer renderer for the strings
* @param xPos absolute left position
* @param yPos absolute top position
* @param width absolute width
* @param height absolute height
*/
public AETextField(final FontRenderer fontRenderer, final int xPos, final int yPos, final int width,
final int height) {
super(fontRenderer, xPos + PADDING, yPos + PADDING, width - 2 * PADDING - (int) fontRenderer.getCharWidth('_'),
height - 2 * PADDING, "");
this._fontPad = (int) fontRenderer.getCharWidth('_');
}
@Override
public boolean mouseClicked(final double xPos, final double yPos, final int button) {
if (!super.mouseClicked(xPos, yPos, button)) {
return false;
}
final boolean requiresFocus = this.isMouseOver(xPos, yPos);
if (!this.isFocused()) {
this.setFocused2(requiresFocus);
}
return true;
}
public void selectAll() {
this.setCursorPosition(0);
this.setSelectionPos(this.getMaxStringLength());
}
public void setSelectionColor(int color) {
this.selectionColor = color;
}
@Override
public void renderButton(int mouseX, int mouseY, float partial) {
if (this.getVisible()) {
if (this.isFocused()) {
fill(this.x - PADDING + 1, this.y - PADDING + 1, this.x + this.width + this._fontPad + PADDING - 1,
this.y + this.height + PADDING - 1, 0xFF606060);
} else {
fill(this.x - PADDING + 1, this.y - PADDING + 1, this.x + this.width + this._fontPad + PADDING - 1,
this.y + this.height + PADDING - 1, 0xFFA8A8A8);
}
super.renderButton(mouseX, mouseY, partial);
}
}
@Override
public void drawSelectionBox(int startX, int startY, int endX, int endY) {
if (!this.isFocused()) {
return;
}
if (startX < endX) {
int i = startX;
startX = endX;
endX = i;
}
startX += 1;
endX -= 1;
if (startY < endY) {
int j = startY;
startY = endY;
endY = j;
}
startY -= PADDING;
if (endX > this.x + this.width) {
endX = this.x + this.width;
}
if (startX > this.x + this.width) {
startX = this.x + this.width;
}
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
float red = (this.selectionColor >> 16 & 255) / 255.0F;
float blue = (this.selectionColor >> 8 & 255) / 255.0F;
float green = (this.selectionColor & 255) / 255.0F;
float alpha = (this.selectionColor >> 24 & 255) / 255.0F;
RenderSystem.color4f(red, green, blue, alpha);
RenderSystem.disableTexture();
RenderSystem.enableColorLogicOp();
RenderSystem.logicOp(GlStateManager.LogicOp.OR_REVERSE);
bufferbuilder.begin(7, VertexFormats.POSITION);
bufferbuilder.pos(startX, endY, 0.0D).endVertex();
bufferbuilder.pos(endX, endY, 0.0D).endVertex();
bufferbuilder.pos(endX, startY, 0.0D).endVertex();
bufferbuilder.pos(startX, startY, 0.0D).endVertex();
tessellator.draw();
RenderSystem.disableColorLogicOp();
RenderSystem.enableTexture();
RenderSystem.color4f(1, 1, 1, 1);
}
}
@@ -0,0 +1,97 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import appeng.api.config.ActionItems;
import appeng.core.localization.ButtonToolTips;
public class ActionButton extends IconButton implements ITooltip {
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
private final int iconIndex;
public ActionButton(final int x, final int y, final ActionItems action, Consumer<ActionItems> onPress) {
super(x, y, btn -> onPress.accept(action));
ButtonToolTips displayName;
ButtonToolTips displayValue;
switch (action) {
case WRENCH:
iconIndex = 66;
displayName = ButtonToolTips.PartitionStorage;
displayValue = ButtonToolTips.PartitionStorageHint;
break;
case CLOSE:
iconIndex = 6;
displayName = ButtonToolTips.Clear;
displayValue = ButtonToolTips.ClearSettings;
break;
case STASH:
iconIndex = 6;
displayName = ButtonToolTips.Stash;
displayValue = ButtonToolTips.StashDesc;
break;
case ENCODE:
iconIndex = 8;
displayName = ButtonToolTips.Encode;
displayValue = ButtonToolTips.EncodeDescription;
break;
case ENABLE_SUBSTITUTION:
iconIndex = 4 + 3 * 16;
displayName = ButtonToolTips.Substitutions;
displayValue = ButtonToolTips.SubstitutionsDescEnabled;
break;
case DISABLE_SUBSTITUTION:
iconIndex = 7 + 3 * 16;
displayName = ButtonToolTips.Substitutions;
displayValue = ButtonToolTips.SubstitutionsDescDisabled;
break;
default:
throw new IllegalArgumentException("Unknown ActionItem: " + action);
}
setMessage(buildMessage(displayName, displayValue));
}
@Override
protected int getIconIndex() {
return iconIndex;
}
private String buildMessage(ButtonToolTips displayName, ButtonToolTips displayValue) {
String name = displayName.getTranslationKey().getString();
String value = displayValue.getTranslationKey().getString();
value = PATTERN_NEW_LINE.matcher(value).replaceAll("\n");
final StringBuilder sb = new StringBuilder(value);
int i = sb.lastIndexOf("\n");
if (i <= 0) {
i = 0;
}
while (i + 30 < sb.length() && (i = sb.lastIndexOf(" ", i + 30)) != -1) {
sb.replace(i, i + 1, "\n");
}
return name + '\n' + sb;
}
}
@@ -0,0 +1,22 @@
package appeng.client.gui.widgets;
import appeng.api.config.PowerUnits;
import appeng.api.config.Settings;
import appeng.core.AEConfig;
public final class CommonButtons {
private CommonButtons() {
}
public static SettingToggleButton<PowerUnits> togglePowerUnit(int x, int y) {
return new SettingToggleButton<>(x, y, Settings.POWER_UNITS, AEConfig.instance().getSelectedPowerUnit(),
CommonButtons::togglePowerUnit);
}
private static void togglePowerUnit(SettingToggleButton<PowerUnits> button, boolean backwards) {
AEConfig.instance().nextPowerUnit(backwards);
button.set(AEConfig.instance().getSelectedPowerUnit());
}
}
@@ -0,0 +1,70 @@
package appeng.client.gui.widgets;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
private final int x;
private final int y;
private final int id;
public CustomSlotWidget(final int id, final int x, final int y) {
this.x = x;
this.y = y;
this.id = id;
}
public int getId() {
return this.id;
}
public boolean canClick(final PlayerEntity player) {
return true;
}
public void slotClicked(final ItemStack clickStack, final int mouseButton) {
}
public abstract void drawContent(final MinecraftClient mc, final int mouseX, final int mouseY, final float partialTicks);
public void drawBackground(int guileft, int guitop, int currentZIndex) {
}
@Override
public String getMessage() {
return null;
}
@Override
public int xPos() {
return this.x;
}
@Override
public int yPos() {
return this.y;
}
@Override
public int getWidth() {
return 16;
}
@Override
public int getHeight() {
return 16;
}
@Override
public boolean isVisible() {
return false;
}
public boolean isSlotEnabled() {
return true;
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
public interface IScrollSource {
int getCurrentScroll();
}
@@ -0,0 +1,31 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
public interface ISortSource {
SortOrder getSortBy();
SortDir getSortDir();
ViewItems getSortDisplay();
}
@@ -0,0 +1,65 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
/**
* AEBaseGui controlled Tooltip Interface.
*/
public interface ITooltip {
/**
* returns the tooltip message.
*
* @return tooltip message
*/
String getMessage();
/**
* x Location for the object that triggers the tooltip.
*
* @return xPosition
*/
int xPos();
/**
* y Location for the object that triggers the tooltip.
*
* @return yPosition
*/
int yPos();
/**
* Width of the object that triggers the tooltip.
*
* @return width
*/
int getWidth();
/**
* Height for the object that triggers the tooltip.
*
* @return height
*/
int getHeight();
/**
* @return true if button being drawn
*/
boolean isVisible();
}
@@ -0,0 +1,130 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.Identifier;
import net.minecraftforge.fml.client.gui.GuiUtils;
public abstract class IconButton extends Button implements ITooltip {
public static final Identifier TEXTURE_STATES = new Identifier("appliedenergistics2",
"textures/guis/states.png");
private boolean halfSize = false;
public IconButton(final int x, final int y, IPressable onPress) {
super(x, y, 16, 16, "", onPress);
}
public void setVisibility(final boolean vis) {
this.visible = vis;
this.active = vis;
}
@Override
public void renderButton(final int mouseX, final int mouseY, float partial) {
MinecraftClient minecraft = MinecraftClient.getInstance();
if (this.visible) {
final int iconIndex = this.getIconIndex();
TextureManager textureManager = minecraft.getTextureManager();
textureManager.bindTexture(TEXTURE_STATES);
RenderSystem.disableDepthTest();
RenderSystem.enableBlend(); // FIXME: This should be the _default_ state, but some vanilla widget disables
// it :|
if (this.halfSize) {
this.width = 8;
this.height = 8;
RenderSystem.pushMatrix();
RenderSystem.translatef(this.x, this.y, 0.0F);
RenderSystem.scalef(0.5f, 0.5f, 0.5f);
if (this.active) {
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
} else {
RenderSystem.color4f(0.5f, 0.5f, 0.5f, 1.0f);
}
final int uv_y = iconIndex / 16;
final int uv_x = iconIndex - uv_y * 16;
GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0);
GuiUtils.drawTexturedModalRect(0, 0, uv_x * 16, uv_y * 16, 16, 16, 0);
RenderSystem.popMatrix();
} else {
if (this.active) {
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
} else {
RenderSystem.color4f(0.5f, 0.5f, 0.5f, 1.0f);
}
final int uv_y = iconIndex / 16;
final int uv_x = iconIndex - uv_y * 16;
GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0);
GuiUtils.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16, 0);
}
RenderSystem.enableDepthTest();
}
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
}
protected abstract int getIconIndex();
@Override
public int xPos() {
return this.x;
}
@Override
public int yPos() {
return this.y;
}
@Override
public int getWidth() {
return this.halfSize ? 8 : 16;
}
@Override
public int getHeight() {
return this.halfSize ? 8 : 16;
}
@Override
public boolean isVisible() {
return this.visible;
}
public boolean isHalfSize() {
return this.halfSize;
}
public void setHalfSize(final boolean halfSize) {
this.halfSize = halfSize;
}
}
@@ -0,0 +1,52 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
// FIXME: Fix this piece of crap (i.e. onChange listener)
public class NumberBox extends TextFieldWidget {
private final Class type;
public NumberBox(final FontRenderer fontRenderer, final int x, final int y, final int width, final int height,
final Class type) {
super(fontRenderer, x, y, width, height, "0");
this.type = type;
}
@Override
public void writeText(final String selectedText) {
final String original = this.getText();
super.writeText(selectedText);
try {
if (this.type == int.class || this.type == Integer.class) {
Integer.parseInt(this.getText());
} else if (this.type == long.class || this.type == Long.class) {
Long.parseLong(this.getText());
} else if (this.type == double.class || this.type == Double.class) {
Double.parseDouble(this.getText());
}
} catch (final NumberFormatException e) {
this.setText(original);
}
}
}
@@ -0,0 +1,116 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.gui.widgets;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.util.Identifier;
import net.minecraftforge.fml.client.gui.GuiUtils;
import appeng.container.interfaces.IProgressProvider;
import appeng.core.localization.GuiText;
public class ProgressBar extends Widget implements ITooltip {
private final IProgressProvider source;
private final Identifier texture;
private final int fill_u;
private final int fill_v;
private final Direction layout;
private final String titleName;
private String fullMsg;
public ProgressBar(final IProgressProvider source, final String texture, final int posX, final int posY,
final int u, final int y, final int width, final int height, final Direction dir) {
this(source, texture, posX, posY, u, y, width, height, dir, null);
}
public ProgressBar(final IProgressProvider source, final String texture, final int posX, final int posY,
final int u, final int y, final int width, final int height, final Direction dir, final String title) {
super(posX, posY, width, height, "");
this.source = source;
this.texture = new Identifier("appliedenergistics2", "textures/" + texture);
this.fill_u = u;
this.fill_v = y;
this.layout = dir;
this.titleName = title;
}
@Override
public void renderButton(final int par2, final int par3, final float partial) {
if (this.visible) {
MinecraftClient.getInstance().getTextureManager().bindTexture(this.texture);
final int max = this.source.getMaxProgress();
final int current = this.source.getCurrentProgress();
if (this.layout == Direction.VERTICAL) {
final int diff = this.height - (max > 0 ? (this.height * current) / max : 0);
GuiUtils.drawTexturedModalRect(this.x, this.y + diff, this.fill_u, this.fill_v + diff, this.width,
this.height - diff, 0);
} else {
final int diff = this.width - (max > 0 ? (this.width * current) / max : 0);
GuiUtils.drawTexturedModalRect(this.x, this.y, this.fill_u + diff, this.fill_v, this.width - diff,
this.height, 0);
}
}
}
public void setFullMsg(final String msg) {
this.fullMsg = msg;
}
@Override
public String getMessage() {
if (this.fullMsg != null) {
return this.fullMsg;
}
return (this.titleName != null ? this.titleName : "") + '\n' + this.source.getCurrentProgress() + ' '
+ GuiText.Of.getLocal() + ' ' + this.source.getMaxProgress();
}
@Override
public int xPos() {
return this.x - 2;
}
@Override
public int yPos() {
return this.y - 2;
}
@Override
public int getWidth() {
return this.width + 4;
}
@Override
public int getHeight() {
return this.height + 4;
}
@Override
public boolean isVisible() {
return true;
}
public enum Direction {
HORIZONTAL, VERTICAL
}
}

Some files were not shown because too many files have changed in this diff Show More