Lots more moved
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.attributes;
|
||||
|
||||
import alexiil.mc.lib.attributes.Attribute;
|
||||
import alexiil.mc.lib.attributes.Attributes;
|
||||
import alexiil.mc.lib.attributes.SearchOptions;
|
||||
import appeng.api.storage.IStorageMonitorableAccessor;
|
||||
import appeng.parts.AEBasePart;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Utility class that holds various attributes, both by AE2 and other Mods.
|
||||
*/
|
||||
public final class MEAttributes {
|
||||
|
||||
private MEAttributes() {
|
||||
}
|
||||
|
||||
public static Attribute<IStorageMonitorableAccessor> STORAGE_MONITORABLE_ACCESSOR
|
||||
= Attributes.createDefaulted(IStorageMonitorableAccessor.class, new NullMENetworkAccessor());
|
||||
|
||||
public static <T> T getFirstAttributeOnSide(Attribute<T> attribute, BlockEntity be, Direction side) {
|
||||
World world = be.getWorld();
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return attribute.getFirstOrNull(world, be.getPos().offset(side), SearchOptions.inDirection(side.getOpposite()));
|
||||
}
|
||||
|
||||
// Convenience function to get an attribute of the block that is in front of a part
|
||||
public static <T> T getAttributeInFrontOfPart(Attribute<T> attribute, AEBasePart part) {
|
||||
BlockEntity self = part.getHost().getTile();
|
||||
Direction direction = part.getSide().getFacing();
|
||||
final World w = self.getWorld();
|
||||
BlockPos neighborPos = self.getPos().offset(direction);
|
||||
// Do not force-load a neighboring chunk for this.
|
||||
ChunkPos chunkPos = new ChunkPos(neighborPos);
|
||||
if (!w.getChunkManager().isChunkLoaded(chunkPos.x, chunkPos.z)) {
|
||||
return null;
|
||||
}
|
||||
return attribute.getFirstOrNull(w, neighborPos, SearchOptions.inDirection(direction));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.attributes;
|
||||
|
||||
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,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,46 @@
|
||||
/*
|
||||
* 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.Item;
|
||||
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);
|
||||
}
|
||||
|
||||
// FIXME FABRIC needs to move to disassembly crafting recipes
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public Item getRecipeRemainder() {
|
||||
// FIXME FABRIC return AEApi.instance().definitions().blocks().craftingUnit().item();
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public boolean hasRecipeRemainder() {
|
||||
// FIXME FABRIC return AEConfig.instance().isFeatureEnabled(AEFeature.ENABLE_DISASSEMBLY_CRAFTING);
|
||||
// FIXME FABRIC }
|
||||
}
|
||||
@@ -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 appeng.util.FakePlayer;
|
||||
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 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 (FakePlayer.isFakePlayer(player) || 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).solidBlock((state, world, pos) -> false));
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,8 +158,8 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
|
||||
// FIXME FABRIC Hook does not exist
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player,
|
||||
// FIXME FABRIC boolean willHarvest, IFluidState fluid) {
|
||||
// FIXME FABRIC if (player.abilities.isCreativeMode) {
|
||||
// FIXME FABRIC boolean willHarvest, FluidState fluid) {
|
||||
// FIXME FABRIC if (player.isCreative()) {
|
||||
// FIXME FABRIC final AEBaseBlockEntity tile = this.getBlockEntity(world, pos);
|
||||
// FIXME FABRIC if (tile != null) {
|
||||
// FIXME FABRIC tile.disableDrops();
|
||||
|
||||
@@ -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 appeng.tile.networking.ControllerBlockEntity;
|
||||
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;
|
||||
|
||||
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.of("state",
|
||||
ControllerBlockState.class);
|
||||
|
||||
public static final EnumProperty<ControllerRenderType> CONTROLLER_TYPE = EnumProperty.of("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.AEMaterials;
|
||||
import appeng.tile.networking.CreativeEnergyCellBlockEntity;
|
||||
|
||||
public class CreativeEnergyCellBlock extends AEBaseTileBlock<CreativeEnergyCellBlockEntity> {
|
||||
|
||||
public CreativeEnergyCellBlock() {
|
||||
super(defaultProps(AEMaterials.GLASS));
|
||||
}
|
||||
}
|
||||
@@ -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,64 @@
|
||||
/*
|
||||
* 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.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.IntProperty;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.helpers.AEMaterials;
|
||||
import appeng.tile.networking.EnergyCellBlockEntity;
|
||||
|
||||
public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellBlockEntity> {
|
||||
|
||||
public static final IntProperty ENERGY_STORAGE = IntProperty.of("fullness", 0, 7);
|
||||
|
||||
public EnergyCellBlock() {
|
||||
super(defaultProps(AEMaterials.GLASS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStacksForDisplay(ItemGroup group, DefaultedList<ItemStack> itemStacks) {
|
||||
super.addStacksForDisplay(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.AEMaterials;
|
||||
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.of("state", State.class);
|
||||
|
||||
public WirelessBlock() {
|
||||
super(defaultProps(AEMaterials.GLASS)
|
||||
.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,184 @@
|
||||
|
||||
package appeng.block.paint;
|
||||
|
||||
import appeng.client.render.cablebus.CubeBuilder;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.helpers.Splotch;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 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 BakedModel, FabricBakedModel {
|
||||
|
||||
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) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanillaAdapter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
|
||||
Object renderAttachment = ((RenderAttachedBlockView) blockView).getBlockEntityRenderAttachment(pos);
|
||||
if (!(renderAttachment instanceof PaintSplotches)) {
|
||||
return;
|
||||
}
|
||||
PaintSplotches splotchesState = (PaintSplotches) renderAttachment;
|
||||
|
||||
List<Splotch> splotches = splotchesState.getSplotches();
|
||||
|
||||
CubeBuilder builder = new CubeBuilder(context.getEmitter());
|
||||
|
||||
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:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction face, Random random) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@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 ModelTransformation getTransformation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@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,92 @@
|
||||
/*
|
||||
* 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).solidBlock((state, world, pos) -> false)
|
||||
.air());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStacksForDisplay(ItemGroup group, DefaultedList<ItemStack> list) {
|
||||
}
|
||||
|
||||
@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 rainTick(World world, BlockPos pos) {
|
||||
if (Platform.isServer()) {
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME FABRIC currently no equivalent
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public int getLightValue(final BlockState state, final BlockView w, final BlockPos pos) {
|
||||
// FIXME FABRIC final PaintSplotchesBlockEntity tp = this.getBlockEntity(w, pos);
|
||||
|
||||
// FIXME FABRIC if (tp != null) {
|
||||
// FIXME FABRIC return tp.getLightLevel();
|
||||
// FIXME FABRIC }
|
||||
|
||||
// FIXME FABRIC return 0;
|
||||
// FIXME FABRIC }
|
||||
|
||||
@Override
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
package appeng.block.paint;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||
import net.minecraft.client.render.model.ModelLoader;
|
||||
import net.minecraft.client.render.model.UnbakedModel;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaintSplotchesModel implements UnbakedModel {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
|
||||
return new PaintSplotchesBakedModel(textureGetter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, Set<Pair<String, String>> unresolvedTextureReferences) {
|
||||
return PaintSplotchesBakedModel.getRequiredTextures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> getModelDependencies() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -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,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,91 @@
|
||||
/*
|
||||
* 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.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.AEMaterials;
|
||||
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(AEMaterials.GLASS));
|
||||
}
|
||||
|
||||
@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,89 @@
|
||||
/*
|
||||
* 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 appeng.block.AEBaseBlock;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.piston.PistonBehavior;
|
||||
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.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldView;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
|
||||
/**
|
||||
* 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, PistonBehavior.PUSH_ONLY);
|
||||
|
||||
public MatrixFrameBlock() {
|
||||
super(Settings.of(MATERIAL).strength(-1.0F, 6000000.0F).solidBlock((state, world, pos) -> false).dropsNothing());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.INVISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStacksForDisplay(ItemGroup group, DefaultedList<ItemStack> list) {
|
||||
// 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 onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
||||
world.setBlockState(pos, getDefaultState(), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTranslucent(BlockState state, BlockView reader, BlockPos pos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,56 @@
|
||||
/*
|
||||
* 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.AEMaterials;
|
||||
import appeng.tile.spatial.SpatialPylonBlockEntity;
|
||||
|
||||
public class SpatialPylonBlock extends AEBaseTileBlock<SpatialPylonBlockEntity> {
|
||||
|
||||
public SpatialPylonBlock() {
|
||||
super(defaultProps(AEMaterials.GLASS));
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME FABRIC Must use block states for dynamic lighting
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public int getLightValue(final BlockState state, final BlockView w, final BlockPos pos) {
|
||||
// FIXME FABRIC final SpatialPylonBlockEntity tsp = this.getBlockEntity(w, pos);
|
||||
// FIXME FABRIC if (tsp != null) {
|
||||
// FIXME FABRIC return tsp.getLightValue();
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC return super.getLightValue(state, w, pos);
|
||||
// FIXME FABRIC }
|
||||
|
||||
}
|
||||
@@ -20,6 +20,9 @@ package appeng.block.storage;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.ContainerOpener;
|
||||
import appeng.container.implementations.ChestContainer;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Material;
|
||||
@@ -83,8 +86,8 @@ public class ChestBlock extends AEBaseTileBlock<ChestBlockEntity> {
|
||||
p.sendSystemMessage(PlayerMessages.ChestCannotReadStorageCell.get(), Util.NIL_UUID);
|
||||
}
|
||||
} else {
|
||||
// FIXME FABRIC ContainerOpener.openContainer(ChestContainer.TYPE, p,
|
||||
// FIXME FABRIC ContainerLocator.forTileEntitySide(tg, hit.getSide()));
|
||||
ContainerOpener.openContainer(ChestContainer.TYPE, p,
|
||||
ContainerLocator.forTileEntitySide(tg, hit.getSide()));
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,12 @@ import appeng.bootstrap.components.IClientSetupComponent;
|
||||
import appeng.bootstrap.components.IItemColorRegistrationComponent;
|
||||
import appeng.bootstrap.components.IModelBakeComponent;
|
||||
import appeng.bootstrap.components.ITileEntityRegistrationComponent;
|
||||
import appeng.client.gui.implementations.*;
|
||||
import appeng.client.render.cablebus.CableBusModelLoader;
|
||||
import appeng.client.render.effects.*;
|
||||
import appeng.client.render.tesr.InscriberTESR;
|
||||
import appeng.client.render.tesr.SkyChestTESR;
|
||||
import appeng.container.implementations.*;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.ApiDefinitions;
|
||||
import appeng.core.AppEng;
|
||||
@@ -24,9 +27,12 @@ import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
|
||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
||||
import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.options.KeyBinding;
|
||||
import net.minecraft.client.render.entity.ItemEntityRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
@@ -39,10 +45,7 @@ import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -55,6 +58,8 @@ public final class AppEngClient extends AppEngBase {
|
||||
|
||||
private final ClientTickHandler tickHandler;
|
||||
|
||||
private final EnumMap<ActionKey, KeyBinding> bindings = new EnumMap<>(ActionKey.class);
|
||||
|
||||
public static AppEngClient instance() {
|
||||
return (AppEngClient) AppEng.instance();
|
||||
}
|
||||
@@ -75,6 +80,7 @@ public final class AppEngClient extends AppEngBase {
|
||||
registerEntityRenderers();
|
||||
registerItemColors();
|
||||
registerTextures();
|
||||
registerScreens();
|
||||
|
||||
// On the client, we'll register for server startup/shutdown to properly setup WorldData
|
||||
// each time the integrated server starts&stops
|
||||
@@ -153,8 +159,8 @@ public final class AppEngClient extends AppEngBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionKey(@Nonnull ActionKey key, InputUtil.Key input) {
|
||||
return false;
|
||||
public boolean isActionKey(@Nonnull ActionKey key, int keyCode, int scanCode) {
|
||||
return this.bindings.get(key).matchesKey(keyCode, scanCode);
|
||||
}
|
||||
|
||||
protected void registerParticleRenderers() {
|
||||
@@ -194,9 +200,9 @@ public final class AppEngClient extends AppEngBase {
|
||||
}
|
||||
|
||||
public void registerTextures() {
|
||||
// FIXME FABRIC InscriberTESR.registerTexture();
|
||||
Stream<Collection<SpriteIdentifier>> sprites = Stream.of(
|
||||
SkyChestTESR.SPRITES
|
||||
SkyChestTESR.SPRITES,
|
||||
InscriberTESR.SPRITES
|
||||
);
|
||||
|
||||
// Group every needed sprite by atlas, since every atlas has their own event
|
||||
@@ -241,4 +247,49 @@ public final class AppEngClient extends AppEngBase {
|
||||
// FIXME FABRIC new CableBusModelLoader());
|
||||
}
|
||||
|
||||
private void registerScreens() {
|
||||
ScreenRegistry.register(GrinderContainer.TYPE, GrinderScreen::new);
|
||||
ScreenRegistry.register(QNBContainer.TYPE, QNBScreen::new);
|
||||
ScreenRegistry.register(SkyChestContainer.TYPE, SkyChestScreen::new);
|
||||
ScreenRegistry.register(ChestContainer.TYPE, ChestScreen::new);
|
||||
ScreenRegistry.register(WirelessContainer.TYPE, WirelessScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.<MEMonitorableContainer, MEMonitorableScreen<MEMonitorableContainer>>register(
|
||||
// FIXME FABRIC MEMonitorableContainer.TYPE, MEMonitorableScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(MEPortableCellContainer.TYPE, MEPortableCellScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(WirelessTermContainer.TYPE, WirelessTermScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(NetworkStatusContainer.TYPE, NetworkStatusScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.<CraftingCPUContainer, CraftingCPUScreen<CraftingCPUContainer>>register(
|
||||
// FIXME FABRIC CraftingCPUContainer.TYPE, CraftingCPUScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(NetworkToolContainer.TYPE, NetworkToolScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(QuartzKnifeContainer.TYPE, QuartzKnifeScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(DriveContainer.TYPE, DriveScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(VibrationChamberContainer.TYPE, VibrationChamberScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(CondenserContainer.TYPE, CondenserScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(InterfaceContainer.TYPE, InterfaceScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FluidInterfaceContainer.TYPE, FluidInterfaceScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.<UpgradeableContainer, UpgradeableScreen<UpgradeableContainer>>register(
|
||||
// FIXME FABRIC UpgradeableContainer.TYPE, UpgradeableScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FluidIOContainer.TYPE, FluidIOScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(IOPortContainer.TYPE, IOPortScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(StorageBusContainer.TYPE, StorageBusScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FluidStorageBusContainer.TYPE, FluidStorageBusScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FormationPlaneContainer.TYPE, FormationPlaneScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FluidFormationPlaneContainer.TYPE, FluidFormationPlaneScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(PriorityContainer.TYPE, PriorityScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(SecurityStationContainer.TYPE, SecurityStationScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(CraftingTermContainer.TYPE, CraftingTermScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(PatternTermContainer.TYPE, PatternTermScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FluidTerminalContainer.TYPE, FluidTerminalScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(LevelEmitterContainer.TYPE, LevelEmitterScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(FluidLevelEmitterContainer.TYPE, FluidLevelEmitterScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(SpatialIOPortContainer.TYPE, SpatialIOPortScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(InscriberContainer.TYPE, InscriberScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(CellWorkbenchContainer.TYPE, CellWorkbenchScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(MolecularAssemblerContainer.TYPE, MolecularAssemblerScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(CraftAmountContainer.TYPE, CraftAmountScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(CraftConfirmContainer.TYPE, CraftConfirmScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(InterfaceTerminalContainer.TYPE, InterfaceTerminalScreen::new);
|
||||
// FIXME FABRIC ScreenRegistry.register(CraftingStatusContainer.TYPE, CraftingStatusScreen::new);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.slot.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(MatrixStack matrices, 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<Text> 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 formattedAmount = NumberFormat.getNumberInstance(Locale.US)
|
||||
.format(myStack.getStackSize());
|
||||
currentToolTip.add(ButtonToolTips.ItemsStored.text(formattedAmount)
|
||||
.formatted(Formatting.GRAY));
|
||||
}
|
||||
|
||||
if (myStack.getCountRequestable() > 0) {
|
||||
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US)
|
||||
.format(myStack.getCountRequestable());
|
||||
currentToolTip.add(ButtonToolTips.ItemsRequestable.text(formattedAmount));
|
||||
}
|
||||
|
||||
this.renderTooltip(matrices, currentToolTip, x, y);
|
||||
|
||||
return;
|
||||
} else if (stack.getCount() > bigNumber) {
|
||||
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US).format(stack.getCount());
|
||||
currentToolTip.add(ButtonToolTips.ItemsStored.text(formattedAmount).formatted(Formatting.GRAY));
|
||||
|
||||
this.renderTooltip(matrices, currentToolTip, x, y);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.renderTooltip(matrices, stack, x, y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,782 @@
|
||||
/*
|
||||
* 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 appeng.mixins.SlotMixin;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.text.StringRenderable;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.util.Formatting;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
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 HandledScreen<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);
|
||||
}
|
||||
|
||||
public MinecraftClient getClient() {
|
||||
return Preconditions.checkNotNull(client);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@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.handler.slots;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, final int mouseX, final int mouseY, final float partialTicks) {
|
||||
super.renderBackground(matrices);
|
||||
super.render(matrices, mouseX, mouseY, partialTicks);
|
||||
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.translatef(this.x, this.y, 0.0F);
|
||||
RenderSystem.enableDepthTest();
|
||||
for (final CustomSlotWidget c : this.guiSlots) {
|
||||
this.drawGuiSlot(matrices, c, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
RenderSystem.disableDepthTest();
|
||||
for (final CustomSlotWidget c : this.guiSlots) {
|
||||
this.drawTooltip(matrices, c, mouseX - this.x, mouseY - this.y);
|
||||
}
|
||||
RenderSystem.popMatrix();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
this.drawMouseoverTooltip(matrices, mouseX, mouseY);
|
||||
|
||||
for (final Object c : this.buttons) {
|
||||
if (c instanceof ITooltip) {
|
||||
this.drawTooltip(matrices, (ITooltip) c, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawGuiSlot(MatrixStack matrices, CustomSlotWidget slot, int mouseX, int mouseY, float partialTicks) {
|
||||
if (slot.isSlotEnabled()) {
|
||||
final int left = slot.xPos();
|
||||
final int top = slot.yPos();
|
||||
final int right = left + slot.getWidth();
|
||||
final int bottom = top + slot.getHeight();
|
||||
|
||||
slot.drawContent(getClient(), mouseX, mouseY, partialTicks);
|
||||
|
||||
if (this.isPointWithinBounds(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY)
|
||||
&& slot.canClick(getPlayer())) {
|
||||
RenderSystem.colorMask(true, true, true, false);
|
||||
this.fillGradient(matrices, left, top, right, bottom, -2130706433, -2130706433);
|
||||
RenderSystem.colorMask(true, true, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTooltip(MatrixStack matrices, 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 Text msg = tooltip.getMessage();
|
||||
if (msg != null) {
|
||||
this.drawTooltip(matrices, x + 11, y + 4, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawTooltip(MatrixStack matrices, int x, int y, Text message) {
|
||||
String[] lines = message.getString().split("\n"); // FIXME FABRIC
|
||||
this.drawTooltip(matrices, x, y, Arrays.asList(lines));
|
||||
}
|
||||
|
||||
// FIXME FABRIC: move out to json (?)
|
||||
private static final Style TOOLTIP_HEADER = Style.EMPTY.withColor(Formatting.WHITE);
|
||||
private static final Style TOOLTIP_BODY = Style.EMPTY.withColor(Formatting.GRAY);
|
||||
|
||||
protected void drawTooltip(MatrixStack matrices, int x, int y, List<String> lines) {
|
||||
if (lines.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<StringRenderable> renderableLines = new ArrayList<>(lines.size());
|
||||
|
||||
// Make the first line white
|
||||
// All lines after the first are colored gray
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
Style style = (i == 0) ? TOOLTIP_HEADER : TOOLTIP_BODY;
|
||||
renderableLines.add(StringRenderable.styled(lines.get(0), style));
|
||||
}
|
||||
|
||||
this.renderTooltip(matrices, renderableLines, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void drawForeground(MatrixStack matrices, final int x, final int y) {
|
||||
final int ox = this.x; // (width - xSize) / 2;
|
||||
final int oy = this.y; // (height - ySize) / 2;
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().draw(matrices, this);
|
||||
}
|
||||
|
||||
this.drawFG(matrices, ox, oy, x, y);
|
||||
}
|
||||
|
||||
public abstract void drawFG(MatrixStack matrices, int offsetX, int offsetY, int mouseX, int mouseY);
|
||||
|
||||
@Override
|
||||
protected final void drawBackground(MatrixStack matrices, final float f, final int x, final int y) {
|
||||
final int ox = this.x; // (width - xSize) / 2;
|
||||
final int oy = this.y; // (height - ySize) / 2;
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.drawBG(matrices, 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()) {
|
||||
drawTexture(matrices, ox + aeSlot.x - 1, oy + aeSlot.y - 1,
|
||||
optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18);
|
||||
} else {
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F);
|
||||
RenderSystem.enableBlend();
|
||||
drawTexture(matrices, ox + aeSlot.x - 1, oy + aeSlot.y - 1,
|
||||
optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18);
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final CustomSlotWidget slot : this.guiSlots) {
|
||||
slot.drawBackground(ox, oy, getZOffset());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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 AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (CustomSlotWidget slot : this.guiSlots) {
|
||||
if (this.isPointWithinBounds(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord)
|
||||
&& slot.canClick(getPlayer())) {
|
||||
slot.slotClicked(getPlayer().inventory.getCursorStack(), btn);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().click(xCoord - this.x, yCoord - this.y);
|
||||
}
|
||||
|
||||
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.getCursorStack();
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
// FIXME: Coordinate system of mouseX/mouseY is unclear
|
||||
this.getScrollBar().click((int) mouseX - this.x, (int) mouseY - this.y);
|
||||
}
|
||||
|
||||
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.id, 0);
|
||||
NetworkHandler.instance().sendToServer(p);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return super.mouseDragged(mouseX, mouseY, mouseButton, dragX, dragY);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 1.9.4 aftermath - Whole SlotActionType thing, to be checked.
|
||||
@Override
|
||||
protected void onMouseClick(final Slot slot, final int slotIdx, final int mouseButton,
|
||||
final SlotActionType 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 (InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().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.id;
|
||||
}
|
||||
|
||||
this.handler.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.isCreative()) {
|
||||
action = InventoryAction.CREATIVE_DUPLICATE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
case THROW: // drop item:
|
||||
}
|
||||
|
||||
if (action != null) {
|
||||
final InventoryActionPacket p = new InventoryActionPacket(action, getSlotIndex(slot),
|
||||
((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.getCursorStack().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.isCreative()) {
|
||||
final IAEItemStack slotItem = ((SlotME) slot).getAEStack();
|
||||
if (slotItem != null) {
|
||||
action = InventoryAction.CREATIVE_DUPLICATE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case THROW: // drop item:
|
||||
}
|
||||
|
||||
if (action != null) {
|
||||
this.handler.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.hasStack() ? 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.canTakeItems(getPlayer()) && inventorySlot.hasStack()
|
||||
&& inventorySlot.inventory == slot.inventory
|
||||
&& ScreenHandler.canInsertItemIntoSlot(inventorySlot, this.dbl_whichItem, true)) {
|
||||
this.onMouseClick(inventorySlot, inventorySlot.id, 0, SlotActionType.QUICK_MOVE);
|
||||
}
|
||||
}
|
||||
this.dbl_whichItem = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
this.disableShiftClick = false;
|
||||
}
|
||||
|
||||
super.onMouseClick(slot, slotIdx, mouseButton, clickType);
|
||||
}
|
||||
|
||||
protected ClientPlayerEntity getPlayer() {
|
||||
// Our UIs are usually not opened when not in-game, so this should not be a
|
||||
// problem
|
||||
return Preconditions.checkNotNull(getClient().player);
|
||||
}
|
||||
|
||||
protected int getSlotIndex(Slot slot) {
|
||||
return ((SlotMixin)slot).getIndex();
|
||||
}
|
||||
|
||||
protected boolean checkHotbarKeys(int keyCode, int scanCode) {
|
||||
final Slot theSlot = this.focusedSlot;
|
||||
|
||||
if (getPlayer().inventory.getCursorStack().isEmpty() && theSlot != null) {
|
||||
for (int j = 0; j < 9; ++j) {
|
||||
if (getClient().options.keysHotbar[j].matchesKey(keyCode, scanCode)) {
|
||||
final List<Slot> slots = this.getInventorySlots();
|
||||
for (final Slot s : slots) {
|
||||
if (getSlotIndex(s) == j && s.inventory == this.handler.getPlayerInv()) {
|
||||
if (!s.canTakeItems(this.handler.getPlayerInv().player)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theSlot.getMaxStackAmount() == 64) {
|
||||
this.onMouseClick(theSlot, theSlot.id, j, SlotActionType.SWAP);
|
||||
return true;
|
||||
} else {
|
||||
for (final Slot s : slots) {
|
||||
if (getSlotIndex(s) == j
|
||||
&& s.inventory == this.handler.getPlayerInv()) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new SwapSlotsPacket(s.id, theSlot.id));
|
||||
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) {
|
||||
// isPointWithinBounds
|
||||
if (this.isPointWithinBounds(slot.x, slot.y, 16, 16, mouseX, mouseY)) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract void drawBG(MatrixStack matrices, 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) {
|
||||
this.handler.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);
|
||||
getClient().getTextureManager().bindTexture(loc);
|
||||
}
|
||||
|
||||
protected void drawItem(final int x, final int y, final ItemStack is) {
|
||||
this.itemRenderer.zOffset = 100.0F;
|
||||
this.itemRenderer.renderInGuiWithOverrides(is, x, y);
|
||||
|
||||
this.itemRenderer.zOffset = 0.0F;
|
||||
}
|
||||
|
||||
protected String getGuiDisplayName(final String in) {
|
||||
return this.hasCustomInventoryName() ? this.getInventoryName() : in;
|
||||
}
|
||||
|
||||
private boolean hasCustomInventoryName() {
|
||||
return this.handler.getCustomName() != null;
|
||||
}
|
||||
|
||||
private String getInventoryName() {
|
||||
return this.handler.getCustomName();
|
||||
}
|
||||
|
||||
/**
|
||||
* This overrides the base-class method through some access transformer
|
||||
* hackery...
|
||||
*/
|
||||
@Override
|
||||
public void drawSlot(MatrixStack matrices, Slot s) {
|
||||
if (s instanceof SlotME) {
|
||||
|
||||
try {
|
||||
if (!this.isPowered()) {
|
||||
fill(matrices, s.x, s.y, 16 + s.x, 16 + s.y, 0x66111111);
|
||||
}
|
||||
|
||||
// Annoying but easier than trying to splice into render item
|
||||
super.drawSlot(matrices, new Size1Slot((SlotME) s));
|
||||
|
||||
this.stackSizeRenderer.renderStackSize(this.textRenderer, ((SlotME) s).getAEStack(), s.x, s.y);
|
||||
|
||||
} 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()) {
|
||||
fs.getFluidStack().renderGuiRect(s.x, s.y, s.x + 16, s.y + 16);
|
||||
|
||||
this.fluidStackSizeRenderer.renderStackSize(this.textRenderer, fs, s.x, s.y);
|
||||
} else if (!this.isPowered()) {
|
||||
fill(matrices, s.x, s.y, 16 + s.x, 16 + s.y, 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.x;
|
||||
final float par2 = aes.y;
|
||||
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_COLOR_TEXTURE);
|
||||
|
||||
final float f1 = 0.00390625F;
|
||||
final float f = 0.00390625F;
|
||||
final float par6 = 16;
|
||||
vb.vertex(par1 + 0, par2 + par6, getZOffset())
|
||||
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon())
|
||||
.texture((par3 + 0) * f, (par4 + par6) * f1)
|
||||
.next();
|
||||
final float par5 = 16;
|
||||
vb.vertex(par1 + par5, par2 + par6, getZOffset())
|
||||
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon())
|
||||
.texture((par3 + par5) * f, (par4 + par6) * f1)
|
||||
.next();
|
||||
vb.vertex(par1 + par5, par2 + 0, getZOffset())
|
||||
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon())
|
||||
.texture((par3 + par5) * f, (par4 + 0) * f1)
|
||||
.next();
|
||||
vb.vertex(par1 + 0, par2 + 0, getZOffset())
|
||||
.color(1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon())
|
||||
.texture((par3 + 0) * f, (par4 + 0) * f1)
|
||||
.next();
|
||||
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.canInsert(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, getClient().world);
|
||||
} catch (final Exception err) {
|
||||
AELog.debug(err);
|
||||
}
|
||||
}
|
||||
aeSlot.setIsValid(isValid ? CalculatedValidity.Valid : CalculatedValidity.Invalid);
|
||||
}
|
||||
|
||||
if (aeSlot.getIsValid() == CalculatedValidity.Invalid) {
|
||||
setZOffset(100);
|
||||
this.itemRenderer.zOffset = 100.0F;
|
||||
|
||||
fill(matrices, s.x, s.y, 16 + s.x, 16 + s.y, 0x66ff6666);
|
||||
|
||||
setZOffset(0);
|
||||
this.itemRenderer.zOffset = 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
if (s instanceof AppEngSlot) {
|
||||
((AppEngSlot) s).setDisplay(true);
|
||||
super.drawSlot(matrices, s);
|
||||
} else {
|
||||
super.drawSlot(matrices, 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(matrices, s);
|
||||
}
|
||||
|
||||
protected boolean isPowered() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void bindTexture(final String file) {
|
||||
final Identifier loc = new Identifier(AppEng.MOD_ID, "textures/" + file);
|
||||
getClient().getTextureManager().bindTexture(loc);
|
||||
}
|
||||
|
||||
public void bindTexture(final Identifier loc) {
|
||||
getClient().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,81 @@
|
||||
|
||||
package appeng.client.gui;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.client.me.SlotME;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
/**
|
||||
* 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 Slot {
|
||||
|
||||
private final SlotME delegate;
|
||||
|
||||
public Size1Slot(SlotME delegate) {
|
||||
super(delegate.inventory, -1, delegate.x, delegate.y);
|
||||
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 hasStack() {
|
||||
return this.delegate.hasStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackAmount() {
|
||||
return this.delegate.getMaxStackAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackAmount(ItemStack stack) {
|
||||
return this.delegate.getMaxStackAmount(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItems(PlayerEntity playerIn) {
|
||||
return this.delegate.canTakeItems(playerIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
delegate.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public Pair<Identifier, Identifier> getBackgroundSprite() {
|
||||
return delegate.getBackgroundSprite();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public boolean doDrawHoveringEffect() {
|
||||
return delegate.doDrawHoveringEffect();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.client.render.item.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;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
/**
|
||||
* 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 Text label) {
|
||||
if (this.previousContainerType != null && !previousContainerIcon.isEmpty()) {
|
||||
if (label == null) {
|
||||
label = previousContainerIcon.getName();
|
||||
}
|
||||
ItemRenderer itemRenderer = gui.getClient().getItemRenderer();
|
||||
TabButton button = new TabButton(gui.getX() + x, gui.getY() + 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,64 @@
|
||||
/*
|
||||
* 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.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
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.backgroundHeight = 166;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.addButton(new TabButton(this.x + 154, this.y, 2 + 4 * 16, GuiText.Priority.textComponent(),
|
||||
this.itemRenderer, btn -> openPriority()));
|
||||
}
|
||||
|
||||
private void openPriority() {
|
||||
NetworkHandler.instance().sendToServer(new SwitchGuisPacket(PriorityContainer.TYPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
||||
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.Chest.getLocal()), 8, 6, 4210752);
|
||||
this.textRenderer.draw(matrices, GuiText.inventory.getLocal(), 8, this.backgroundHeight - 96 + 3, 4210752);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
|
||||
this.bindTexture("guis/chest.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
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.backgroundHeight = 176;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
||||
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.GrindStone.getLocal()), 8, 6, 4210752);
|
||||
this.textRenderer.draw(matrices, GuiText.inventory.getLocal(), 8, this.backgroundHeight - 96 + 3, 4210752);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
|
||||
this.bindTexture("guis/grinder.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
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.backgroundHeight = 166;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
||||
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.QuantumLinkChamber.getLocal()), 8, 6, 4210752);
|
||||
this.textRenderer.draw(matrices, GuiText.inventory.getLocal(), 8, this.backgroundHeight - 96 + 3, 4210752);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
|
||||
this.bindTexture("guis/chest.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
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.backgroundHeight = 195;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
||||
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.SkyChest.getLocal()), 8, 8, 4210752);
|
||||
this.textRenderer.draw(matrices, GuiText.inventory.getLocal(), 8, this.backgroundHeight - 96 + 2, 4210752);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
|
||||
bindTexture(TEXTURE);
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean enableSpaceClicking() {
|
||||
// NOTE: previously checked for inventory tweaks mod (which no longer exists)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
|
||||
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.backgroundHeight = 166;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.addButton(CommonButtons.togglePowerUnit(this.x - 18, this.y + 8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
||||
this.textRenderer.draw(matrices, this.getGuiDisplayName(GuiText.Wireless.getLocal()), 8, 6, 4210752);
|
||||
this.textRenderer.draw(matrices, GuiText.inventory.getLocal(), 8, this.backgroundHeight - 96 + 3, 4210752);
|
||||
|
||||
if (handler.getRange() > 0) {
|
||||
final String firstMessage = GuiText.Range.getLocal() + ": " + (handler.getRange() / 10.0) + " m";
|
||||
final String secondMessage = GuiText.PowerUsageRate.getLocal() + ": "
|
||||
+ Platform.formatPowerLong(handler.getDrain(), true);
|
||||
|
||||
final int strWidth = Math.max(this.textRenderer.getWidth(firstMessage),
|
||||
this.textRenderer.getWidth(secondMessage));
|
||||
final int cOffset = (this.backgroundWidth / 2) - (strWidth / 2);
|
||||
this.textRenderer.draw(matrices, firstMessage, cOffset, 20, 4210752);
|
||||
this.textRenderer.draw(matrices, secondMessage, cOffset, 20 + 12, 4210752);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
|
||||
this.bindTexture("guis/wireless.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
/**
|
||||
* 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 TextRenderer fontRenderer, final int xPos, final int yPos, final int width,
|
||||
final int height) {
|
||||
super(fontRenderer, xPos + PADDING, yPos + PADDING, width - 2 * PADDING - (int) fontRenderer.getWidth("_"),
|
||||
height - 2 * PADDING, LiteralText.EMPTY);
|
||||
|
||||
this._fontPad = (int) fontRenderer.getWidth("_");
|
||||
}
|
||||
|
||||
@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.setFocused(requiresFocus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
this.setCursor(0);
|
||||
this.setSelectionEnd(getText().length());
|
||||
}
|
||||
|
||||
public void setSelectionColor(int color) {
|
||||
this.selectionColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float partial) {
|
||||
if (this.isVisible()) {
|
||||
if (this.isFocused()) {
|
||||
fill(matrices, 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(matrices, 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(matrices, mouseX, mouseY, partial);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSelectionHighlight(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.vertex(startX, endY, 0.0D).next();
|
||||
bufferbuilder.vertex(endX, endY, 0.0D).next();
|
||||
bufferbuilder.vertex(endX, startY, 0.0D).next();
|
||||
bufferbuilder.vertex(startX, startY, 0.0D).next();
|
||||
tessellator.draw();
|
||||
RenderSystem.disableColorLogicOp();
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.color4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocused(boolean focused) {
|
||||
super.setFocused(focused);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
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 Text buildMessage(ButtonToolTips displayName, ButtonToolTips displayValue) {
|
||||
String name = displayName.text().getString();
|
||||
String value = displayValue.text().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 new LiteralText(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,71 @@
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public abstract class CustomSlotWidget extends DrawableHelper 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 Text 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,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.client.gui.widgets;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
/**
|
||||
* AEBaseGui controlled Tooltip Interface.
|
||||
*/
|
||||
public interface ITooltip {
|
||||
|
||||
/**
|
||||
* returns the tooltip message.
|
||||
*
|
||||
* @return tooltip message
|
||||
*/
|
||||
Text 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,131 @@
|
||||
/*
|
||||
* 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.ButtonWidget;
|
||||
import net.minecraft.client.texture.TextureManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class IconButton extends ButtonWidget 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, PressAction onPress) {
|
||||
super(x, y, 16, 16, LiteralText.EMPTY, onPress);
|
||||
}
|
||||
|
||||
public void setVisibility(final boolean vis) {
|
||||
this.visible = vis;
|
||||
this.active = vis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, 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;
|
||||
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
drawTexture(matrices, 0, 0, uv_x * 16, uv_y * 16, 16, 16);
|
||||
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;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
|
||||
}
|
||||
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,53 @@
|
||||
/*
|
||||
* 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.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
// FIXME: Fix this piece of crap (i.e. onChange listener)
|
||||
public class NumberBox extends TextFieldWidget {
|
||||
|
||||
private final Class type;
|
||||
|
||||
public NumberBox(final TextRenderer fontRenderer, final int x, final int y, final int width, final int height,
|
||||
final Class type) {
|
||||
super(fontRenderer, x, y, width, height, new LiteralText("0"));
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final String selectedText) {
|
||||
final String original = this.getText();
|
||||
super.write(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,119 @@
|
||||
/*
|
||||
* 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.container.interfaces.IProgressProvider;
|
||||
import appeng.core.localization.GuiText;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ProgressBar extends AbstractButtonWidget 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 Text titleName;
|
||||
private Text 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 Text title) {
|
||||
super(posX, posY, width, height, LiteralText.EMPTY);
|
||||
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(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
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);
|
||||
drawTexture(matrices, this.x, this.y + diff, this.fill_u, this.fill_v + diff, this.width,
|
||||
this.height - diff);
|
||||
} else {
|
||||
final int diff = this.width - (max > 0 ? (this.width * current) / max : 0);
|
||||
drawTexture(matrices, this.x, this.y, this.fill_u + diff, this.fill_v, this.width - diff,
|
||||
this.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setFullMsg(final Text msg) {
|
||||
this.fullMsg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
if (this.fullMsg != null) {
|
||||
return this.fullMsg;
|
||||
}
|
||||
|
||||
Text text = this.titleName != null ? this.titleName : LiteralText.EMPTY;
|
||||
return text.copy().append("\n" + this.source.getCurrentProgress() + " ")
|
||||
.append(GuiText.Of.textComponent())
|
||||
.append(" " + 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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 appeng.client.gui.AEBaseScreen;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
public class Scrollbar implements IScrollSource {
|
||||
|
||||
private int displayX = 0;
|
||||
private int displayY = 0;
|
||||
private int width = 12;
|
||||
private int height = 16;
|
||||
private int pageSize = 1;
|
||||
|
||||
private int maxScroll = 0;
|
||||
private int minScroll = 0;
|
||||
private int currentScroll = 0;
|
||||
|
||||
private final DrawableHelper drawable = new DrawableHelper(){};
|
||||
|
||||
public void draw(MatrixStack matrices, final AEBaseScreen<?> g) {
|
||||
g.bindTexture("minecraft", "gui/container/creative_inventory/tabs.png");
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
drawable.setZOffset(g.getZOffset());
|
||||
if (this.getRange() == 0) {
|
||||
drawable.drawTexture(matrices, this.displayX, this.displayY, 232 + this.width, 0, this.width, 15);
|
||||
} else {
|
||||
final int offset = (this.currentScroll - this.minScroll) * (this.height - 15) / this.getRange();
|
||||
drawable.drawTexture(matrices, this.displayX, offset + this.displayY, 232, 0, this.width, 15);
|
||||
}
|
||||
}
|
||||
|
||||
private int getRange() {
|
||||
return this.maxScroll - this.minScroll;
|
||||
}
|
||||
|
||||
public int getLeft() {
|
||||
return this.displayX;
|
||||
}
|
||||
|
||||
public Scrollbar setLeft(final int v) {
|
||||
this.displayX = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getTop() {
|
||||
return this.displayY;
|
||||
}
|
||||
|
||||
public Scrollbar setTop(final int v) {
|
||||
this.displayY = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public Scrollbar setWidth(final int v) {
|
||||
this.width = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public Scrollbar setHeight(final int v) {
|
||||
this.height = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setRange(final int min, final int max, final int pageSize) {
|
||||
this.minScroll = min;
|
||||
this.maxScroll = max;
|
||||
this.pageSize = pageSize;
|
||||
|
||||
if (this.minScroll > this.maxScroll) {
|
||||
this.maxScroll = this.minScroll;
|
||||
}
|
||||
|
||||
this.applyRange();
|
||||
}
|
||||
|
||||
private void applyRange() {
|
||||
this.currentScroll = Math.max(Math.min(this.currentScroll, this.maxScroll), this.minScroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentScroll() {
|
||||
return this.currentScroll;
|
||||
}
|
||||
|
||||
public void click(final double x, final double y) {
|
||||
if (this.getRange() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x > this.displayX && x <= this.displayX + this.width) {
|
||||
if (y > this.displayY && y <= this.displayY + this.height) {
|
||||
this.currentScroll = (int) (y - this.displayY);
|
||||
this.currentScroll = this.minScroll + ((this.currentScroll * 2 * this.getRange() / this.height));
|
||||
this.currentScroll = (this.currentScroll + 1) >> 1;
|
||||
this.applyRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void wheel(double delta) {
|
||||
delta = Math.max(Math.min(-delta, 1), -1);
|
||||
this.currentScroll += delta * this.pageSize;
|
||||
this.applyRange();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.Settings;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigButtonPacket;
|
||||
|
||||
/**
|
||||
* Convenience button that automatically sends settings changes to the server.
|
||||
*/
|
||||
public class ServerSettingToggleButton<T extends Enum<T>> extends SettingToggleButton<T> {
|
||||
|
||||
public ServerSettingToggleButton(final int x, final int y, final Settings setting, final T val) {
|
||||
super(x, y, setting, val, ServerSettingToggleButton::sendToServer);
|
||||
}
|
||||
|
||||
private static <T extends Enum<T>> void sendToServer(SettingToggleButton<T> button, boolean backwards) {
|
||||
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(button.getSetting(), backwards));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* 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.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.CondenserOutput;
|
||||
import appeng.api.config.FullnessMode;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.LevelType;
|
||||
import appeng.api.config.OperationMode;
|
||||
import appeng.api.config.PowerUnits;
|
||||
import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.RelativeDirection;
|
||||
import appeng.api.config.SchedulingMode;
|
||||
import appeng.api.config.SearchBoxMode;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.SortDir;
|
||||
import appeng.api.config.SortOrder;
|
||||
import appeng.api.config.StorageFilter;
|
||||
import appeng.api.config.TerminalStyle;
|
||||
import appeng.api.config.ViewItems;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.core.localization.ButtonToolTips;
|
||||
import appeng.util.EnumCycler;
|
||||
|
||||
public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
private static final Pattern COMPILE = Pattern.compile("%s");
|
||||
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
|
||||
private static Map<EnumPair, ButtonAppearance> appearances;
|
||||
private final Settings buttonSetting;
|
||||
private final IHandler<SettingToggleButton<T>> onPress;
|
||||
private final EnumSet<T> validValues;
|
||||
private String fillVar;
|
||||
private T currentValue;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface IHandler<T extends SettingToggleButton<?>> {
|
||||
void handle(T button, boolean backwards);
|
||||
}
|
||||
|
||||
public SettingToggleButton(final int x, final int y, final Settings setting, final T val,
|
||||
IHandler<SettingToggleButton<T>> onPress) {
|
||||
this(x, y, setting, val, t -> true, onPress);
|
||||
}
|
||||
|
||||
public SettingToggleButton(final int x, final int y, final Settings setting, final T val, Predicate<T> isValidValue,
|
||||
IHandler<SettingToggleButton<T>> onPress) {
|
||||
super(x, y, SettingToggleButton::onPress);
|
||||
this.onPress = onPress;
|
||||
|
||||
// Build a list of values (in order) that are valid w.r.t. the given predicate
|
||||
EnumSet<T> validValues = EnumSet.allOf(val.getDeclaringClass());
|
||||
validValues.removeIf(isValidValue.negate());
|
||||
validValues.removeIf(s -> !setting.getPossibleValues().contains(s));
|
||||
this.validValues = validValues;
|
||||
|
||||
this.buttonSetting = setting;
|
||||
this.currentValue = val;
|
||||
|
||||
if (appearances == null) {
|
||||
appearances = new HashMap<>();
|
||||
registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Trash);
|
||||
registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.MatterBalls);
|
||||
registerApp(16 * 7 + 2, Settings.CONDENSER_OUTPUT, CondenserOutput.SINGULARITY,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.Singularity);
|
||||
|
||||
registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode,
|
||||
ButtonToolTips.Read);
|
||||
registerApp(16 * 9, Settings.ACCESS, AccessRestriction.WRITE, ButtonToolTips.IOMode, ButtonToolTips.Write);
|
||||
registerApp(16 * 9 + 2, Settings.ACCESS, AccessRestriction.READ_WRITE, ButtonToolTips.IOMode,
|
||||
ButtonToolTips.ReadWrite);
|
||||
|
||||
registerApp(16 * 10, Settings.POWER_UNITS, PowerUnits.AE, ButtonToolTips.PowerUnits,
|
||||
PowerUnits.AE.textComponent());
|
||||
registerApp(16 * 10 + 1, Settings.POWER_UNITS, PowerUnits.EU, ButtonToolTips.PowerUnits,
|
||||
PowerUnits.EU.textComponent());
|
||||
registerApp(16 * 10 + 4, Settings.POWER_UNITS, PowerUnits.RF, ButtonToolTips.PowerUnits,
|
||||
PowerUnits.RF.textComponent());
|
||||
|
||||
registerApp(3, Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE, ButtonToolTips.RedstoneMode,
|
||||
ButtonToolTips.AlwaysActive);
|
||||
registerApp(0, Settings.REDSTONE_CONTROLLED, RedstoneMode.LOW_SIGNAL, ButtonToolTips.RedstoneMode,
|
||||
ButtonToolTips.ActiveWithoutSignal);
|
||||
registerApp(1, Settings.REDSTONE_CONTROLLED, RedstoneMode.HIGH_SIGNAL, ButtonToolTips.RedstoneMode,
|
||||
ButtonToolTips.ActiveWithSignal);
|
||||
registerApp(2, Settings.REDSTONE_CONTROLLED, RedstoneMode.SIGNAL_PULSE, ButtonToolTips.RedstoneMode,
|
||||
ButtonToolTips.ActiveOnPulse);
|
||||
|
||||
registerApp(0, Settings.REDSTONE_EMITTER, RedstoneMode.LOW_SIGNAL, ButtonToolTips.RedstoneMode,
|
||||
ButtonToolTips.EmitLevelsBelow);
|
||||
registerApp(1, Settings.REDSTONE_EMITTER, RedstoneMode.HIGH_SIGNAL, ButtonToolTips.RedstoneMode,
|
||||
ButtonToolTips.EmitLevelAbove);
|
||||
|
||||
registerApp(51, Settings.OPERATION_MODE, OperationMode.FILL, ButtonToolTips.TransferDirection,
|
||||
ButtonToolTips.TransferToStorageCell);
|
||||
registerApp(50, Settings.OPERATION_MODE, OperationMode.EMPTY, ButtonToolTips.TransferDirection,
|
||||
ButtonToolTips.TransferToNetwork);
|
||||
|
||||
registerApp(51, Settings.IO_DIRECTION, RelativeDirection.LEFT, ButtonToolTips.TransferDirection,
|
||||
ButtonToolTips.TransferToStorageCell);
|
||||
registerApp(50, Settings.IO_DIRECTION, RelativeDirection.RIGHT, ButtonToolTips.TransferDirection,
|
||||
ButtonToolTips.TransferToNetwork);
|
||||
|
||||
registerApp(48, Settings.SORT_DIRECTION, SortDir.ASCENDING, ButtonToolTips.SortOrder,
|
||||
ButtonToolTips.ToggleSortDirection);
|
||||
registerApp(49, Settings.SORT_DIRECTION, SortDir.DESCENDING, ButtonToolTips.SortOrder,
|
||||
ButtonToolTips.ToggleSortDirection);
|
||||
|
||||
registerApp(16 * 2 + 3, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_Auto);
|
||||
registerApp(16 * 2 + 4, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_Standard);
|
||||
registerApp(16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_JEIAuto);
|
||||
registerApp(16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_JEIStandard);
|
||||
registerApp(16 * 2 + 7, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_AutoKeep);
|
||||
registerApp(16 * 2 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_StandardKeep);
|
||||
registerApp(16 * 2 + 9, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH_KEEP, ButtonToolTips.SearchMode,
|
||||
ButtonToolTips.SearchMode_JEIAutoKeep);
|
||||
registerApp(16 * 2 + 10, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH_KEEP,
|
||||
ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIStandardKeep);
|
||||
|
||||
registerApp(16 * 5 + 3, Settings.LEVEL_TYPE, LevelType.ENERGY_LEVEL, ButtonToolTips.LevelType,
|
||||
ButtonToolTips.LevelType_Energy);
|
||||
registerApp(16 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType,
|
||||
ButtonToolTips.LevelType_Item);
|
||||
|
||||
registerApp(16 * 13, Settings.TERMINAL_STYLE, TerminalStyle.TALL, ButtonToolTips.TerminalStyle,
|
||||
ButtonToolTips.TerminalStyle_Tall);
|
||||
registerApp(16 * 13 + 1, Settings.TERMINAL_STYLE, TerminalStyle.SMALL, ButtonToolTips.TerminalStyle,
|
||||
ButtonToolTips.TerminalStyle_Small);
|
||||
registerApp(16 * 13 + 2, Settings.TERMINAL_STYLE, TerminalStyle.FULL, ButtonToolTips.TerminalStyle,
|
||||
ButtonToolTips.TerminalStyle_Full);
|
||||
|
||||
registerApp(64, Settings.SORT_BY, SortOrder.NAME, ButtonToolTips.SortBy, ButtonToolTips.ItemName);
|
||||
registerApp(65, Settings.SORT_BY, SortOrder.AMOUNT, ButtonToolTips.SortBy, ButtonToolTips.NumberOfItems);
|
||||
// 68: Formerly sort by inventory tweaks
|
||||
registerApp(69, Settings.SORT_BY, SortOrder.MOD, ButtonToolTips.SortBy, ButtonToolTips.Mod);
|
||||
|
||||
registerApp(16, Settings.VIEW_MODE, ViewItems.STORED, ButtonToolTips.View, ButtonToolTips.StoredItems);
|
||||
registerApp(18, Settings.VIEW_MODE, ViewItems.ALL, ButtonToolTips.View, ButtonToolTips.StoredCraftable);
|
||||
registerApp(19, Settings.VIEW_MODE, ViewItems.CRAFTABLE, ButtonToolTips.View, ButtonToolTips.Craftable);
|
||||
|
||||
registerApp(16 * 6, Settings.FUZZY_MODE, FuzzyMode.PERCENT_25, ButtonToolTips.FuzzyMode,
|
||||
ButtonToolTips.FZPercent_25);
|
||||
registerApp(16 * 6 + 1, Settings.FUZZY_MODE, FuzzyMode.PERCENT_50, ButtonToolTips.FuzzyMode,
|
||||
ButtonToolTips.FZPercent_50);
|
||||
registerApp(16 * 6 + 2, Settings.FUZZY_MODE, FuzzyMode.PERCENT_75, ButtonToolTips.FuzzyMode,
|
||||
ButtonToolTips.FZPercent_75);
|
||||
registerApp(16 * 6 + 3, Settings.FUZZY_MODE, FuzzyMode.PERCENT_99, ButtonToolTips.FuzzyMode,
|
||||
ButtonToolTips.FZPercent_99);
|
||||
registerApp(16 * 6 + 4, Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL, ButtonToolTips.FuzzyMode,
|
||||
ButtonToolTips.FZIgnoreAll);
|
||||
|
||||
registerApp(80, Settings.FULLNESS_MODE, FullnessMode.EMPTY, ButtonToolTips.OperationMode,
|
||||
ButtonToolTips.MoveWhenEmpty);
|
||||
registerApp(81, Settings.FULLNESS_MODE, FullnessMode.HALF, ButtonToolTips.OperationMode,
|
||||
ButtonToolTips.MoveWhenWorkIsDone);
|
||||
registerApp(82, Settings.FULLNESS_MODE, FullnessMode.FULL, ButtonToolTips.OperationMode,
|
||||
ButtonToolTips.MoveWhenFull);
|
||||
|
||||
registerApp(16 + 5, Settings.BLOCK, YesNo.YES, ButtonToolTips.InterfaceBlockingMode,
|
||||
ButtonToolTips.Blocking);
|
||||
registerApp(16 + 4, Settings.BLOCK, YesNo.NO, ButtonToolTips.InterfaceBlockingMode,
|
||||
ButtonToolTips.NonBlocking);
|
||||
|
||||
registerApp(16 + 3, Settings.CRAFT_ONLY, YesNo.YES, ButtonToolTips.Craft, ButtonToolTips.CraftOnly);
|
||||
registerApp(16 + 2, Settings.CRAFT_ONLY, YesNo.NO, ButtonToolTips.Craft, ButtonToolTips.CraftEither);
|
||||
|
||||
registerApp(16 * 11 + 2, Settings.CRAFT_VIA_REDSTONE, YesNo.YES, ButtonToolTips.EmitterMode,
|
||||
ButtonToolTips.CraftViaRedstone);
|
||||
registerApp(16 * 11 + 1, Settings.CRAFT_VIA_REDSTONE, YesNo.NO, ButtonToolTips.EmitterMode,
|
||||
ButtonToolTips.EmitWhenCrafting);
|
||||
|
||||
registerApp(16 * 3 + 5, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY,
|
||||
ButtonToolTips.ReportInaccessibleItems, ButtonToolTips.ReportInaccessibleItemsNo);
|
||||
registerApp(16 * 3 + 6, Settings.STORAGE_FILTER, StorageFilter.NONE, ButtonToolTips.ReportInaccessibleItems,
|
||||
ButtonToolTips.ReportInaccessibleItemsYes);
|
||||
|
||||
registerApp(16 * 14, Settings.PLACE_BLOCK, YesNo.YES, ButtonToolTips.BlockPlacement,
|
||||
ButtonToolTips.BlockPlacementYes);
|
||||
registerApp(16 * 14 + 1, Settings.PLACE_BLOCK, YesNo.NO, ButtonToolTips.BlockPlacement,
|
||||
ButtonToolTips.BlockPlacementNo);
|
||||
|
||||
registerApp(16 * 15, Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeDefault);
|
||||
registerApp(16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeRoundRobin);
|
||||
registerApp(16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode,
|
||||
ButtonToolTips.SchedulingModeRandom);
|
||||
}
|
||||
}
|
||||
|
||||
private static void onPress(ButtonWidget btn) {
|
||||
if (btn instanceof SettingToggleButton) {
|
||||
((SettingToggleButton<?>) btn).triggerPress();
|
||||
}
|
||||
}
|
||||
|
||||
private void triggerPress() {
|
||||
boolean backwards = MinecraftClient.getInstance().mouse.wasRightButtonClicked();
|
||||
onPress.handle(this, backwards);
|
||||
}
|
||||
|
||||
private static void registerApp(final int iconIndex, final Settings setting, final Enum<?> val,
|
||||
final ButtonToolTips title, final Text hint) {
|
||||
final ButtonAppearance a = new ButtonAppearance();
|
||||
a.displayName = title.text();
|
||||
a.displayValue = hint;
|
||||
a.index = iconIndex;
|
||||
appearances.put(new EnumPair(setting, val), a);
|
||||
}
|
||||
|
||||
private static void registerApp(final int iconIndex, final Settings setting, final Enum<?> val,
|
||||
final ButtonToolTips title, final ButtonToolTips hint) {
|
||||
registerApp(iconIndex, setting, val, title, hint.text());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIconIndex() {
|
||||
if (this.buttonSetting != null && this.currentValue != null) {
|
||||
final ButtonAppearance app = appearances.get(new EnumPair(this.buttonSetting, this.currentValue));
|
||||
if (app == null) {
|
||||
return 256 - 1;
|
||||
}
|
||||
return app.index;
|
||||
}
|
||||
return 256 - 1;
|
||||
}
|
||||
|
||||
public Settings getSetting() {
|
||||
return this.buttonSetting;
|
||||
}
|
||||
|
||||
public T getCurrentValue() {
|
||||
return this.currentValue;
|
||||
}
|
||||
|
||||
public void set(final T e) {
|
||||
if (this.currentValue != e) {
|
||||
this.currentValue = e;
|
||||
}
|
||||
}
|
||||
|
||||
public T getNextValue(boolean backwards) {
|
||||
return EnumCycler.rotateEnum(currentValue, backwards, validValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
Text displayName = null;
|
||||
Text displayValue = null;
|
||||
|
||||
if (this.buttonSetting != null && this.currentValue != null) {
|
||||
final ButtonAppearance buttonAppearance = appearances
|
||||
.get(new EnumPair(this.buttonSetting, this.currentValue));
|
||||
if (buttonAppearance == null) {
|
||||
return new LiteralText("No Such Message");
|
||||
}
|
||||
|
||||
displayName = buttonAppearance.displayName;
|
||||
displayValue = buttonAppearance.displayValue;
|
||||
}
|
||||
|
||||
if (displayName != null) {
|
||||
String name = displayName.getString();
|
||||
String value = displayValue.getString();
|
||||
|
||||
if (this.fillVar != null) {
|
||||
value = COMPILE.matcher(value).replaceFirst(this.fillVar);
|
||||
}
|
||||
|
||||
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 new LiteralText(name + '\n' + sb);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getFillVar() {
|
||||
return this.fillVar;
|
||||
}
|
||||
|
||||
public void setFillVar(final String fillVar) {
|
||||
this.fillVar = fillVar;
|
||||
}
|
||||
|
||||
private static final class EnumPair {
|
||||
|
||||
final Settings setting;
|
||||
final Enum<?> value;
|
||||
|
||||
EnumPair(final Settings a, final Enum<?> b) {
|
||||
this.setting = a;
|
||||
this.value = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.setting.hashCode() ^ this.value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final EnumPair other = (EnumPair) obj;
|
||||
return other.setting == this.setting && other.value == this.value;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ButtonAppearance {
|
||||
public int index;
|
||||
public Text displayName;
|
||||
public Text displayValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.ButtonWidget;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class TabButton extends ButtonWidget implements ITooltip {
|
||||
public static final Identifier TEXTURE_STATES = new Identifier("appliedenergistics2",
|
||||
"textures/guis/states.png");
|
||||
private final ItemRenderer itemRenderer;
|
||||
private int hideEdge = 0;
|
||||
private int myIcon = -1;
|
||||
private ItemStack myItem;
|
||||
|
||||
public TabButton(final int x, final int y, final int ico, final Text message, final ItemRenderer ir,
|
||||
PressAction onPress) {
|
||||
super(x, y, 22, 22, message, onPress);
|
||||
|
||||
this.myIcon = ico;
|
||||
this.itemRenderer = ir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using itemstack as an icon
|
||||
*
|
||||
* @param x x pos of button
|
||||
* @param y y pos of button
|
||||
* @param ico used icon
|
||||
* @param message mouse over message
|
||||
* @param ir renderer
|
||||
*/
|
||||
public TabButton(final int x, final int y, final ItemStack ico, final Text message, final ItemRenderer ir,
|
||||
PressAction onPress) {
|
||||
super(x, y, 22, 22, message, onPress);
|
||||
this.myItem = ico;
|
||||
this.itemRenderer = ir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, final int x, final int y, float partial) {
|
||||
final MinecraftClient minecraft = MinecraftClient.getInstance();
|
||||
|
||||
if (this.visible) {
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
minecraft.getTextureManager().bindTexture(TEXTURE_STATES);
|
||||
|
||||
RenderSystem.enableAlphaTest();
|
||||
|
||||
int uv_x = (this.hideEdge > 0 ? 11 : 13);
|
||||
|
||||
final int offsetX = this.hideEdge > 0 ? 1 : 0;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, 0, 25, 22);
|
||||
|
||||
if (this.myIcon >= 0) {
|
||||
final int uv_y = this.myIcon / 16;
|
||||
uv_x = this.myIcon - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
|
||||
}
|
||||
|
||||
RenderSystem.disableAlphaTest();
|
||||
|
||||
if (this.myItem != null) {
|
||||
this.itemRenderer.zOffset = 100.0F;
|
||||
this.itemRenderer.renderInGuiWithOverrides(this.myItem, offsetX + this.x + 3, this.y + 3);
|
||||
this.itemRenderer.zOffset = 0.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int xPos() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int yPos() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 22;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 22;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
public int getHideEdge() {
|
||||
return this.hideEdge;
|
||||
}
|
||||
|
||||
public void setHideEdge(final int hideEdge) {
|
||||
this.hideEdge = hideEdge;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.regex.Pattern;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ToggleButton extends ButtonWidget implements ITooltip {
|
||||
public static final Identifier TEXTURE_STATES = new Identifier("appliedenergistics2",
|
||||
"textures/guis/states.png");
|
||||
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
|
||||
private final int iconIdxOn;
|
||||
private final int iconIdxOff;
|
||||
|
||||
private final Text displayName;
|
||||
private final Text displayHint;
|
||||
|
||||
private boolean isActive;
|
||||
|
||||
public ToggleButton(final int x, final int y, final int on, final int off, final Text displayName,
|
||||
final Text displayHint, PressAction onPress) {
|
||||
super(x, y, 16, 16, LiteralText.EMPTY, onPress);
|
||||
this.iconIdxOn = on;
|
||||
this.iconIdxOff = off;
|
||||
this.displayName = displayName;
|
||||
this.displayHint = displayHint;
|
||||
}
|
||||
|
||||
public void setState(final boolean isOn) {
|
||||
this.isActive = isOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, final int mouseX, final int mouseY, final float partial) {
|
||||
if (this.visible) {
|
||||
final int iconIndex = this.getIconIndex();
|
||||
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
MinecraftClient.getInstance().getTextureManager().bindTexture(TEXTURE_STATES);
|
||||
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
|
||||
}
|
||||
}
|
||||
|
||||
private int getIconIndex() {
|
||||
return this.isActive ? this.iconIdxOn : this.iconIdxOff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
if (this.displayName != null) {
|
||||
String name = this.displayName.getString();
|
||||
String value = this.displayHint.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 new LiteralText(name + '\n' + sb);
|
||||
}
|
||||
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 this.visible;
|
||||
}
|
||||
}
|
||||
@@ -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.me;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
|
||||
public class ClientDCInternalInv implements Comparable<ClientDCInternalInv> {
|
||||
|
||||
private final String searchName;
|
||||
private final String formattedName;
|
||||
private final AppEngInternalInventory inventory;
|
||||
|
||||
private final long id;
|
||||
private final long sortBy;
|
||||
|
||||
public ClientDCInternalInv(final int size, final long id, final long sortBy, final Text name) {
|
||||
this.inventory = new AppEngInternalInventory(null, size);
|
||||
this.searchName = name.getString().toLowerCase();
|
||||
this.formattedName = name.getString(); // FIXME FABRIC no longer formatted!
|
||||
this.id = id;
|
||||
this.sortBy = sortBy;
|
||||
}
|
||||
|
||||
public String getSearchName() {
|
||||
return searchName;
|
||||
}
|
||||
|
||||
public String getFormattedName() {
|
||||
return formattedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull final ClientDCInternalInv o) {
|
||||
return Long.compare(this.sortBy, o.sortBy);
|
||||
}
|
||||
|
||||
public AppEngInternalInventory getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public boolean matchesSearch(String searchFilterLowerCase) {
|
||||
return this.searchName.contains(searchFilterLowerCase);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2018, 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.me;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.SortOrder;
|
||||
import appeng.api.config.ViewItems;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.client.gui.widgets.IScrollSource;
|
||||
import appeng.client.gui.widgets.ISortSource;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.fluids.util.FluidSorters;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.prioritylist.IPartitionList;
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 22/05/2018
|
||||
* @since rv6 22/05/2018
|
||||
*/
|
||||
public class FluidRepo {
|
||||
private final IItemList<IAEFluidStack> list = AEApi.instance().storage()
|
||||
.getStorageChannel(IFluidStorageChannel.class).createList();
|
||||
private final ArrayList<IAEFluidStack> view = new ArrayList<>();
|
||||
private final IScrollSource src;
|
||||
private final ISortSource sortSrc;
|
||||
|
||||
private int rowSize = 9;
|
||||
|
||||
private String searchString = "";
|
||||
private IPartitionList<IAEFluidStack> myPartitionList;
|
||||
private boolean hasPower;
|
||||
|
||||
public FluidRepo(final IScrollSource src, final ISortSource sortSrc) {
|
||||
this.src = src;
|
||||
this.sortSrc = sortSrc;
|
||||
}
|
||||
|
||||
public void updateView() {
|
||||
this.view.clear();
|
||||
|
||||
this.view.ensureCapacity(this.list.size());
|
||||
|
||||
String innerSearch = this.searchString;
|
||||
|
||||
boolean searchMod = false;
|
||||
if (innerSearch.startsWith("@")) {
|
||||
searchMod = true;
|
||||
innerSearch = innerSearch.substring(1);
|
||||
}
|
||||
|
||||
Pattern m;
|
||||
try {
|
||||
m = Pattern.compile(innerSearch.toLowerCase(), Pattern.CASE_INSENSITIVE);
|
||||
} catch (final Exception ignore1) {
|
||||
try {
|
||||
m = Pattern.compile(Pattern.quote(innerSearch.toLowerCase()), Pattern.CASE_INSENSITIVE);
|
||||
} catch (final Exception ignore2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final Enum viewMode = this.sortSrc.getSortDisplay();
|
||||
final boolean needsZeroCopy = viewMode == ViewItems.CRAFTABLE;
|
||||
final boolean terminalSearchToolTips = AEConfig.instance().getSearchTooltips() != YesNo.NO;
|
||||
|
||||
boolean notDone = false;
|
||||
for (IAEFluidStack fs : this.list) {
|
||||
if (this.myPartitionList != null && !this.myPartitionList.isListed(fs)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (viewMode == ViewItems.CRAFTABLE && !fs.isCraftable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (viewMode == ViewItems.STORED && fs.getStackSize() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String dspName = searchMod ? Platform.getModId(fs) : Platform.getFluidDisplayName(fs).getString();
|
||||
boolean foundMatchingFluidStack = false;
|
||||
notDone = true;
|
||||
|
||||
if (m.matcher(dspName.toLowerCase()).find()) {
|
||||
notDone = false;
|
||||
foundMatchingFluidStack = true;
|
||||
}
|
||||
|
||||
if (terminalSearchToolTips && notDone && !searchMod) {
|
||||
final List<Text> tooltip = Platform.getTooltip(fs);
|
||||
|
||||
for (final Text line : tooltip) {
|
||||
if (m.matcher(line.getString()).find()) {
|
||||
foundMatchingFluidStack = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMatchingFluidStack) {
|
||||
if (needsZeroCopy) {
|
||||
fs = fs.copy();
|
||||
fs.setStackSize(0);
|
||||
}
|
||||
|
||||
this.view.add(fs);
|
||||
}
|
||||
}
|
||||
|
||||
final Enum sortBy = this.sortSrc.getSortBy();
|
||||
final Enum sortDir = this.sortSrc.getSortDir();
|
||||
|
||||
FluidSorters.setDirection((appeng.api.config.SortDir) sortDir);
|
||||
|
||||
if (sortBy == SortOrder.MOD) {
|
||||
Collections.sort(this.view, FluidSorters.CONFIG_BASED_SORT_BY_MOD);
|
||||
} else if (sortBy == SortOrder.AMOUNT) {
|
||||
Collections.sort(this.view, FluidSorters.CONFIG_BASED_SORT_BY_SIZE);
|
||||
} else {
|
||||
Collections.sort(this.view, FluidSorters.CONFIG_BASED_SORT_BY_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
public void postUpdate(final IAEFluidStack is) {
|
||||
final IAEFluidStack st = this.list.findPrecise(is);
|
||||
|
||||
if (st != null) {
|
||||
st.reset();
|
||||
st.add(is);
|
||||
} else {
|
||||
this.list.add(is);
|
||||
}
|
||||
}
|
||||
|
||||
public IAEFluidStack getReferenceFluid(int idx) {
|
||||
idx += this.src.getCurrentScroll() * this.rowSize;
|
||||
|
||||
if (idx >= this.view.size()) {
|
||||
return null;
|
||||
}
|
||||
return this.view.get(idx);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.view.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.list.resetStatus();
|
||||
}
|
||||
|
||||
public boolean hasPower() {
|
||||
return this.hasPower;
|
||||
}
|
||||
|
||||
public void setPower(final boolean hasPower) {
|
||||
this.hasPower = hasPower;
|
||||
}
|
||||
|
||||
public int getRowSize() {
|
||||
return this.rowSize;
|
||||
}
|
||||
|
||||
public void setRowSize(final int rowSize) {
|
||||
this.rowSize = rowSize;
|
||||
}
|
||||
|
||||
public String getSearchString() {
|
||||
return this.searchString;
|
||||
}
|
||||
|
||||
public void setSearchString(@Nonnull final String searchString) {
|
||||
this.searchString = searchString;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2018, 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.me;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 22/05/2018
|
||||
* @since rv6 22/05/2018
|
||||
*/
|
||||
public class InternalFluidSlotME {
|
||||
|
||||
private final int offset;
|
||||
private final int xPos;
|
||||
private final int yPos;
|
||||
private final FluidRepo repo;
|
||||
|
||||
public InternalFluidSlotME(final FluidRepo def, final int offset, final int displayX, final int displayY) {
|
||||
this.repo = def;
|
||||
this.offset = offset;
|
||||
this.xPos = displayX;
|
||||
this.yPos = displayY;
|
||||
}
|
||||
|
||||
IAEFluidStack getAEStack() {
|
||||
return this.repo.getReferenceFluid(this.offset);
|
||||
}
|
||||
|
||||
boolean hasPower() {
|
||||
return this.repo.hasPower();
|
||||
}
|
||||
|
||||
int getxPosition() {
|
||||
return this.xPos;
|
||||
}
|
||||
|
||||
int getyPosition() {
|
||||
return this.yPos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.me;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
|
||||
public class InternalSlotME {
|
||||
|
||||
private final int offset;
|
||||
private final int xPos;
|
||||
private final int yPos;
|
||||
private final ItemRepo repo;
|
||||
|
||||
public InternalSlotME(final ItemRepo def, final int offset, final int displayX, final int displayY) {
|
||||
this.repo = def;
|
||||
this.offset = offset;
|
||||
this.xPos = displayX;
|
||||
this.yPos = displayY;
|
||||
}
|
||||
|
||||
ItemStack getStack() {
|
||||
return this.getAEStack() == null ? ItemStack.EMPTY : this.getAEStack().asItemStackRepresentation();
|
||||
}
|
||||
|
||||
IAEItemStack getAEStack() {
|
||||
return this.repo.getReferenceItem(this.offset);
|
||||
}
|
||||
|
||||
boolean hasPower() {
|
||||
return this.repo.hasPower();
|
||||
}
|
||||
|
||||
int getxPosition() {
|
||||
return this.xPos;
|
||||
}
|
||||
|
||||
int getyPosition() {
|
||||
return this.yPos;
|
||||
}
|
||||
}
|
||||
@@ -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.client.me;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.SearchBoxMode;
|
||||
import appeng.api.config.SortOrder;
|
||||
import appeng.api.config.ViewItems;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.client.gui.widgets.IScrollSource;
|
||||
import appeng.client.gui.widgets.ISortSource;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.integration.abstraction.JEIFacade;
|
||||
import appeng.items.storage.ViewCellItem;
|
||||
import appeng.util.ItemSorters;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.prioritylist.IPartitionList;
|
||||
|
||||
public class ItemRepo {
|
||||
|
||||
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
|
||||
.createList();
|
||||
private final ArrayList<IAEItemStack> view = new ArrayList<>();
|
||||
private final IScrollSource src;
|
||||
private final ISortSource sortSrc;
|
||||
|
||||
private int rowSize = 9;
|
||||
|
||||
private String searchString = "";
|
||||
private IPartitionList<IAEItemStack> myPartitionList;
|
||||
private String innerSearch = "";
|
||||
private boolean hasPower;
|
||||
|
||||
public ItemRepo(final IScrollSource src, final ISortSource sortSrc) {
|
||||
this.src = src;
|
||||
this.sortSrc = sortSrc;
|
||||
}
|
||||
|
||||
public IAEItemStack getReferenceItem(int idx) {
|
||||
idx += this.src.getCurrentScroll() * this.rowSize;
|
||||
|
||||
if (idx >= this.view.size()) {
|
||||
return null;
|
||||
}
|
||||
return this.view.get(idx);
|
||||
}
|
||||
|
||||
void setSearch(final String search) {
|
||||
this.searchString = search == null ? "" : search;
|
||||
}
|
||||
|
||||
public void postUpdate(final IAEItemStack is) {
|
||||
final IAEItemStack st = this.list.findPrecise(is);
|
||||
|
||||
if (st != null) {
|
||||
st.reset();
|
||||
st.add(is);
|
||||
} else {
|
||||
this.list.add(is);
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewCell(final ItemStack[] list) {
|
||||
this.myPartitionList = ViewCellItem.createFilter(list);
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
public void updateView() {
|
||||
this.view.clear();
|
||||
|
||||
this.view.ensureCapacity(this.list.size());
|
||||
|
||||
ViewItems viewMode = this.sortSrc.getSortDisplay();
|
||||
SearchBoxMode searchMode = AEConfig.instance().getTerminalSearchMode();
|
||||
final boolean needsZeroCopy = viewMode == ViewItems.CRAFTABLE;
|
||||
|
||||
if (searchMode == SearchBoxMode.JEI_AUTOSEARCH || searchMode == SearchBoxMode.JEI_MANUAL_SEARCH
|
||||
|| searchMode == SearchBoxMode.JEI_AUTOSEARCH_KEEP
|
||||
|| searchMode == SearchBoxMode.JEI_MANUAL_SEARCH_KEEP) {
|
||||
this.updateJEI(this.searchString);
|
||||
}
|
||||
|
||||
this.innerSearch = this.searchString;
|
||||
final boolean terminalSearchToolTips = AEConfig.instance().getSearchTooltips() != YesNo.NO;
|
||||
|
||||
boolean searchMod = false;
|
||||
if (this.innerSearch.startsWith("@")) {
|
||||
searchMod = true;
|
||||
this.innerSearch = this.innerSearch.substring(1);
|
||||
}
|
||||
|
||||
Pattern m = null;
|
||||
try {
|
||||
m = Pattern.compile(this.innerSearch.toLowerCase(), Pattern.CASE_INSENSITIVE);
|
||||
} catch (final Throwable ignore) {
|
||||
try {
|
||||
m = Pattern.compile(Pattern.quote(this.innerSearch.toLowerCase()), Pattern.CASE_INSENSITIVE);
|
||||
} catch (final Throwable __) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
boolean notDone = false;
|
||||
for (IAEItemStack is : this.list) {
|
||||
if (this.myPartitionList != null) {
|
||||
if (!this.myPartitionList.isListed(is)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (viewMode == ViewItems.CRAFTABLE && !is.isCraftable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (viewMode == ViewItems.STORED && is.getStackSize() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String dspName = searchMod ? Platform.getModId(is) : Platform.getItemDisplayName(is).getString();
|
||||
boolean foundMatchingItemStack = false;
|
||||
notDone = true;
|
||||
|
||||
if (m.matcher(dspName.toLowerCase()).find()) {
|
||||
notDone = false;
|
||||
foundMatchingItemStack = true;
|
||||
}
|
||||
|
||||
if (terminalSearchToolTips && notDone && !searchMod) {
|
||||
final List<Text> tooltip = Platform.getTooltip(is);
|
||||
|
||||
for (final Text line : tooltip) {
|
||||
if (m.matcher(line.getString()).find()) {
|
||||
foundMatchingItemStack = true;
|
||||
notDone = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMatchingItemStack) {
|
||||
if (needsZeroCopy) {
|
||||
is = is.copy();
|
||||
is.setStackSize(0);
|
||||
}
|
||||
|
||||
this.view.add(is);
|
||||
}
|
||||
}
|
||||
|
||||
final Enum SortBy = this.sortSrc.getSortBy();
|
||||
final Enum SortDir = this.sortSrc.getSortDir();
|
||||
|
||||
ItemSorters.setDirection((appeng.api.config.SortDir) SortDir);
|
||||
|
||||
if (SortBy == SortOrder.MOD) {
|
||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_MOD);
|
||||
} else if (SortBy == SortOrder.AMOUNT) {
|
||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_SIZE);
|
||||
} else {
|
||||
Collections.sort(this.view, ItemSorters.CONFIG_BASED_SORT_BY_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateJEI(String filter) {
|
||||
JEIFacade.instance().setSearchText(filter);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.view.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.list.resetStatus();
|
||||
}
|
||||
|
||||
public boolean hasPower() {
|
||||
return this.hasPower;
|
||||
}
|
||||
|
||||
public void setPower(final boolean hasPower) {
|
||||
this.hasPower = hasPower;
|
||||
}
|
||||
|
||||
public int getRowSize() {
|
||||
return this.rowSize;
|
||||
}
|
||||
|
||||
public void setRowSize(final int rowSize) {
|
||||
this.rowSize = rowSize;
|
||||
}
|
||||
|
||||
public String getSearchString() {
|
||||
return this.searchString;
|
||||
}
|
||||
|
||||
public void setSearchString(@Nonnull final String searchString) {
|
||||
this.searchString = searchString;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.me;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
import appeng.items.misc.EncodedPatternItem;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class SlotDisconnected extends AppEngSlot {
|
||||
|
||||
private final ClientDCInternalInv mySlot;
|
||||
|
||||
public SlotDisconnected(final ClientDCInternalInv me, final int which, final int x, final int y) {
|
||||
super(me.getInventory(), which, x, y);
|
||||
this.mySlot = me;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert(final ItemStack par1ItemStack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(final ItemStack par1ItemStack) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItems(final PlayerEntity par1PlayerEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDisplayStack() {
|
||||
if (Platform.isClient()) {
|
||||
final ItemStack is = super.getStack();
|
||||
if (!is.isEmpty() && is.getItem() instanceof EncodedPatternItem) {
|
||||
final EncodedPatternItem iep = (EncodedPatternItem) is.getItem();
|
||||
final ItemStack out = iep.getOutput(MinecraftClient.getInstance().world, is);
|
||||
if (!out.isEmpty()) {
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStack() {
|
||||
return !this.getStack().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackAmount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack takeStack(final int par1) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public ClientDCInternalInv getSlot() {
|
||||
return this.mySlot;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2018, 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.me;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.fluids.container.slots.IMEFluidSlot;
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 22/05/2018
|
||||
* @since rv6 22/05/2018
|
||||
*/
|
||||
public class SlotFluidME extends Slot implements IMEFluidSlot {
|
||||
|
||||
private final InternalFluidSlotME slot;
|
||||
|
||||
public SlotFluidME(InternalFluidSlotME slot) {
|
||||
super(null, 0, slot.getxPosition(), slot.getyPosition());
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack getAEFluidStack() {
|
||||
if (this.slot.hasPower()) {
|
||||
return this.slot.getAEStack();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStack() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStack() {
|
||||
if (this.slot.hasPower()) {
|
||||
return this.getAEFluidStack() != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(final ItemStack par1ItemStack) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackAmount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack takeStack(final int par1) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItems(final PlayerEntity par1PlayerEntity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -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.me;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
|
||||
public class SlotME extends Slot {
|
||||
|
||||
private final InternalSlotME mySlot;
|
||||
|
||||
public SlotME(final InternalSlotME me) {
|
||||
super(null, 0, me.getxPosition(), me.getyPosition());
|
||||
this.mySlot = me;
|
||||
}
|
||||
|
||||
public IAEItemStack getAEStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
return this.mySlot.getAEStack();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
return this.mySlot.getStack();
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
return !this.getStack().isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(ItemStack stack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackAmount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack takeStack(final int par1) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItems(final PlayerEntity par1PlayerEntity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.render;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.AffineTransformation;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.util.ISlimReadableNumberConverter;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv0
|
||||
*/
|
||||
public class StackSizeRenderer {
|
||||
private static final ISlimReadableNumberConverter SLIM_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
private static final IWideReadableNumberConverter WIDE_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
|
||||
public void renderStackSize(TextRenderer fontRenderer, IAEItemStack aeStack, int xPos, int yPos) {
|
||||
if (aeStack != null) {
|
||||
if (aeStack.getStackSize() == 0 && aeStack.isCraftable()) {
|
||||
final String craftLabelText = AEConfig.instance().isUseLargeFonts() ? GuiText.LargeFontCraft.getLocal()
|
||||
: GuiText.SmallFontCraft.getLocal();
|
||||
|
||||
renderSizeLabel(fontRenderer, xPos, yPos, craftLabelText);
|
||||
}
|
||||
|
||||
if (aeStack.getStackSize() > 0) {
|
||||
final String stackSize = this.getToBeRenderedStackSize(aeStack.getStackSize());
|
||||
|
||||
renderSizeLabel(fontRenderer, xPos, yPos, stackSize);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderSizeLabel(TextRenderer fontRenderer, float xPos, float yPos, String text) {
|
||||
|
||||
final float scaleFactor = AEConfig.instance().isUseLargeFonts() ? 0.85f : 0.5f;
|
||||
final float inverseScaleFactor = 1.0f / scaleFactor;
|
||||
final int offset = AEConfig.instance().isUseLargeFonts() ? 0 : -1;
|
||||
|
||||
AffineTransformation tm = new AffineTransformation(new Vector3f(0, 0, 300), // Taken from
|
||||
// ItemRenderer.renderItemOverlayIntoGUI
|
||||
null, new Vector3f(scaleFactor, scaleFactor, scaleFactor), null);
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
final int X = (int) ((xPos + offset + 16.0f - fontRenderer.getWidth(text) * scaleFactor)
|
||||
* inverseScaleFactor);
|
||||
final int Y = (int) ((yPos + offset + 16.0f - 7.0f * scaleFactor) * inverseScaleFactor);
|
||||
VertexConsumerProvider.Immediate buffer = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
|
||||
fontRenderer.draw(text, X, Y, 16777215, true, tm.getMatrix(), buffer, false, 0, 15728880);
|
||||
buffer.draw();
|
||||
RenderSystem.enableBlend();
|
||||
}
|
||||
|
||||
private String getToBeRenderedStackSize(final long originalSize) {
|
||||
if (AEConfig.instance().isUseLargeFonts()) {
|
||||
return SLIM_CONVERTER.toSlimReadableForm(originalSize);
|
||||
} else {
|
||||
return WIDE_CONVERTER.toWideReadableForm(originalSize);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.render;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.color.block.BlockColorProvider;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
import appeng.api.util.AEColor;
|
||||
|
||||
/**
|
||||
* Returns the shades of a single AE color for tint indices 0, 1, and 2.
|
||||
*/
|
||||
public class StaticBlockColor implements BlockColorProvider {
|
||||
|
||||
private final AEColor color;
|
||||
|
||||
public StaticBlockColor(AEColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(BlockState state, @Nullable BlockRenderView worldIn, @Nullable BlockPos pos, int tintIndex) {
|
||||
return this.color.getVariantByTintIndex(tintIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.render;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
|
||||
/**
|
||||
* Helper methods for rendering TESRs.
|
||||
*/
|
||||
public class TesrRenderHelper {
|
||||
|
||||
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
|
||||
/**
|
||||
* Rotate the current coordinate system so it is on the face of the given block
|
||||
* side. This can be used to render on the given face as if it was a 2D canvas.
|
||||
*/
|
||||
public static void rotateToFace(MatrixStack mStack, Direction face, byte spin) {
|
||||
switch (face) {
|
||||
case UP:
|
||||
mStack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(270));
|
||||
mStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(-spin * 90.0F));
|
||||
break;
|
||||
|
||||
case DOWN:
|
||||
mStack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90.0F));
|
||||
mStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(spin * -90.0F));
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90.0F));
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-90.0F));
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(180.0F));
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO, A different approach will have to be used for this from TESRs, -covers,
|
||||
// i have ideas.
|
||||
/**
|
||||
* Render an item in 2D.
|
||||
*/
|
||||
public static void renderItem2d(MatrixStack matrixStack, VertexConsumerProvider buffers, ItemStack itemStack,
|
||||
float scale, int combinedLightIn, int combinedOverlayIn) {
|
||||
if (!itemStack.isEmpty()) {
|
||||
matrixStack.push();
|
||||
// Push it out of the block face a bit to avoid z-fighting
|
||||
matrixStack.translate(0, 0, 0.01f);
|
||||
// The Z-scaling by 0.0002 causes the model to be visually "flattened"
|
||||
// This cannot replace a proper projection, but it's cheap and gives the desired
|
||||
// effect at least from head-on
|
||||
matrixStack.scale(scale, scale, 0.0002f);
|
||||
|
||||
MinecraftClient.getInstance().getItemRenderer().renderItem(itemStack, ModelTransformation.Mode.GUI,
|
||||
combinedLightIn, OverlayTexture.DEFAULT_UV, matrixStack, buffers);
|
||||
|
||||
matrixStack.pop();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an item in 2D and the given text below it.
|
||||
*
|
||||
* @param matrixStack
|
||||
* @param buffers
|
||||
* @param spacing Specifies how far apart the item and the item stack
|
||||
* amount are rendered.
|
||||
* @param combinedLightIn
|
||||
* @param combinedOverlayIn
|
||||
*/
|
||||
public static void renderItem2dWithAmount(MatrixStack matrixStack, VertexConsumerProvider buffers,
|
||||
IAEItemStack itemStack, float itemScale, float spacing, int combinedLightIn, int combinedOverlayIn) {
|
||||
final ItemStack renderStack = itemStack.asItemStackRepresentation();
|
||||
|
||||
TesrRenderHelper.renderItem2d(matrixStack, buffers, renderStack, itemScale, combinedLightIn, combinedOverlayIn);
|
||||
|
||||
final long stackSize = itemStack.getStackSize();
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm(stackSize);
|
||||
|
||||
// Render the item count
|
||||
final TextRenderer fr = MinecraftClient.getInstance().textRenderer;
|
||||
final int width = fr.getWidth(renderedStackSize);
|
||||
matrixStack.push();
|
||||
matrixStack.translate(0.0f, spacing, 0.02f);
|
||||
matrixStack.scale(1.0f / 62.0f, -1.0f / 62.0f, 1.0f / 62.0f);
|
||||
matrixStack.scale(0.5f, 0.5f, 0);
|
||||
matrixStack.translate(-0.5f * width, 0.0f, 0.5f);
|
||||
fr.draw(renderedStackSize, 0, 0, -1, false, matrixStack.peek().getModel(), buffers, false, 0,
|
||||
15728880);
|
||||
matrixStack.pop();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.render.crafting;
|
||||
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
|
||||
/**
|
||||
* Rendering customization for the crafting cube.
|
||||
*/
|
||||
public class CraftingCubeRendering extends BlockRenderingCustomizer {
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderLayer.getCutout());
|
||||
// Disable auto-rotation
|
||||
rendering.modelCustomizer((loc, model) -> model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
|
||||
public class DriveModelData extends AEModelData {
|
||||
|
||||
private final DriveSlotsState slotsState;
|
||||
|
||||
public DriveModelData(Direction up, Direction forward, DriveSlotsState slotsState) {
|
||||
super(up, forward);
|
||||
this.slotsState = slotsState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCacheable() {
|
||||
return false; // Too many combinations
|
||||
}
|
||||
|
||||
public DriveSlotsState getSlotsState() {
|
||||
return slotsState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
DriveModelData that = (DriveModelData) o;
|
||||
return slotsState.equals(that.slotsState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), slotsState);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.render.renderable;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.render.model.json.Transformation;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ItemRenderable<T extends BlockEntity> implements Renderable<T> {
|
||||
|
||||
private final Function<T, Pair<ItemStack, Transformation>> f;
|
||||
|
||||
public ItemRenderable(Function<T, Pair<ItemStack, Transformation>> f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityAt(T te, float partialTicks, net.minecraft.client.util.math.MatrixStack matrixStack,
|
||||
VertexConsumerProvider buffers, int combinedLight, int combinedOverlay) {
|
||||
Pair<ItemStack, Transformation> pair = this.f.apply(te);
|
||||
if (pair != null && pair.getLeft() != null) {
|
||||
matrixStack.push();
|
||||
if (pair.getRight() != null) {
|
||||
pair.getRight().apply(true, matrixStack); // FIXME: check left handed
|
||||
}
|
||||
MinecraftClient.getInstance().getItemRenderer().renderItem(pair.getLeft(),
|
||||
ModelTransformation.Mode.GROUND, combinedLight, combinedOverlay, matrixStack, buffers);
|
||||
matrixStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.render.renderable;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
|
||||
public interface Renderable<T extends BlockEntity> {
|
||||
|
||||
void renderTileEntityAt(T te, float partialTicks, MatrixStack matrixStack, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay);
|
||||
|
||||
}
|
||||
@@ -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.render.spatial;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
|
||||
public class SpatialPylonRendering extends BlockRenderingCustomizer {
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderLayer.getCutout());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.client.render.tesr;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.TexturedRenderLayers;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.tile.grindstone.CrankBlockEntity;
|
||||
|
||||
/**
|
||||
* This FastTESR only handles the animated model of the turning crank. When the
|
||||
* crank is at rest, it is rendered using a normal model.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class CrankTESR extends BlockEntityRenderer<CrankBlockEntity> {
|
||||
|
||||
public CrankTESR(BlockEntityRenderDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(CrankBlockEntity te, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
|
||||
int combinedLightIn, int combinedOverlayIn) {
|
||||
|
||||
// Apply GL transformations relative to the center of the block: 1) TE rotation
|
||||
// and 2) crank rotation
|
||||
ms.push();
|
||||
ms.translate(0.5, 0.5, 0.5);
|
||||
FacingToRotation.get(te.getForward(), te.getUp()).push(ms);
|
||||
ms.multiply(new Quaternion(0, te.getVisibleRotation(), 0, true));
|
||||
ms.translate(-0.5, -0.5, -0.5);
|
||||
|
||||
BlockState blockState = te.getCachedState();
|
||||
BlockRenderManager dispatcher = MinecraftClient.getInstance().getBlockRenderManager();
|
||||
BakedModel model = dispatcher.getModel(blockState);
|
||||
VertexConsumer buffer = buffers.getBuffer(TexturedRenderLayers.getEntityTranslucentCull());
|
||||
dispatcher.getModelRenderer().render(ms.peek(), buffer, null, model, 1, 1, 1,
|
||||
combinedLightIn, combinedOverlayIn);
|
||||
ms.pop();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.tile.storage.DriveBlockEntity;
|
||||
|
||||
/**
|
||||
* Renders the drive cell status indicators.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class DriveLedTileEntityRenderer extends BlockEntityRenderer<DriveBlockEntity> {
|
||||
|
||||
private static final EnumMap<DriveSlotState, Vector3f> STATE_COLORS;
|
||||
|
||||
// Color used for the cell indicator for blinking during recent activity
|
||||
private static final Vector3f BLINK_COLOR = new Vector3f(1, 0.5f, 0.5f);
|
||||
|
||||
static {
|
||||
STATE_COLORS = new EnumMap<>(DriveSlotState.class);
|
||||
STATE_COLORS.put(DriveSlotState.OFFLINE, new Vector3f(0, 0, 0));
|
||||
STATE_COLORS.put(DriveSlotState.ONLINE, new Vector3f(0, 1, 0));
|
||||
STATE_COLORS.put(DriveSlotState.NOT_EMPTY, new Vector3f(0f, 0.667f, 1));
|
||||
STATE_COLORS.put(DriveSlotState.TYPES_FULL, new Vector3f(1, 0.667f, 0));
|
||||
STATE_COLORS.put(DriveSlotState.FULL, new Vector3f(1, 0, 0));
|
||||
}
|
||||
|
||||
private static final float L = 14 / 16.f; // left (x-axis)
|
||||
private static final float R = 13 / 16.f; // right (x-axis)
|
||||
private static final float T = 14 / 16.f; // top (x-axis)
|
||||
private static final float B = 12.999f / 16.f; // bottom (x-axis)
|
||||
private static final float FR = 0.999f / 16.f; // front (z-axis)
|
||||
private static final float BA = 1.499f / 16.f; // back (z-axis)
|
||||
|
||||
// Vertex data for the LED cuboid (has no back)
|
||||
// Directions are when looking from the front onto the LED
|
||||
private static final float[] LED_QUADS = {
|
||||
// Front Face
|
||||
R, T, FR, L, T, FR, L, B, FR, R, B, FR,
|
||||
// Left Face
|
||||
L, T, FR, L, T, BA, L, B, BA, L, B, FR,
|
||||
// Right Face
|
||||
R, T, BA, R, T, FR, R, B, FR, R, B, BA,
|
||||
// Top Face
|
||||
R, T, BA, L, T, BA, L, T, FR, R, T, FR,
|
||||
// Bottom Face
|
||||
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
|
||||
|
||||
private static final RenderLayer STATE = RenderLayer.of("ae_drive_leds", VertexFormats.POSITION_COLOR, 7,
|
||||
32565, false, true, RenderLayer.MultiPhaseParameters.builder().build(false));
|
||||
|
||||
public DriveLedTileEntityRenderer(BlockEntityRenderDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DriveBlockEntity drive, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
|
||||
int combinedLightIn, int combinedOverlayIn) {
|
||||
|
||||
if (drive.getCellCount() != 10) {
|
||||
throw new IllegalStateException("Expected drive to have 10 slots");
|
||||
}
|
||||
|
||||
ms.push();
|
||||
ms.translate(0.5, 0.5, 0.5);
|
||||
FacingToRotation.get(drive.getForward(), drive.getUp()).push(ms);
|
||||
ms.translate(-0.5, -0.5, -0.5);
|
||||
|
||||
VertexConsumer buffer = buffers.getBuffer(STATE);
|
||||
|
||||
for (int row = 0; row < 5; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
int slot = row * 2 + col;
|
||||
Vector3f color = getColorForSlot(drive, slot, partialTicks);
|
||||
if (color == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ms.push();
|
||||
|
||||
// Position this drive model copy at the correct slot. The transform is based on
|
||||
// the
|
||||
// cell-model being in slot 0,0 at the top left of the drive.
|
||||
float xOffset = -col * 8 / 16.0f;
|
||||
float yOffset = -row * 3 / 16.0f;
|
||||
ms.translate(xOffset, yOffset, 0);
|
||||
|
||||
for (int i = 0; i < LED_QUADS.length; i += 3) {
|
||||
float x = LED_QUADS[i];
|
||||
float y = LED_QUADS[i + 1];
|
||||
float z = LED_QUADS[i + 2];
|
||||
buffer.vertex(ms.peek().getModel(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
|
||||
.next();
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private Vector3f getColorForSlot(DriveBlockEntity drive, int slot, float partialTicks) {
|
||||
DriveSlotState state = DriveSlotState.fromCellStatus(drive.getCellStatus(slot));
|
||||
if (state == DriveSlotState.EMPTY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!drive.isPowered()) {
|
||||
return STATE_COLORS.get(DriveSlotState.OFFLINE);
|
||||
}
|
||||
|
||||
Vector3f col = STATE_COLORS.get(state);
|
||||
if (drive.isCellBlinking(slot)) {
|
||||
// 200 ms interval (100ms to get to red, then 100ms back)
|
||||
long t = System.currentTimeMillis() % 200;
|
||||
float f = (t - 100) / 200.0f + 0.5f;
|
||||
f = easeInOutCubic(f);
|
||||
col = col.copy();
|
||||
col.lerp(BLINK_COLOR, f);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
private static float easeInOutCubic(float x) {
|
||||
return x < 0.5f ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tag.ItemTags;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import appeng.api.features.InscriberProcessType;
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.recipes.handlers.InscriberRecipe;
|
||||
import appeng.tile.misc.InscriberBlockEntity;
|
||||
|
||||
/**
|
||||
* Renders the dynamic parts of an inscriber (the presses, the animation and the
|
||||
* item being smashed)
|
||||
*/
|
||||
public final class InscriberTESR extends BlockEntityRenderer<InscriberBlockEntity> {
|
||||
|
||||
private static final float ITEM_RENDER_SCALE = 1.0f / 1.2f;
|
||||
|
||||
private static final SpriteIdentifier TEXTURE_INSIDE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
new Identifier(AppEng.MOD_ID, "block/inscriber_inside"));
|
||||
|
||||
public static final ImmutableList<SpriteIdentifier> SPRITES = ImmutableList.of(
|
||||
TEXTURE_INSIDE
|
||||
);
|
||||
|
||||
public InscriberTESR(BlockEntityRenderDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(InscriberBlockEntity tile, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay) {
|
||||
|
||||
// render inscriber
|
||||
|
||||
ms.push();
|
||||
ms.translate(0.5F, 0.5F, 0.5F);
|
||||
FacingToRotation.get(tile.getForward(), tile.getUp()).push(ms);
|
||||
ms.translate(-0.5F, -0.5F, -0.5F);
|
||||
|
||||
// render sides of stamps
|
||||
|
||||
long absoluteProgress = 0;
|
||||
|
||||
if (tile.isSmash()) {
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
absoluteProgress = currentTime - tile.getClientStart();
|
||||
if (absoluteProgress > 800) {
|
||||
tile.setSmash(false);
|
||||
}
|
||||
}
|
||||
|
||||
final float relativeProgress = absoluteProgress % 800 / 400.0f;
|
||||
float progress = relativeProgress;
|
||||
|
||||
if (progress > 1.0f) {
|
||||
progress = 1.0f - (easeDecompressMotion(progress - 1.0f));
|
||||
} else {
|
||||
progress = easeCompressMotion(progress);
|
||||
}
|
||||
|
||||
float press = 0.2f;
|
||||
press -= progress / 5.0f;
|
||||
|
||||
float middle = 0.5f;
|
||||
middle += 0.02f;
|
||||
final float TwoPx = 2.0f / 16.0f;
|
||||
final float base = 0.4f;
|
||||
|
||||
final Sprite tas = TEXTURE_INSIDE.getSprite();
|
||||
|
||||
VertexConsumer buffer = buffers.getBuffer(RenderLayer.getSolid());
|
||||
|
||||
// Bottom of Top Stamp
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + press, TwoPx, 2, 13, combinedOverlay, combinedLight, Direction.DOWN);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + press, TwoPx, 14, 13, combinedOverlay, combinedLight,
|
||||
Direction.DOWN);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + press, 1.0f - TwoPx, 14, 2, combinedOverlay, combinedLight,
|
||||
Direction.DOWN);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + press, 1.0f - TwoPx, 2, 2, combinedOverlay, combinedLight,
|
||||
Direction.DOWN);
|
||||
|
||||
// Front of Top Stamp
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + base, TwoPx, 2, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + base, TwoPx, 14, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + press, TwoPx, 14, 3, combinedOverlay, combinedLight,
|
||||
Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + press, TwoPx, 2, 3, combinedOverlay, combinedLight, Direction.NORTH);
|
||||
|
||||
// Top of Bottom Stamp
|
||||
middle -= 2.0f * 0.02f;
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle - press, TwoPx, 2, 13, combinedOverlay, combinedLight,
|
||||
Direction.UP);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - press, TwoPx, 14, 13, combinedOverlay, combinedLight, Direction.UP);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - press, 1.0f - TwoPx, 14, 2, combinedOverlay, combinedLight,
|
||||
Direction.UP);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle - press, 1.0f - TwoPx, 2, 2, combinedOverlay, combinedLight,
|
||||
Direction.UP);
|
||||
|
||||
// Front of Bottom Stamp
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + -base, TwoPx, 2, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - base, TwoPx, 14, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - press, TwoPx, 14, 3, combinedOverlay, combinedLight,
|
||||
Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle - press, TwoPx, 2, 3, combinedOverlay, combinedLight,
|
||||
Direction.NORTH);
|
||||
|
||||
// render items.
|
||||
|
||||
FixedItemInv tileInv = tile.getInternalInventory();
|
||||
|
||||
int items = 0;
|
||||
if (!tileInv.getInvStack(0).isEmpty()) {
|
||||
items++;
|
||||
}
|
||||
if (!tileInv.getInvStack(1).isEmpty()) {
|
||||
items++;
|
||||
}
|
||||
if (!tileInv.getInvStack(2).isEmpty()) {
|
||||
items++;
|
||||
}
|
||||
|
||||
boolean renderPresses;
|
||||
if (relativeProgress > 1.0f || items == 0) {
|
||||
// When crafting completes, dont render the presses (they mave have been
|
||||
// consumed, see below)
|
||||
renderPresses = false;
|
||||
|
||||
ItemStack is = tileInv.getInvStack(3);
|
||||
|
||||
if (is.isEmpty()) {
|
||||
final InscriberRecipe ir = tile.getTask();
|
||||
if (ir != null) {
|
||||
// The "PRESS" type will consume the presses so they should not render after
|
||||
// completing
|
||||
// the press animation
|
||||
renderPresses = ir.getProcessType() == InscriberProcessType.INSCRIBE;
|
||||
is = ir.getOutput().copy();
|
||||
}
|
||||
}
|
||||
this.renderItem(ms, is, 0.0f, buffers, combinedLight, combinedOverlay);
|
||||
} else {
|
||||
renderPresses = true;
|
||||
this.renderItem(ms, tileInv.getInvStack(2), 0.0f, buffers, combinedLight, combinedOverlay);
|
||||
}
|
||||
|
||||
if (renderPresses) {
|
||||
this.renderItem(ms, tileInv.getInvStack(0), press, buffers, combinedLight, combinedOverlay);
|
||||
this.renderItem(ms, tileInv.getInvStack(1), -press, buffers, combinedLight, combinedOverlay);
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private static void addVertex(VertexConsumer vb, MatrixStack ms, Sprite sprite, float x, float y,
|
||||
float z, double texU, double texV, int overlayUV, int lightmapUV, Direction front) {
|
||||
vb.vertex(ms.peek().getModel(), x, y, z);
|
||||
vb.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
vb.texture(sprite.getFrameU(texU), sprite.getFrameV(texV));
|
||||
vb.overlay(overlayUV);
|
||||
vb.light(lightmapUV);
|
||||
vb.normal(ms.peek().getNormal(), front.getOffsetX(), front.getOffsetY(), front.getOffsetZ());
|
||||
vb.next();
|
||||
}
|
||||
|
||||
private static final Identifier TAG_STORAGE_BLOCKS = new Identifier("forge:storage_blocks");
|
||||
|
||||
private void renderItem(MatrixStack ms, final ItemStack stack, final float o, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay) {
|
||||
if (!stack.isEmpty()) {
|
||||
ms.push();
|
||||
// move to center
|
||||
ms.translate(0.5f, 0.5f + o, 0.5f);
|
||||
ms.multiply(new Quaternion(90, 0, 0, true));
|
||||
// set scale
|
||||
ms.scale(ITEM_RENDER_SCALE, ITEM_RENDER_SCALE, ITEM_RENDER_SCALE);
|
||||
|
||||
ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
|
||||
|
||||
// heuristic to scale items down much further than blocks
|
||||
Tag<Item> storageBlockTag = ItemTags.getContainer().get(TAG_STORAGE_BLOCKS);
|
||||
if (storageBlockTag == null || !stack.getItem().isIn(storageBlockTag)) {
|
||||
ms.scale(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
itemRenderer.renderItem(stack, ModelTransformation.Mode.FIXED, combinedLight, combinedOverlay, ms,
|
||||
buffers);
|
||||
ms.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// See https://easings.net/#easeOutBack
|
||||
private static float easeCompressMotion(float x) {
|
||||
float c1 = 1.70158f;
|
||||
float c3 = c1 + 1;
|
||||
|
||||
return (float) (1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2));
|
||||
}
|
||||
|
||||
// See https://easings.net/#easeInQuint
|
||||
private static float easeDecompressMotion(float x) {
|
||||
return x * x * x * x * x;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.client.render.tesr;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.client.render.renderable.Renderable;
|
||||
import appeng.tile.AEBaseBlockEntity;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ModularTESR<T extends AEBaseBlockEntity> extends BlockEntityRenderer<T> {
|
||||
|
||||
private final List<Renderable<? super T>> renderables;
|
||||
|
||||
@SafeVarargs
|
||||
public ModularTESR(BlockEntityRenderDispatcher rendererDispatcherIn, Renderable<? super T>... renderables) {
|
||||
super(rendererDispatcherIn);
|
||||
this.renderables = ImmutableList.copyOf(renderables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(T te, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers, int combinedLight,
|
||||
int combinedOverlay) {
|
||||
ms.push();
|
||||
ms.translate(0.5, 0.5, 0.5);
|
||||
FacingToRotation.get(te.getForward(), te.getUp()).push(ms);
|
||||
ms.translate(-0.5, -0.5, -0.5);
|
||||
for (Renderable<? super T> renderable : this.renderables) {
|
||||
renderable.renderTileEntityAt(te, partialTicks, ms, buffers, combinedLight, combinedOverlay);
|
||||
}
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,10 @@
|
||||
|
||||
package appeng.container;
|
||||
|
||||
import appeng.api.parts.IPartHost;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.parts.AEBasePart;
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
@@ -123,12 +126,11 @@ public final class ContainerLocator {
|
||||
throw new IllegalArgumentException("Could not find item held in hand " + hand + " in player inventory");
|
||||
}
|
||||
|
||||
// FIXME FABRIC public static ContainerLocator forPart(AEBasePart part) {
|
||||
// FIXME FABRIC IPartHost host = part.getHost();
|
||||
// FIXME FABRIC DimensionalCoord pos = host.getLocation();
|
||||
// FIXME FABRIC return new ContainerLocator(Type.PART, -1, pos.getWorld().getDimension().getType().getId(), pos.getBlockPos(),
|
||||
// FIXME FABRIC part.getSide());
|
||||
// FIXME FABRIC }
|
||||
public static ContainerLocator forPart(AEBasePart part) {
|
||||
IPartHost host = part.getHost();
|
||||
DimensionalCoord pos = host.getLocation();
|
||||
return new ContainerLocator(Type.PART, -1, pos.getWorld().getWorld(), pos.getBlockPos(), part.getSide());
|
||||
}
|
||||
|
||||
public boolean hasItemIndex() {
|
||||
return type == Type.PLAYER_INVENTORY || type == Type.PLAYER_INVENTORY_WITH_BLOCK_CONTEXT;
|
||||
|
||||
@@ -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.container;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
|
||||
/*
|
||||
* Totally useless container that does nothing.
|
||||
*/
|
||||
public class ContainerNull extends ScreenHandler {
|
||||
|
||||
public ContainerNull() {
|
||||
super(null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package appeng.container;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
import appeng.core.AELog;
|
||||
|
||||
/**
|
||||
* Allows opening containers generically.
|
||||
*/
|
||||
public final class ContainerOpener {
|
||||
|
||||
private ContainerOpener() {
|
||||
}
|
||||
|
||||
private static final Map<ScreenHandlerType<? extends AEBaseContainer>, Opener<?>> registry = new HashMap<>();
|
||||
|
||||
public static <T extends AEBaseContainer> void addOpener(ScreenHandlerType<T> type, Opener<T> opener) {
|
||||
registry.put(type, opener);
|
||||
}
|
||||
|
||||
public static boolean openContainer(ScreenHandlerType<?> type, PlayerEntity player, ContainerLocator locator) {
|
||||
Opener<?> opener = registry.get(type);
|
||||
if (opener == null) {
|
||||
AELog.warn("Trying to open container for unknown container type {}", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
return opener.open(player, locator);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Opener<T extends AEBaseContainer> {
|
||||
|
||||
boolean open(PlayerEntity player, ContainerLocator locator);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.container.guisync;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotates that this field should be synchronized between the server and
|
||||
* client. Requires the field to be public.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface GuiSync {
|
||||
|
||||
int value();
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.container.guisync;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.core.sync.packets.ProgressBarPacket;
|
||||
|
||||
/**
|
||||
* This class is responsible for synchronizing Container-fields from server to
|
||||
* client.
|
||||
*/
|
||||
public class SyncData {
|
||||
|
||||
private final AEBaseContainer source;
|
||||
private final Field field;
|
||||
private final Class<?> fieldType;
|
||||
private final int channel;
|
||||
private final MethodHandle getter;
|
||||
private final MethodHandle setter;
|
||||
private Object clientVersion;
|
||||
|
||||
public SyncData(final AEBaseContainer container, final Field field, final GuiSync annotation) {
|
||||
this.clientVersion = null;
|
||||
this.source = container;
|
||||
this.channel = annotation.value();
|
||||
this.field = field;
|
||||
this.fieldType = field.getType();
|
||||
try {
|
||||
this.getter = MethodHandles.publicLookup().unreflectGetter(field);
|
||||
this.setter = MethodHandles.publicLookup().unreflectSetter(field);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(
|
||||
"Failed to get accessor for field " + field + ". Did you forget to make it public?");
|
||||
}
|
||||
}
|
||||
|
||||
public int getChannel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
public void tick(final ScreenHandlerListener c) {
|
||||
|
||||
try {
|
||||
final Object val = this.getter.invoke(source);
|
||||
if (!Objects.equals(val, this.clientVersion)) {
|
||||
this.send(c, val);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void send(final ScreenHandlerListener o, Object val) {
|
||||
if (fieldType.isAssignableFrom(Text.class)) {
|
||||
if (o instanceof ServerPlayerEntity) {
|
||||
String json = "";
|
||||
if (val != null) {
|
||||
json = Text.Serializer.toJson((Text) val);
|
||||
}
|
||||
NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json),
|
||||
(ServerPlayerEntity) o);
|
||||
}
|
||||
}
|
||||
|
||||
// Types other than Text must be non-null
|
||||
if (val == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fieldType.equals(String.class)) {
|
||||
if (o instanceof ServerPlayerEntity) {
|
||||
NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, (String) val),
|
||||
(ServerPlayerEntity) o);
|
||||
}
|
||||
} else if (this.fieldType.isEnum()) {
|
||||
o.onPropertyUpdate(this.source, this.channel, ((Enum<?>) val).ordinal());
|
||||
} else if (val instanceof Long) {
|
||||
if (o instanceof ServerPlayerEntity) {
|
||||
NetworkHandler.instance().sendTo(new ProgressBarPacket(this.channel, (Long) val),
|
||||
(ServerPlayerEntity) o);
|
||||
}
|
||||
} else if (fieldType.equals(Boolean.class) || fieldType.equals(boolean.class)) {
|
||||
o.onPropertyUpdate(this.source, this.channel, ((Boolean) val) ? 1 : 0);
|
||||
} else if (fieldType.equals(Integer.class) || fieldType.equals(int.class)) {
|
||||
o.onPropertyUpdate(this.source, this.channel, (Integer) val);
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown field type: " + fieldType);
|
||||
}
|
||||
|
||||
this.clientVersion = val;
|
||||
}
|
||||
|
||||
public void update(Object val) {
|
||||
try {
|
||||
final Object oldValue = this.getter.invoke(source);
|
||||
if (val instanceof String) {
|
||||
if (this.fieldType.isAssignableFrom(Text.class)) {
|
||||
String json = (String) val;
|
||||
Text text = null;
|
||||
if (!json.isEmpty()) {
|
||||
text = Text.Serializer.fromJson((String) val);
|
||||
}
|
||||
this.updateTextComponent(text);
|
||||
} else {
|
||||
this.updateString((String) val);
|
||||
}
|
||||
} else {
|
||||
this.updateValue(oldValue, (Long) val);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateString(final String val) {
|
||||
try {
|
||||
this.setter.invoke(source, val);
|
||||
} catch (Throwable e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTextComponent(final Text val) {
|
||||
try {
|
||||
this.setter.invoke(source, val);
|
||||
} catch (Throwable e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateValue(final Object oldValue, final long val) {
|
||||
try {
|
||||
if (this.fieldType.isEnum()) {
|
||||
Object e = this.fieldType.getEnumConstants()[(int) val];
|
||||
this.setter.invoke(source, e);
|
||||
} else {
|
||||
if (this.fieldType.equals(int.class)) {
|
||||
this.setter.invoke(source, (int) val);
|
||||
} else if (this.fieldType.equals(long.class)) {
|
||||
this.setter.invoke(source, val);
|
||||
} else if (this.fieldType.equals(boolean.class)) {
|
||||
this.setter.invoke(source, val == 1);
|
||||
} else if (this.fieldType.equals(Integer.class)) {
|
||||
this.setter.invoke(source, (int) val);
|
||||
} else if (this.fieldType.equals(Long.class)) {
|
||||
this.setter.invoke(source, val);
|
||||
} else if (this.fieldType.equals(Boolean.class)) {
|
||||
this.setter.invoke(source, val == 1);
|
||||
}
|
||||
}
|
||||
|
||||
this.source.onUpdate(this.field.getName(), oldValue, this.getter.invoke(source));
|
||||
} catch (Throwable e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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.container.implementations;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import alexiil.mc.lib.attributes.item.impl.EmptyFixedItemInv;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.CopyMode;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.implementations.items.IStorageCell;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.cells.ICellWorkbenchItem;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.FakeTypeOnlySlot;
|
||||
import appeng.container.slot.OptionalRestrictedInputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.misc.CellWorkbenchBlockEntity;
|
||||
import appeng.util.EnumCycler;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.WrapperSupplierItemHandler;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
|
||||
public class CellWorkbenchContainer extends UpgradeableContainer {
|
||||
|
||||
public static ScreenHandlerType<CellWorkbenchContainer> TYPE;
|
||||
|
||||
private static final ContainerHelper<CellWorkbenchContainer, CellWorkbenchBlockEntity> helper = new ContainerHelper<>(
|
||||
CellWorkbenchContainer::new, CellWorkbenchBlockEntity.class);
|
||||
|
||||
private final CellWorkbenchBlockEntity workBench;
|
||||
@GuiSync(2)
|
||||
public CopyMode copyMode = CopyMode.CLEAR_ON_REMOVE;
|
||||
private ItemStack prevStack = ItemStack.EMPTY;
|
||||
private int lastUpgrades = 0;
|
||||
|
||||
public CellWorkbenchContainer(int id, final PlayerInventory ip, final CellWorkbenchBlockEntity te) {
|
||||
super(TYPE, id, ip, te);
|
||||
this.workBench = te;
|
||||
}
|
||||
|
||||
public static CellWorkbenchContainer fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf buf) {
|
||||
return helper.fromNetwork(windowId, inv, buf);
|
||||
}
|
||||
|
||||
public static boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return helper.open(player, locator);
|
||||
}
|
||||
|
||||
public void setFuzzy(final FuzzyMode valueOf) {
|
||||
final ICellWorkbenchItem cwi = this.workBench.getCell();
|
||||
if (cwi != null) {
|
||||
cwi.setFuzzyMode(this.workBench.getInventoryByName("cell").getInvStack(0), valueOf);
|
||||
}
|
||||
}
|
||||
|
||||
public void nextWorkBenchCopyMode() {
|
||||
this.workBench.getConfigManager().putSetting(Settings.COPY_MODE, EnumCycler.next(this.getWorkBenchCopyMode()));
|
||||
}
|
||||
|
||||
private CopyMode getWorkBenchCopyMode() {
|
||||
return (CopyMode) this.workBench.getConfigManager().getSetting(Settings.COPY_MODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeight() {
|
||||
return 251;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupConfig() {
|
||||
final FixedItemInv cell = this.getUpgradeable().getInventoryByName("cell");
|
||||
this.addSlot(new RestrictedInputSlot(RestrictedInputSlot.PlacableItemType.WORKBENCH_CELL, cell, 0, 152, 8,
|
||||
this.getPlayerInv()));
|
||||
|
||||
final FixedItemInv inv = this.getUpgradeable().getInventoryByName("config");
|
||||
final WrapperSupplierItemHandler upgradeInventory = new WrapperSupplierItemHandler(
|
||||
this::getCellUpgradeInventory);
|
||||
|
||||
int offset = 0;
|
||||
final int y = 29;
|
||||
final int x = 8;
|
||||
for (int w = 0; w < 7; w++) {
|
||||
for (int z = 0; z < 9; z++) {
|
||||
this.addSlot(new FakeTypeOnlySlot(inv, offset, x + z * 18, y + w * 18));
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int zz = 0; zz < 3; zz++) {
|
||||
for (int z = 0; z < 8; z++) {
|
||||
final int iSLot = zz * 8 + z;
|
||||
this.addSlot(new OptionalRestrictedInputSlot(RestrictedInputSlot.PlacableItemType.UPGRADES,
|
||||
upgradeInventory, this, iSLot, 187 + zz * 18, 8 + 18 * z, iSLot, this.getPlayerInventory()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int availableUpgrades() {
|
||||
final ItemStack is = this.workBench.getInventoryByName("cell").getInvStack(0);
|
||||
if (this.prevStack != is) {
|
||||
this.prevStack = is;
|
||||
this.lastUpgrades = this.getCellUpgradeInventory().getSlotCount();
|
||||
}
|
||||
return this.lastUpgrades;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
final ItemStack is = this.workBench.getInventoryByName("cell").getInvStack(0);
|
||||
if (Platform.isServer()) {
|
||||
for (final ScreenHandlerListener listener : this.getListeners()) {
|
||||
if (this.prevStack != is) {
|
||||
// if the bars changed an item was probably made, so just send shit!
|
||||
for (int i = 0; i < this.slots.size(); i++) {
|
||||
Slot s = this.slots.get(i);
|
||||
if (s instanceof OptionalRestrictedInputSlot) {
|
||||
final OptionalRestrictedInputSlot sri = (OptionalRestrictedInputSlot) s;
|
||||
listener.onSlotUpdate(this, i, sri.getStack());
|
||||
}
|
||||
}
|
||||
|
||||
if (listener instanceof ServerPlayerEntity) {
|
||||
((ServerPlayerEntity) listener).skipPacketSlotUpdates = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setCopyMode(this.getWorkBenchCopyMode());
|
||||
this.setFuzzyMode(this.getWorkBenchFuzzyMode());
|
||||
}
|
||||
|
||||
this.prevStack = is;
|
||||
this.standardDetectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlotEnabled(final int idx) {
|
||||
return idx < this.availableUpgrades();
|
||||
}
|
||||
|
||||
public FixedItemInv getCellUpgradeInventory() {
|
||||
final FixedItemInv upgradeInventory = this.workBench.getCellUpgradeInventory();
|
||||
|
||||
return upgradeInventory == null ? EmptyFixedItemInv.INSTANCE : upgradeInventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
|
||||
if (field.equals("copyMode")) {
|
||||
this.workBench.getConfigManager().putSetting(Settings.COPY_MODE, this.getCopyMode());
|
||||
}
|
||||
|
||||
super.onUpdate(field, oldValue, newValue);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
ItemHandlerUtil.clear(this.getUpgradeable().getInventoryByName("config"));
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
private FuzzyMode getWorkBenchFuzzyMode() {
|
||||
final ICellWorkbenchItem cwi = this.workBench.getCell();
|
||||
if (cwi != null) {
|
||||
return cwi.getFuzzyMode(this.workBench.getInventoryByName("cell").getInvStack(0));
|
||||
}
|
||||
return FuzzyMode.IGNORE_ALL;
|
||||
}
|
||||
|
||||
public void partition() {
|
||||
|
||||
final FixedItemInv inv = this.getUpgradeable().getInventoryByName("config");
|
||||
|
||||
final ItemStack is = this.getUpgradeable().getInventoryByName("cell").getInvStack(0);
|
||||
final IStorageChannel channel = is.getItem() instanceof IStorageCell
|
||||
? ((IStorageCell) is.getItem()).getChannel()
|
||||
: AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
|
||||
final IMEInventory cellInv = AEApi.instance().registries().cell().getCellInventory(is, null, channel);
|
||||
|
||||
Iterator<IAEStack> i = new NullIterator<>();
|
||||
if (cellInv != null) {
|
||||
final IItemList list = cellInv.getAvailableItems(channel.createList());
|
||||
i = list.iterator();
|
||||
}
|
||||
|
||||
for (int x = 0; x < inv.getSlotCount(); x++) {
|
||||
if (i.hasNext()) {
|
||||
// TODO: check if ok
|
||||
final ItemStack g = i.next().asItemStackRepresentation();
|
||||
ItemHandlerUtil.setStackInSlot(inv, x, g);
|
||||
} else {
|
||||
ItemHandlerUtil.setStackInSlot(inv, x, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
public CopyMode getCopyMode() {
|
||||
return this.copyMode;
|
||||
}
|
||||
|
||||
private void setCopyMode(final CopyMode copyMode) {
|
||||
this.copyMode = copyMode;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user