Major cleanup of the redstone side of control panels. Not done yet.

This commit is contained in:
malte0811 2018-07-30 18:41:52 +02:00
parent c48bbb2d63
commit 1cef97f260
24 changed files with 1054 additions and 950 deletions

View file

@ -20,9 +20,7 @@ import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.BlockIWBase;
import malte0811.industrialWires.blocks.IMetaEnum;
import malte0811.industrialWires.controlpanel.PanelComponent;
import malte0811.industrialWires.controlpanel.PanelUtils;
import malte0811.industrialWires.controlpanel.PropertyComponents;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
@ -47,7 +45,6 @@ import net.minecraftforge.common.property.IUnlistedProperty;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class BlockPanel extends BlockIWBase implements IMetaEnum {
public static final PropertyEnum<BlockTypes_Panel> type = PropertyEnum.create("type", BlockTypes_Panel.class);
@ -223,48 +220,7 @@ public class BlockPanel extends BlockIWBase implements IMetaEnum {
super.harvestBlock(worldIn, player, pos, state, te, stack);
if (te instanceof TileEntityPanel) {
for (PanelComponent pc:((TileEntityPanel) te).getComponents()) {
pc.dropItems((TileEntityPanel)te);
}
}
}
@Override
public void breakBlock(@Nonnull World worldIn, @Nonnull BlockPos pos, @Nonnull IBlockState state) {
super.breakBlock(worldIn, pos, state);
//break connections
List<BlockPos> panels = PanelUtils.discoverPanelParts(worldIn, pos, 11 * 11 * 11);
for (BlockPos p : panels) {
if (!p.equals(pos)) {
TileEntity panelPart = worldIn.getTileEntity(p);
if (panelPart instanceof TileEntityPanel) {
((TileEntityPanel) panelPart).removeAllRSCons();
}
}
}
}
@Override
public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) {
super.onBlockAdded(worldIn, pos, state);
List<BlockPos> panels = PanelUtils.discoverPanelParts(worldIn, pos, 11 * 11 * 11);
for (BlockPos p : panels) {
if (!p.equals(pos)) {
TileEntity panelPart = worldIn.getTileEntity(p);
if (panelPart instanceof TileEntityPanel) {
((TileEntityPanel) panelPart).firstTick = true;
}
}
}
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
super.neighborChanged(state, world, pos, blockIn, fromPos);
IBlockState blockState = world.getBlockState(pos);
if (blockState.getValue(type)==BlockTypes_Panel.SINGLE_COMP) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof TileEntityComponentPanel) {
((TileEntityComponentPanel)te).updateRS();
pc.dropItems();
}
}
}
@ -279,7 +235,7 @@ public class BlockPanel extends BlockIWBase implements IMetaEnum {
return state.getValue(type)==BlockTypes_Panel.SINGLE_COMP;
}
@Override
/*@Override
public int getStrongPower(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) {
if (blockState.getValue(type)==BlockTypes_Panel.SINGLE_COMP) {
TileEntity te = blockAccess.getTileEntity(pos);
@ -300,5 +256,5 @@ public class BlockPanel extends BlockIWBase implements IMetaEnum {
}
}
return 0;
}
}*/
}

View file

@ -15,25 +15,8 @@
package malte0811.industrialWires.blocks.controlpanel;
import malte0811.industrialWires.controlpanel.PanelComponent;
import malte0811.industrialWires.controlpanel.PropertyComponents;
import malte0811.industrialWires.items.ItemPanelComponent;
import net.minecraft.block.BlockRedstoneWire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nonnull;
import java.util.function.Consumer;
import static malte0811.industrialWires.util.MiscUtils.apply;
public class TileEntityComponentPanel extends TileEntityPanel {
private int rsOut = 0;
/*private int rsOut = 0; todo
private Consumer<byte[]> rsIn;
public TileEntityComponentPanel() {
components = new PropertyComponents.AABBPanelProperties();
@ -42,7 +25,7 @@ public class TileEntityComponentPanel extends TileEntityPanel {
@Override
public void update() {
for (PanelComponent pc : components) {
pc.update(this);
pc.update();
}
if (!world.isRemote) {
if (firstTick&&components.size()>0) {
@ -81,7 +64,7 @@ public class TileEntityComponentPanel extends TileEntityPanel {
public void markBlockForUpdate(BlockPos pos)
{
IBlockState state = world.getBlockState(getPos());
IBlockState state = world.getBlockState(getBlockPos());
world.notifyBlockUpdate(pos,state,state,3);
world.notifyNeighborsOfStateChange(pos, state.getBlock(), true);
}
@ -122,4 +105,4 @@ public class TileEntityComponentPanel extends TileEntityPanel {
}
return ItemPanelComponent.stackFromComponent(components.get(0));
}
}
*/}

View file

@ -0,0 +1,73 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2018 malte0811
* Industrial Wires is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Industrial Wires 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Industrial Wires. If not, see <http://www.gnu.org/licenses/>.
*/
package malte0811.industrialWires.blocks.controlpanel;
import malte0811.industrialWires.blocks.TileEntityIWBase;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.IOwner;
import malte0811.industrialWires.util.MiscUtils;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nonnull;
public abstract class TileEntityGeneralCP extends TileEntityIWBase implements IOwner {
@Nonnull
protected ControlPanelNetwork panelNetwork = new ControlPanelNetwork();
public void setNetworkAndInit(ControlPanelNetwork newNet) {
panelNetwork = newNet;
}
@Override
public void onLoad() {
super.onLoad();
boolean isFinalNet = false;
for (EnumFacing side:EnumFacing.VALUES) {
BlockPos posSide = pos.offset(side);
TileEntityGeneralCP neighbour = MiscUtils.getExistingTE(world, posSide, TileEntityGeneralCP.class);
if (neighbour!=null) {
if (!isFinalNet) {
panelNetwork = neighbour.panelNetwork;
panelNetwork.addMember(this);
isFinalNet = true;
} else {
neighbour.panelNetwork.replaceWith(panelNetwork, world);
}
}
}
if (!isFinalNet) {
panelNetwork.addMember(this);
}
}
@Override
public void onChunkUnload() {
super.onChunkUnload();
panelNetwork.removeMember(pos, world);
}
@Override
public void invalidate() {
super.invalidate();
panelNetwork.removeMember(pos, world);
}
@Override
public BlockPos getBlockPos() {
return pos;
}
}

View file

@ -21,8 +21,8 @@ import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IPlayerIn
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.IBlockBoundsIW;
import malte0811.industrialWires.blocks.TileEntityIWBase;
import malte0811.industrialWires.controlpanel.*;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.network.MessagePanelInteract;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
@ -31,7 +31,6 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ITickable;
@ -44,17 +43,12 @@ import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static malte0811.industrialWires.util.MiscUtils.apply;
public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTile, IBlockBoundsIW, IPlayerInteraction, ITickable, IEBlockInterfaces.ITileDrop {
public class TileEntityPanel extends TileEntityGeneralCP implements IDirectionalTile, IBlockBoundsIW, IPlayerInteraction, ITickable, IEBlockInterfaces.ITileDrop {
protected PropertyComponents.PanelRenderProperties components = new PropertyComponents.PanelRenderProperties();
public boolean firstTick = true;
// non-rendered properties
private Set<TileEntityRSPanelConn> rsPorts = new HashSet<>();
{
int[] colors = {
@ -62,9 +56,10 @@ public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTil
4673362, 10329495, 1481884, 8991416, 3949738, 8606770, 6192150
};
for (int i = 2; i < 14; i++) {
int color = colors[i];
IndicatorLight ind = new IndicatorLight(0, (byte) (i - 2), color);
LightedButton btn = new LightedButton(color, false, true, 1, i - 2);
int color = colors[i-2];
IndicatorLight ind = new IndicatorLight(new RSChannel(0, (byte) (i - 2)), color);
LightedButton btn = new LightedButton(color, false, true,
new RSChannel(0, (byte)(i-2)));
Label lbl = new Label("->", color);
ind.setX(0);
ind.setY(i / 16F);
@ -84,19 +79,15 @@ public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTil
@Override
public void update() {
for (PanelComponent pc : components) {
pc.update(this);
pc.update();
}
if (!world.isRemote) {
if (firstTick) {
List<BlockPos> parts = PanelUtils.discoverPanelParts(world, pos, 100);
for (BlockPos bp : parts) {
TileEntity te = world.getTileEntity(bp);
if (te instanceof TileEntityRSPanelConn && !rsPorts.contains(te)) {
((TileEntityRSPanelConn) te).registerPanel(this);
}
}
firstTick = false;
}
}
@Override
public void setNetworkAndInit(ControlPanelNetwork newNet) {
super.setNetworkAndInit(newNet);
for (PanelComponent pc : components) {
pc.setNetwork(newNet, this);
}
}
@ -278,47 +269,7 @@ public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTil
public void interactServer(Vec3d hitRelative, int pcId, EntityPlayerMP player) {
if (pcId >= 0 && pcId < components.size()) {
components.get(pcId).interactWith(hitRelative, this, player);
components.get(pcId).interactWith(hitRelative, player);
}
}
public void registerRS(TileEntityRSPanelConn te) {
rsPorts.add(te);
}
public void unregisterRS(TileEntityRSPanelConn te) {
if (!tileEntityInvalid) {
rsPorts.remove(te);
}
}
@Override
public void onChunkUnload() {
super.onChunkUnload();
for (PanelComponent pc : components) {
pc.invalidate(this);
}
removeAllRSCons();
}
public void removeAllRSCons() {
for (TileEntityRSPanelConn rs : rsPorts) {
rs.unregisterPanel(this, true, false);
}
rsPorts.clear();
firstTick = true;
}
@Override
public void invalidate() {
super.invalidate();
for (PanelComponent pc : components) {
pc.invalidate(this);
}
removeAllRSCons();
}
public boolean interactsWithRSWires() {
return true;
}
}

View file

@ -18,22 +18,19 @@ package malte0811.industrialWires.blocks.controlpanel;
import blusunrize.immersiveengineering.api.TargetingInfo;
import blusunrize.immersiveengineering.api.energy.wires.IImmersiveConnectable;
import blusunrize.immersiveengineering.api.energy.wires.ImmersiveNetHandler;
import blusunrize.immersiveengineering.api.energy.wires.TileEntityImmersiveConnectable;
import blusunrize.immersiveengineering.api.energy.wires.WireType;
import blusunrize.immersiveengineering.api.energy.wires.redstone.IRedstoneConnector;
import blusunrize.immersiveengineering.api.energy.wires.redstone.RedstoneWireNetwork;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces;
import malte0811.industrialWires.blocks.IBlockBoundsIW;
import malte0811.industrialWires.blocks.INetGUI;
import malte0811.industrialWires.controlpanel.PanelComponent;
import malte0811.industrialWires.controlpanel.PanelUtils;
import malte0811.industrialWires.controlpanel.PropertyComponents;
import malte0811.industrialWires.util.TriConsumer;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
@ -44,192 +41,113 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.Arrays;
import java.util.function.Consumer;
import static blusunrize.immersiveengineering.api.energy.wires.WireType.REDSTONE_CATEGORY;
public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implements IRedstoneConnector, ITickable, INetGUI, IEBlockInterfaces.IDirectionalTile, IBlockBoundsIW {
public class TileEntityRSPanelConn extends TileEntityGeneralCP//TODO what parts of TEIIC do I need?
implements IRedstoneConnector, INetGUI, IEBlockInterfaces.IDirectionalTile, IBlockBoundsIW,
ITickable {
private byte[] out = new byte[16];
private boolean dirty = true;
private byte[] oldInput = new byte[16];
private Set<Consumer<byte[]>> changeListeners = new HashSet<>();
private Set<TileEntityPanel> connectedPanels = new HashSet<>();
private final RSChannel[] channels = new RSChannel[16];
private EnumFacing facing = EnumFacing.NORTH;
@Nonnull
private RedstoneWireNetwork network = new RedstoneWireNetwork().add(this);
private RedstoneWireNetwork wireNetwork = new RedstoneWireNetwork().add(this);
private boolean hasConn = false;
private int id;
private int controller = 0;
{
for (int i = 0; i < 16; i++) {
oldInput[i] = -1;
}
updateChannelsArray();
}
private boolean loaded = false;
@Override
public void update() {
if (hasWorld() && !world.isRemote) {
if (!loaded) {
loaded = true;
// completely reload the network
network.removeFromNetwork(null);
List<BlockPos> parts = PanelUtils.discoverPanelParts(world, pos, 100);
for (BlockPos bp : parts) {
TileEntity te = world.getTileEntity(bp);
if (te instanceof TileEntityPanel) {
registerPanel(((TileEntityPanel) te));
}
}
}
if (dirty) {
network.updateValues();
dirty = false;
}
if (dirty) {
wireNetwork.updateValues();
dirty = false;
}
}
private void updateChannelsArray() {
for (byte i = 0;i<16;i++) {
channels[i] = new RSChannel(controller, i);
}
}
@Override
public void writeCustomNBT(@Nonnull NBTTagCompound out, boolean updatePacket) {
super.writeCustomNBT(out, updatePacket);
out.setByteArray("out", this.out);
out.setBoolean("hasConn", hasConn);
out.setInteger("rsId", id);
out.setInteger("facing", facing.getIndex());
public void writeNBT(NBTTagCompound nbt, boolean updatePacket) {
nbt.setByteArray("out", this.out);
nbt.setBoolean("hasConn", hasConn);
nbt.setInteger("rsId", controller);
nbt.setInteger("facing", facing.getIndex());
}
@Override
public void readCustomNBT(@Nonnull NBTTagCompound in, boolean updatePacket) {
super.readCustomNBT(in, updatePacket);
out = in.getByteArray("out");
hasConn = in.getBoolean("hasConn");
id = in.getInteger("rsId");
facing = EnumFacing.VALUES[in.getInteger("facing")];
public void readNBT(NBTTagCompound nbt, boolean updatePacket) {
out = nbt.getByteArray("out");
hasConn = nbt.getBoolean("hasConn");
controller = nbt.getInteger("rsId");
updateChannelsArray();
facing = EnumFacing.VALUES[nbt.getInteger("facing")];
aabb = null;
}
private final Map<PCWrapper, byte[]> outputs = new HashMap<>();
private TriConsumer<Integer, Byte, PanelComponent> rsOut = (channel, value, pc) -> {
PCWrapper wrapper = new PCWrapper(pc);
if (!outputs.containsKey(wrapper)) {
outputs.put(wrapper, new byte[16]);
}
if (outputs.get(wrapper)[channel] != value) {
outputs.get(wrapper)[channel] = value;
byte max = 0;
Iterator<Map.Entry<PCWrapper, byte[]>> it = outputs.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<PCWrapper, byte[]> curr = it.next();
if (curr.getKey().pc.get() == null) {
it.remove();
continue;
}
if (curr.getValue()[channel] > max) {
max = curr.getValue()[channel];
}
}
dirty = true;
out[channel] = max;
}
};
private class PCWrapper {
@Nonnull
private final WeakReference<PanelComponent> pc;
public PCWrapper(@Nonnull PanelComponent pc) {
this.pc = new WeakReference<>(pc);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PCWrapper pcWrapper = (PCWrapper) o;
return pcWrapper.pc.get() == pc.get();
}
@Override
public int hashCode() {
return System.identityHashCode(pc.get());
}
}
public void registerPanel(TileEntityPanel panel) {
if (panel.interactsWithRSWires()) {
PropertyComponents.PanelRenderProperties p = panel.getComponents();
for (PanelComponent pc : p) {
Consumer<byte[]> listener = pc.getRSInputHandler(id, panel);
if (listener != null) {
changeListeners.add(listener);
listener.accept(network.channelValues);
}
pc.registerRSOutput(id, rsOut);
}
panel.registerRS(this);
connectedPanels.add(panel);
}
}
public void unregisterPanel(TileEntityPanel panel, boolean remove, boolean callPanel) {
out = new byte[16];
PropertyComponents.PanelRenderProperties p = panel.getComponents();
for (PanelComponent pc : p) {
Consumer<byte[]> listener = pc.getRSInputHandler(id, panel);
if (listener != null) {
listener.accept(new byte[16]);
changeListeners.remove(listener);
}
pc.unregisterRSOutput(id, rsOut);
outputs.remove(new PCWrapper(pc));
}
if (callPanel) {
panel.unregisterRS(this);
}
if (remove) {
connectedPanels.remove(panel);
}
for (TileEntityPanel te : connectedPanels) {
for (PanelComponent pc : te.getComponents()) {
pc.registerRSOutput(id, rsOut);
}
}
network.updateValues();
}
@Override
public void setNetwork(@Nonnull RedstoneWireNetwork net) {
network = net;
wireNetwork = net;
}
@Nonnull
@Override
public RedstoneWireNetwork getNetwork() {
return network;
return wireNetwork;
}
@Override
public void onChange() {
if (!Arrays.equals(oldInput, network.channelValues)) {
oldInput = Arrays.copyOf(network.channelValues, 16);
for (Consumer<byte[]> c : changeListeners) {
c.accept(oldInput);
if (!Arrays.equals(oldInput, wireNetwork.channelValues)) {
RSChannelState[] newStates = new RSChannelState[16];
for (byte i = 0; i < 16; i++) {
if (wireNetwork.channelValues[i]>out[i]) {
newStates[i] = new RSChannelState(channels[i], wireNetwork.channelValues[i]);
} else {
newStates[i] = new RSChannelState(channels[i], (byte) 0);
}
}
panelNetwork.setOutputs(this, newStates);
oldInput = Arrays.copyOf(wireNetwork.channelValues, 16);
}
}
@Override
public void updateInput(byte[] currIn) {
byte[] oldIn = Arrays.copyOf(currIn, 16);
for (int i = 0; i < 16; i++) {
currIn[i] = (byte) Math.max(currIn[i], out[i]);
}
}
@Override
public boolean canConnect() {
return true;
}
@Override
public boolean isEnergyOutput() {
return false;
}
@Override
public int outputEnergy(int amount, boolean simulate, int energyType) {
return 0;
}
@Override
public BlockPos getConnectionMaster(@Nullable WireType wire, TargetingInfo target) {
return pos;
@ -243,8 +161,8 @@ public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implem
@Override
public void connectCable(WireType wireType, TargetingInfo targetingInfo, IImmersiveConnectable other) {
hasConn = true;
if (other instanceof IRedstoneConnector && ((IRedstoneConnector) other).getNetwork() != network) {
network.mergeNetwork(((IRedstoneConnector) other).getNetwork());
if (other instanceof IRedstoneConnector && ((IRedstoneConnector) other).getNetwork() != wireNetwork) {
wireNetwork.mergeNetwork(((IRedstoneConnector) other).getNetwork());
}
}
@ -261,7 +179,7 @@ public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implem
@Override
public void removeCable(ImmersiveNetHandler.Connection connection) {
hasConn = false;
network.removeFromNetwork(this);
wireNetwork.removeFromNetwork(this);
this.markDirty();
if (world != null) {
IBlockState state = world.getBlockState(pos);
@ -277,42 +195,24 @@ public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implem
}
@Override
public void onChunkUnload() {
super.onChunkUnload();
for (TileEntityPanel panel : connectedPanels) {
unregisterPanel(panel, false, true);
}
}
@Override
public void invalidate() {
super.invalidate();
for (TileEntityPanel panel : connectedPanels) {
unregisterPanel(panel, false, true);
}
public void setNetworkAndInit(ControlPanelNetwork newNet) {
super.setNetworkAndInit(newNet);
onChange();
Consumer<RSChannelState> listener = state -> {
if (out[state.getColor()] != state.getStrength()) {
out[state.getColor()] = state.getStrength();
dirty = true;
Thread.dumpStack();
}
};
panelNetwork.addListener(this, listener, channels);
}
@Override
public void onChange(NBTTagCompound nbt, EntityPlayer p) {
if (nbt.hasKey("rsId")) {
List<BlockPos> parts = PanelUtils.discoverPanelParts(world, pos, 100);
List<TileEntityPanel> tes = new ArrayList<>(parts.size());
for (BlockPos bp : parts) {
TileEntity te = world.getTileEntity(bp);
if (te instanceof TileEntityPanel) {
tes.add((TileEntityPanel) te);
unregisterPanel((TileEntityPanel) te, true, true);
}
}
id = nbt.getInteger("rsId");
out = new byte[16];
for (TileEntityPanel panel : tes) {
registerPanel(panel);
}
network.updateValues();
IBlockState state = world.getBlockState(pos);
world.notifyBlockUpdate(pos, state, state, 3);
world.addBlockEvent(pos, state.getBlock(), 255, 0);
panelNetwork.removeIOFor(this);
setNetworkAndInit(panelNetwork);
}
}
@ -322,7 +222,7 @@ public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implem
}
public int getRsId() {
return id;
return controller;
}
@Nonnull

View file

@ -126,7 +126,7 @@ public class ClientEventHandler {
TileEntityPanel panel = (TileEntityPanel) tile;
Pair<PanelComponent, RayTraceResult> pc = panel.getSelectedComponent(Minecraft.getMinecraft().player, event.getTarget().hitVec, true);
if (pc != null) {
pc.getLeft().renderBox(panel);
pc.getLeft().renderBox();
event.setCanceled(true);
}
}

View file

@ -84,9 +84,9 @@ public class GuiPanelComponent extends GuiContainer {
toAdd.setText(sc.value);
stringTexts.add(toAdd);
}
IConfigurableComponent.RSChannelConfig[] rs = confComp.getRSChannelOptions();
IConfigurableComponent.RSColorConfig[] rs = confComp.getRSChannelOptions();
rsChannelChoosers.clear();
for (IConfigurableComponent.RSChannelConfig rc : rs) {
for (IConfigurableComponent.RSColorConfig rc : rs) {
if (rc.small) {
rsChannelChoosers.add(new GuiChannelPickerSmall(0, componentLeft + rc.x, componentTop + rc.y, 10, 40, rc.value));
} else {

View file

@ -30,6 +30,6 @@ public class ContainerRSPanelConn extends Container {
@Override
public boolean canInteractWith(@Nonnull EntityPlayer playerIn) {
return playerIn.getDistanceSq(te.getPos()) < 64;
return playerIn.getDistanceSq(te.getBlockPos()) < 64;
}
}

View file

@ -0,0 +1,398 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2018 malte0811
* Industrial Wires is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Industrial Wires 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Industrial Wires. If not, see <http://www.gnu.org/licenses/>.
*/
package malte0811.industrialWires.controlpanel;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import malte0811.industrialWires.blocks.controlpanel.TileEntityGeneralCP;
import malte0811.industrialWires.util.MiscUtils;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Consumer;
@SuppressWarnings({"unused", "WeakerAccess"})
public class ControlPanelNetwork {
private Map<RSChannel, List<ChangeListener>> listeners = new HashMap<>();
private Map<RSChannel, List<OutputValue>> allOutputs = new HashMap<>();
private Map<RSChannel, OutputValue> activeOutputs = new HashMap<>();
private Map<RSChannel, OutputValue> secondActiveOutputs = new HashMap<>();
private Set<BlockPos> members = new HashSet<>();
public void addListener(IOwner owner, Consumer<RSChannelState> listener, RSChannel... channels) {
ChangeListener l = new ChangeListener(owner, listener);
for (RSChannel channel:channels) {
if (!channel.isValid()) {
continue;
}
listeners.computeIfAbsent(channel, c->new ArrayList<>())
.add(l);
if (activeOutputs.containsKey(channel)) {
listener.accept(activeOutputs.get(channel).targetState);
} else {
listener.accept(new RSChannelState(channel, (byte) 0));
}
}
}
public void setOutputs(IOwner owner, RSChannelState... out) {
for (RSChannelState o:out) {
if (!o.getChannel().isValid()) {
continue;
}
if (removeForChannel(owner, allOutputs.get(o.getChannel()), null)) {
allOutputs.remove(o.getChannel());
}
if (o.getStrength()>0) {
OutputValue outVal = new OutputValue(owner, o);
allOutputs.computeIfAbsent(o.getChannel(), c -> new ArrayList<>())
.add(outVal);
}
recalculateOutput(o.getChannel(), Collections.singleton(owner), Collections.emptyList());
}
}
public void removeIOFor(IOwner owner) {
Iterator<Map.Entry<RSChannel, List<ChangeListener>>> iteratorL = listeners.entrySet().iterator();
while (iteratorL.hasNext()) {
Map.Entry<RSChannel, List<ChangeListener>> entry = iteratorL.next();
removeForChannel(owner, entry.getValue(), iteratorL);
}
Iterator<Map.Entry<RSChannel, List<OutputValue>>> iteratorO = allOutputs.entrySet().iterator();
while (iteratorO.hasNext()) {
Map.Entry<RSChannel, List<OutputValue>> entry = iteratorO.next();
if (!removeForChannel(owner, entry.getValue(), iteratorO)) {
recalculateOutput(entry.getKey(), Collections.singleton(owner), Collections.emptyList());
}
}
}
public void removeMember(BlockPos pos, World w) {
for (List<ChangeListener> list : listeners.values()) {
list.removeIf(l->l.ownerAtPos(pos));
}
Iterator<Map.Entry<RSChannel, List<OutputValue>>> iterator = allOutputs.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<RSChannel, List<OutputValue>> entry = iterator.next();
entry.getValue().removeIf(l -> l.ownerAtPos(pos));
if (entry.getValue().isEmpty()) {
iterator.remove();
}
recalculateOutput(entry.getKey(), Collections.emptyList(), Collections.singleton(pos));
}
members.remove(pos);
split(pos, w);
}
//This does not call split!
private void removeAllMembers(Collection<BlockPos> toRemove) {
Iterator<Map.Entry<RSChannel, List<ChangeListener>>> iteratorL = listeners.entrySet().iterator();
while (iteratorL.hasNext()) {
Map.Entry<RSChannel, List<ChangeListener>> entry = iteratorL.next();
entry.getValue().removeIf(l -> l.ownerAtPos(toRemove));
if (entry.getValue().isEmpty()) {
iteratorL.remove();
}
}
Iterator<Map.Entry<RSChannel, List<OutputValue>>> iteratorO = allOutputs.entrySet().iterator();
while (iteratorO.hasNext()) {
Map.Entry<RSChannel, List<OutputValue>> entry = iteratorO.next();
entry.getValue().removeIf(l -> l.ownerAtPos(toRemove));
if (entry.getValue().isEmpty()) {
iteratorO.remove();
}
recalculateOutput(entry.getKey(), Collections.emptyList(), toRemove);
}
members.removeAll(toRemove);
}
public void addMember(TileEntityGeneralCP member) {
members.add(member.getBlockPos());
member.setNetworkAndInit(this);
}
public void replaceWith(ControlPanelNetwork newNet, World w) {
replaceWith(newNet, w, ImmutableSet.copyOf(members));
}
private void replaceWith(ControlPanelNetwork newNet, World w, Collection<BlockPos> toReplace) {
removeAllMembers(ImmutableList.copyOf(toReplace));
for (BlockPos member:toReplace) {
TileEntityGeneralCP te = MiscUtils.getExistingTE(w, member, TileEntityGeneralCP.class);
if (te!=null) {
newNet.addMember(te);
}
}
}
private void recalculateOutput(RSChannel channel, Collection<IOwner> excluded, Collection<BlockPos> excludedPos) {
OutputValue oldMax = activeOutputs.get(channel);
OutputValue oldSecMax = secondActiveOutputs.get(channel);
OutputValue newMax = null;
OutputValue newSecMax = null;
for (OutputValue v : allOutputs.get(channel)) {
if (v.isStrongerThan(newMax)) {
newSecMax = newMax;
newMax = v;
} else if (v.isStrongerThan(newSecMax)) {
newSecMax = v;
}
}
if (newMax == null) {
newMax = new OutputValue(null, new RSChannelState(channel, (byte) 0));
newSecMax = newMax;
activeOutputs.remove(channel);
} else {
activeOutputs.put(channel, newMax);
}
secondActiveOutputs.put(channel, newSecMax);
if (newSecMax == null) {
newSecMax = new OutputValue(null, new RSChannelState(channel, (byte) 0));
}
if (!newSecMax.equals(oldSecMax) || !newMax.equals(oldMax)) {
List<ChangeListener> listenersForChannel = listeners.get(channel);
if (listenersForChannel != null) {
for (ChangeListener l : listenersForChannel) {
if (!l.isOwnedBy(excluded) && !l.ownerAtPos(excludedPos)) {
if (!l.hasSameOwner(newMax)) {
l.onChange(newMax.getTargetState());
} else {
l.onChange(newSecMax.getTargetState());
}
}
}
}
}
}
private <T extends Owned> boolean removeForChannel(IOwner owner, List<T> l, Iterator<?> it) {
l.removeIf(val -> val.isOwnedBy(owner));
if (l.isEmpty()) {
if (it!=null) {
it.remove();
}
return true;
} else {
return false;
}
}
private <T extends Owned> boolean removeForChannel(BlockPos owner, List<T> l, Iterator<?> it) {
l.removeIf(val -> val.ownerAtPos(owner));
if (l.isEmpty()) {
if (it!=null) {
it.remove();
}
return true;
} else {
return false;
}
}
private void split(BlockPos pos, World w) {
Set<BlockPos> reached = new HashSet<>();
List<BlockPos> newForThis = null;
for (EnumFacing side : EnumFacing.VALUES) {
BlockPos start = pos.offset(side);
if (!reached.contains(start)) {
List<BlockPos> netForSide = MiscUtils.discoverLocal(start, (p, s) -> members.contains(p));
if (!netForSide.isEmpty()) {
reached.addAll(netForSide);
if (newForThis == null) {
newForThis = netForSide;
} else {
replaceWith(new ControlPanelNetwork(), w, netForSide);
}
}
}
}
}
private static class ChangeListener extends Owned {
private final Consumer<RSChannelState> listener;
private ChangeListener(IOwner owner, Consumer<RSChannelState> listener) {
super(owner);
this.listener = listener;
}
public void onChange(RSChannelState newState) {
listener.accept(newState);
}
}
private static class OutputValue extends Owned {
private final RSChannelState targetState;
private OutputValue(@Nullable IOwner owner, RSChannelState targetState) {
super(owner);
this.targetState = targetState;
}
public RSChannelState getTargetState() {
return targetState;
}
public boolean isStrongerThan(OutputValue other) {
return other==null || targetState.getStrength()>other.getTargetState().getStrength();
}
}
private static class Owned {
@Nullable
private final IOwner owner;
private Owned(@Nullable IOwner owner) {
this.owner = owner;
}
public final boolean isOwnedBy(IOwner o) {
return o.equals(owner);
}
public final boolean ownerAtPos(BlockPos o) {
return o.equals(getOwnerPos());
}
public final boolean isOwnedBy(Collection<IOwner> o) {
return o.contains(owner);
}
public final boolean ownerAtPos(Collection<BlockPos> o) {
return o.contains(getOwnerPos());
}
public final BlockPos getOwnerPos() {
return owner==null?BlockPos.ORIGIN:owner.getBlockPos();
}
public boolean hasSameOwner(Owned active) {
return Objects.equals(owner, active.owner);
}
}
public interface IOwner {
BlockPos getBlockPos();
}
public static class RSChannel {
public static final RSChannel INVALID_CHANNEL = new RSChannel(-1, (byte)-1);
private final int controller;
private final byte color;
public RSChannel(int controller, byte color) {
this.controller = controller;
this.color = color;
}
public byte getColor() {
return color;
}
public int getController() {
return controller;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RSChannel rsChannel = (RSChannel) o;
if (controller != rsChannel.controller) return false;
return color == rsChannel.color;
}
@Override
public int hashCode() {
int result = controller;
result = 31 * result + color;
return result;
}
public boolean isValid() {
return controller>=0 && color >= 0;
}
public RSChannel withController(int controller) {
return new RSChannel(controller, color);
}
public RSChannel withColor(byte color) {
return new RSChannel(controller, color);
}
public RSChannel withController(NBTBase nbt) {
return withController(((NBTTagInt)nbt).getInt());
}
public RSChannel withColor(NBTBase nbt) {
return withColor(((NBTTagByte)nbt).getByte());
}
}
public static class RSChannelState {
private final RSChannel channel;
private final byte strength;
public RSChannelState(RSChannel channel, byte strength) {
this.channel = channel;
this.strength = strength;
}
public byte getStrength() {
return strength;
}
public RSChannel getChannel() {
return channel;
}
public int getColor() {
return getChannel().getColor();
}
public int getController() {
return getChannel().getController();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RSChannelState that = (RSChannelState) o;
if (strength != that.strength) return false;
return channel.equals(that.channel);
}
@Override
public int hashCode() {
int result = channel.hashCode();
result = 31 * result + strength;
return result;
}
}
}

View file

@ -17,7 +17,6 @@ package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import net.minecraft.client.resources.I18n;
@ -32,7 +31,7 @@ import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nonnull;
import java.util.List;
import static malte0811.industrialWires.util.NBTKeys.*;
import static malte0811.industrialWires.util.NBTKeys.COLOR;
public class CoveredToggleSwitch extends ToggleSwitch {
private int color = 0xff0000;
@ -62,15 +61,15 @@ public class CoveredToggleSwitch extends ToggleSwitch {
}
@Override
public void interactWith(Vec3d hitRel, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRel, EntityPlayerMP player) {
if (player.isSneaking() && state == SwitchState.OPEN) {
state = SwitchState.CLOSED;
} else {
state = state.next();
}
setOut(state.active, tile);
tile.markDirty();
tile.triggerRenderUpdate();
setOut(state.active);
panel.markDirty();
panel.triggerRenderUpdate();
}
@Override
@ -83,20 +82,18 @@ public class CoveredToggleSwitch extends ToggleSwitch {
@Override
protected void writeCustomNBT(NBTTagCompound nbt, boolean toItem) {
super.writeCustomNBT(nbt, toItem);
if (!toItem) {
nbt.setInteger("state", state.ordinal());
nbt.setInteger("active", state.ordinal());
}
nbt.setByte(RS_CHANNEL, rsOutputChannel);
nbt.setInteger(RS_ID, rsOutputId);
nbt.setInteger(COLOR, color);
}
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
super.readCustomNBT(nbt);
state = SwitchState.values()[nbt.getInteger("state")];
color = nbt.getInteger(COLOR);
rsOutputChannel = nbt.getByte(RS_CHANNEL);
rsOutputId = nbt.getInteger(RS_ID);
}
@Nonnull
@ -105,8 +102,7 @@ public class CoveredToggleSwitch extends ToggleSwitch {
CoveredToggleSwitch ret = new CoveredToggleSwitch();
ret.color = color;
ret.state = state;
ret.rsOutputChannel = rsOutputChannel;
ret.rsOutputId = rsOutputId;
ret.outputChannel = outputChannel;
ret.active = active;
ret.setX(getX());
ret.setY(getY());
@ -135,6 +131,7 @@ public class CoveredToggleSwitch extends ToggleSwitch {
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
if (type == ConfigType.FLOAT) {
return I18n.format(IndustrialWires.MODID + ".desc." + (id == 0 ? "red" : (id == 1 ? "green" : "blue")));
@ -143,6 +140,7 @@ public class CoveredToggleSwitch extends ToggleSwitch {
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
if (type == ConfigType.FLOAT) {
return null;
@ -163,20 +161,15 @@ public class CoveredToggleSwitch extends ToggleSwitch {
CoveredToggleSwitch that = (CoveredToggleSwitch) o;
if (rsOutputId != that.rsOutputId) return false;
if (rsOutputChannel != that.rsOutputChannel) return false;
if (color != that.color) return false;
return state == that.state;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + rsOutputId;
result = 31 * result + (int) rsOutputChannel;
result = 31 * result + color;
result = 31 * result + (state != null ? state.hashCode() : 0);
result = 31 * result + state.hashCode();
return result;
}

View file

@ -17,6 +17,8 @@ package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.api.tool.IConfigurableTool.ToolConfig;
import net.minecraft.nbt.NBTBase;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
@ -31,20 +33,22 @@ public interface IConfigurableComponent {
* @return a TRANSLATED name for the config option. Try to keep this short.
*/
@Nullable
@SideOnly(Side.CLIENT)
String fomatConfigName(ConfigType type, int id);
/**
* @return a TRANSLATED name for the config option, displayed when hovering over it
*/
@Nullable
@SideOnly(Side.CLIENT)
String fomatConfigDescription(ConfigType type, int id);
default StringConfig[] getStringOptions() {
return new StringConfig[0];
}
default RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[0];
default RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[0];
}
default IntConfig[] getIntegerOptions() {
@ -80,14 +84,14 @@ public interface IConfigurableComponent {
}
}
class RSChannelConfig extends UniversalConfig<Byte> {
class RSColorConfig extends UniversalConfig<Byte> {
public boolean small;
public RSChannelConfig(String name, int x, int y, Byte value) {
public RSColorConfig(String name, int x, int y, Byte value) {
this(name, x, y, value, false);
}
public RSChannelConfig(String name, int x, int y, Byte value, boolean small) {
public RSColorConfig(String name, int x, int y, Byte value, boolean small) {
super(name, x, y, value);
this.small = small;
}

View file

@ -19,12 +19,11 @@ import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@ -41,8 +40,8 @@ import java.util.function.Consumer;
import static malte0811.industrialWires.util.NBTKeys.*;
public class IndicatorLight extends PanelComponent implements IConfigurableComponent {
private int rsInputId;
private byte rsInputChannel;
@Nonnull
private RSChannel inputChannel = RSChannel.INVALID_CHANNEL;
private int colorA = 0xff00;
private byte rsInput;
@ -50,17 +49,16 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
super("indicator_light");
}
public IndicatorLight(int rsId, byte rsChannel, int color) {
public IndicatorLight(@Nonnull RSChannel input, int color) {
this();
colorA = color;
rsInputChannel = rsChannel;
rsInputId = rsId;
inputChannel = input;
}
@Override
protected void writeCustomNBT(NBTTagCompound nbt, boolean toItem) {
nbt.setInteger(RS_ID, rsInputId);
nbt.setByte(RS_CHANNEL, rsInputChannel);
nbt.setInteger(RS_ID, inputChannel.getController());
nbt.setByte(RS_CHANNEL, inputChannel.getColor());
nbt.setInteger(COLOR, colorA);
if (!toItem) {
nbt.setInteger("rsInput", rsInput);
@ -69,8 +67,9 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
rsInputId = nbt.getInteger(RS_ID);
rsInputChannel = nbt.getByte(RS_CHANNEL);
int rsController = nbt.getInteger(RS_ID);
byte rsColor = nbt.getByte(RS_CHANNEL);
inputChannel = new RSChannel(rsController, rsColor);
colorA = nbt.getInteger(COLOR);
rsInput = nbt.getByte("rsInput");
}
@ -96,7 +95,7 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
@Nonnull
@Override
public PanelComponent copyOf() {
IndicatorLight ret = new IndicatorLight(rsInputId, rsInputChannel, colorA);
IndicatorLight ret = new IndicatorLight(inputChannel, colorA);
ret.rsInput = rsInput;
ret.setX(x);
ret.setY(y);
@ -114,31 +113,27 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
}
@Override
public void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRelative, EntityPlayerMP player) {
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
}
private TileEntityPanel panel;
private Consumer<byte[]> handler = (input) -> {
if (input[rsInputChannel] != rsInput) {
rsInput = input[rsInputChannel];
private Consumer<ControlPanelNetwork.RSChannelState> handler = (state) -> {
if (state.getStrength() != rsInput) {
rsInput = state.getStrength();
panel.markDirty();
panel.triggerRenderUpdate();
}
};
@Nullable
@Override
public Consumer<byte[]> getRSInputHandler(int id, TileEntityPanel panel) {
if (matchesId(rsInputId, id)) {
this.panel = panel;
return handler;
}
return null;
public void setNetwork(ControlPanelNetwork net, TileEntityPanel panel) {
super.setNetwork(net, panel);
net.addListener(this, handler, inputChannel);
}
@Override
@ -175,12 +170,16 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
@Override
public void applyConfigOption(ConfigType type, int id, NBTBase value) {
switch (type) {
case RS_CHANNEL:
rsInputChannel = ((NBTTagByte) value).getByte();
break;
case INT:
rsInputId = ((NBTTagInt) value).getInt();
break;
case RS_CHANNEL:
if (id == 0) {
inputChannel = inputChannel.withColor(value);
}
break;
case INT:
if (id == 0) {
inputChannel = inputChannel.withController(value);
}
break;
case FLOAT:
colorA = PanelUtils.setColor(colorA, id, value);
break;
@ -189,6 +188,7 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -202,6 +202,7 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -216,16 +217,16 @@ public class IndicatorLight extends PanelComponent implements IConfigurableCompo
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{
new RSChannelConfig("channel", 0, 0, rsInputChannel)
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{
new RSColorConfig("channel", 0, 0, inputChannel.getColor())
};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{
new IntConfig("rsId", 0, 45, rsInputId, 2, false)
new IntConfig("rsId", 0, 45, inputChannel.getController(), 2, false)
};
}

View file

@ -16,7 +16,6 @@
package malte0811.industrialWires.controlpanel;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.client.panelmodel.RawModelFontRenderer;
@ -101,12 +100,12 @@ public class Label extends PanelComponent implements IConfigurableComponent {
}
@Override
public void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRelative, EntityPlayerMP player) {
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
//NOP
}
@Override
@ -146,6 +145,7 @@ public class Label extends PanelComponent implements IConfigurableComponent {
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -157,6 +157,7 @@ public class Label extends PanelComponent implements IConfigurableComponent {
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case STRING:

View file

@ -19,16 +19,15 @@ import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.util.TriConsumer;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.util.vector.Vector3f;
@ -37,26 +36,26 @@ import java.util.ArrayList;
import java.util.List;
import static malte0811.industrialWires.util.NBTKeys.*;
import static net.minecraftforge.fml.relauncher.Side.CLIENT;
public class LightedButton extends PanelComponent implements IConfigurableComponent {
public int color = 0xFF0000;
public boolean active;
public boolean latching;
public int rsOutputId;
public int rsOutputChannel;
private boolean active;
private boolean latching;
@Nonnull
private RSChannel outputChannel = RSChannel.INVALID_CHANNEL;
private int ticksTillOff;
public LightedButton() {
LightedButton() {
super("lighted_button");
}
public LightedButton(int color, boolean active, boolean latching, int rsOutputId, int rsOutputChannel) {
public LightedButton(int color, boolean active, boolean latching, @Nonnull RSChannel out) {
this();
this.color = color;
this.active = active;
this.latching = latching;
this.rsOutputChannel = rsOutputChannel;
this.rsOutputId = rsOutputId;
this.outputChannel = out;
}
@Override
@ -67,8 +66,8 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
nbt.setBoolean("active", active);
}
nbt.setBoolean(LATCHING, latching);
nbt.setInteger(RS_CHANNEL, rsOutputChannel);
nbt.setInteger(RS_ID, rsOutputId);
nbt.setByte(RS_CHANNEL, outputChannel.getColor());
nbt.setInteger(RS_ID, outputChannel.getController());
}
@Override
@ -77,14 +76,15 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
ticksTillOff = nbt.getInteger("timeout");
active = nbt.getBoolean("active");
latching = nbt.getBoolean(LATCHING);
rsOutputChannel = nbt.getInteger(RS_CHANNEL);
rsOutputId = nbt.getInteger(RS_ID);
byte rsOutputChannel = nbt.getByte(RS_CHANNEL);
int rsOutputId = nbt.getInteger(RS_ID);
this.outputChannel = new RSChannel(rsOutputId, rsOutputChannel);
}
private final static float size = .0625F;
@Override
@SideOnly(Side.CLIENT)
@SideOnly(CLIENT)
public List<RawQuad> getQuads() {
float[] color = PanelUtils.getFloatColor(active, this.color);
List<RawQuad> ret = new ArrayList<>(5);
@ -99,7 +99,7 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
@Override
@Nonnull
public PanelComponent copyOf() {
LightedButton ret = new LightedButton(color, active, latching, rsOutputId, rsOutputChannel);
LightedButton ret = new LightedButton(color, active, latching, outputChannel);
ret.setX(x);
ret.setY(y);
ret.panelHeight = panelHeight;
@ -116,36 +116,34 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
}
@Override
public void interactWith(Vec3d hitRel, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRel, EntityPlayerMP player) {
if (!latching && active) {
ticksTillOff = 10;
} else {
setOut(!active, tile);
setOut(!active);
if (!latching) {
ticksTillOff = 10;
}
}
tile.markDirty();
tile.triggerRenderUpdate();
panel.markDirty();
panel.triggerRenderUpdate();
}
@Override
public void update(TileEntityPanel tile) {
if (!latching && ticksTillOff > 0) {
public void update() {
if (!latching && active) {
ticksTillOff--;
tile.markDirty();
if (ticksTillOff == 0) {
setOut(false, tile);
panel.markDirty();
if (ticksTillOff <= 0) {
setOut(false);
}
}
}
@Override
public void registerRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
if (matchesId(rsOutputId, id)) {
super.registerRSOutput(id, out);
out.accept(rsOutputChannel, (byte) (active ? 15 : 0), this);
}
public void setNetwork(ControlPanelNetwork net, TileEntityPanel te) {
super.setNetwork(net, te);
net.setOutputs(this, new RSChannelState(outputChannel, (byte) (active?15:0)));
}
@Override
@ -154,21 +152,16 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
}
@Override
@SideOnly(Side.CLIENT)
@SideOnly(CLIENT)
public void renderInGUI(GuiPanelCreator gui) {
renderInGUIDefault(gui, 0xff000000 | color);
}
@Override
public void invalidate(TileEntityPanel te) {
setOut(rsOutputChannel, 0);
}
private void setOut(boolean on, TileEntityPanel tile) {
private void setOut(boolean on) {
active = on;
tile.markDirty();
tile.triggerRenderUpdate();
setOut(rsOutputChannel, active ? 15 : 0);
panel.markDirty();
panel.triggerRenderUpdate();
network.setOutputs(this, new RSChannelState(outputChannel, (byte)(active?15:0)));
}
@Override
@ -203,12 +196,12 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
break;
case RS_CHANNEL:
if (id == 0) {
rsOutputChannel = ((NBTTagByte) value).getByte();
outputChannel = outputChannel.withColor(value);
}
break;
case INT:
if (id == 0) {
rsOutputId = ((NBTTagInt) value).getInt();
outputChannel = outputChannel.withController(value);
}
break;
case FLOAT:
@ -218,6 +211,7 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
}
@Override
@SideOnly(CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case BOOL:
@ -233,6 +227,7 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
}
@Override
@SideOnly(CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case BOOL:
@ -249,13 +244,14 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{new RSChannelConfig("channel", 0, 0, (byte) rsOutputChannel)};
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{new RSColorConfig("channel", 0, 0, outputChannel.getColor())};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{new IntConfig("rsId", 0, 50, rsOutputId, 2, false)};
return new IntConfig[]{new IntConfig("rsId", 0, 50,
outputChannel.getController(), 2, false)};
}
@Override

View file

@ -17,11 +17,11 @@ package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import malte0811.industrialWires.items.ItemKey;
import malte0811.industrialWires.util.TriConsumer;
import net.minecraft.block.Block;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.resources.I18n;
@ -53,8 +53,8 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
private NBTTagCompound keyNBT;
private boolean turned;
private boolean latching = false;
private int rsOutputId;
private int rsOutputChannel;
@Nonnull
private RSChannel outputChannel = RSChannel.INVALID_CHANNEL;
private int ticksTillOff;
private int lockID;
@ -65,11 +65,10 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
}
}
public Lock(boolean latching, int rsOutputId, int rsOutputChannel) {
public Lock(boolean latching, @Nonnull RSChannel out) {
this();
this.latching = latching;
this.rsOutputChannel = rsOutputChannel;
this.rsOutputId = rsOutputId;
outputChannel = out;
}
@Override
@ -83,8 +82,8 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
}
nbt.setInteger("lockId", lockID);
nbt.setBoolean(LATCHING, latching);
nbt.setInteger(RS_CHANNEL, rsOutputChannel);
nbt.setInteger(RS_ID, rsOutputId);
nbt.setByte(RS_CHANNEL, outputChannel.getColor());
nbt.setInteger(RS_ID, outputChannel.getController());
}
@Override
@ -100,8 +99,9 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
lockID = nbt.getInteger("lockId");
}
latching = nbt.getBoolean(LATCHING);
rsOutputChannel = nbt.getInteger(RS_CHANNEL);
rsOutputId = nbt.getInteger(RS_ID);
int rsController = nbt.getInteger(RS_CHANNEL);
byte rsColor = nbt.getByte(RS_ID);
outputChannel = new RSChannel(rsController, rsColor);
}
private final static float size = .0625F;
@ -137,6 +137,7 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
return ret;
}
@SideOnly(Side.CLIENT)
private void addKey(List<RawQuad> out, Matrix4 mat) {
PanelUtils.addColoredBox(DARK_GRAY, DARK_GRAY, null, new Vector3f(xOffset, size / 2, zOffsetLowerKey), new Vector3f(keyWidth, keyOffset, size / 2), out, false, mat);
PanelUtils.addColoredBox(DARK_GRAY, DARK_GRAY, null, new Vector3f(xOffset, size / 2 + keyOffset, zOffset), new Vector3f(keyWidth, size, size - 2 * zOffset), out, false, mat);
@ -145,7 +146,7 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
@Override
@Nonnull
public PanelComponent copyOf() {
Lock ret = new Lock(latching, rsOutputId, rsOutputChannel);
Lock ret = new Lock(latching, outputChannel);
ret.turned = turned;
ret.lockID = lockID;
ret.keyNBT = keyNBT == null ? null : keyNBT.copy();
@ -166,7 +167,7 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
}
@Override
public void interactWith(Vec3d hitRel, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRel, EntityPlayerMP player) {
boolean update = false;
if (keyNBT == null) {
for (EnumHand hand : EnumHand.values()) {
@ -194,34 +195,25 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
}
}
if (update) {
setOut(tile);
setOut();
if (!latching && turned) {
ticksTillOff = 10;
}
}
tile.markDirty();
tile.triggerRenderUpdate();
panel.markDirty();
panel.triggerRenderUpdate();
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
if (!latching && ticksTillOff > 0) {
ticksTillOff--;
tile.markDirty();
if (ticksTillOff == 0) {
turned = false;
tile.markDirty();
tile.triggerRenderUpdate();
setOut(tile);
panel.triggerRenderUpdate();
setOut();
}
}
}
@Override
public void registerRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
if (matchesId(rsOutputId, id)) {
super.registerRSOutput(id, out);
out.accept(rsOutputChannel, (byte) (turned ? 15 : 0), this);
panel.markDirty();
}
}
@ -242,22 +234,15 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
Gui.drawRect(left, top, right, bottom, DARK_GRAY_INT);
}
@Override
public void invalidate(TileEntityPanel te) {
setOut(rsOutputChannel, 0);
}
private void setOut(TileEntityPanel tile) {
tile.markDirty();
tile.triggerRenderUpdate();
setOut(rsOutputChannel, turned ? 15 : 0);
private void setOut() {
network.setOutputs(this, new RSChannelState(outputChannel, (byte) (turned ? 15 : 0)));
}
@Override
public void dropItems(TileEntityPanel te) {
super.dropItems(te);
public void dropItems() {
super.dropItems();
if (keyNBT!=null) {
Block.spawnAsEntity(te.getWorld(), te.getPos(), new ItemStack(keyNBT));
Block.spawnAsEntity(panel.getWorld(), panel.getBlockPos(), new ItemStack(keyNBT));
}
}
@ -271,11 +256,10 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
if (turned != lock.turned) return false;
if (latching != lock.latching) return false;
if (rsOutputId != lock.rsOutputId) return false;
if (rsOutputChannel != lock.rsOutputChannel) return false;
if (ticksTillOff != lock.ticksTillOff) return false;
if (lockID != lock.lockID) return false;
return keyNBT != null ? keyNBT.equals(lock.keyNBT) : lock.keyNBT == null;
if (keyNBT != null ? !keyNBT.equals(lock.keyNBT) : lock.keyNBT != null) return false;
return outputChannel.equals(lock.outputChannel);
}
@Override
@ -284,8 +268,7 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
result = 31 * result + (keyNBT != null ? keyNBT.hashCode() : 0);
result = 31 * result + (turned ? 1 : 0);
result = 31 * result + (latching ? 1 : 0);
result = 31 * result + rsOutputId;
result = 31 * result + rsOutputChannel;
result = 31 * result + outputChannel.hashCode();
result = 31 * result + ticksTillOff;
result = 31 * result + lockID;
return result;
@ -294,25 +277,28 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
@Override
public void applyConfigOption(ConfigType type, int id, NBTBase value) {
switch (type) {
case BOOL:
if (id == 0) {
latching = ((NBTTagByte) value).getByte() != 0;
}
break;
case RS_CHANNEL:
if (id == 0) {
rsOutputChannel = ((NBTTagByte) value).getByte();
}
break;
case INT:
if (id == 0) {
rsOutputId = ((NBTTagInt) value).getInt();
}
break;
case BOOL:
if (id == 0) {
latching = ((NBTTagByte) value).getByte() != 0;
}
break;
case RS_CHANNEL:
if (id == 0) {
byte rsColor = ((NBTTagByte) value).getByte();
outputChannel = new RSChannel(outputChannel.getController(), rsColor);
}
break;
case INT:
if (id == 0) {
int rsController = ((NBTTagInt) value).getInt();
outputChannel = new RSChannel(rsController, outputChannel.getColor());
}
break;
}
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case BOOL:
@ -326,6 +312,7 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case BOOL:
@ -340,13 +327,13 @@ public class Lock extends PanelComponent implements IConfigurableComponent {
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{new RSChannelConfig("channel", 0, 0, (byte) rsOutputChannel)};
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{new RSColorConfig("channel", 0, 0, outputChannel.getColor())};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{new IntConfig("rsId", 0, 50, rsOutputId, 2, false)};
return new IntConfig[]{new IntConfig("rsId", 0, 50, outputChannel.getController(), 2, false)};
}
@Override

View file

@ -19,6 +19,7 @@ import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.IOwner;
import malte0811.industrialWires.util.TriConsumer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.GlStateManager;
@ -26,25 +27,26 @@ import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
public abstract class PanelComponent {
public abstract class PanelComponent implements IOwner {
public static final float Y_DELTA = .001F;
protected static final float[] GRAY = {.8F, .8F, .8F};
protected static final int GRAY_INT = 0xFFD0D0D0;
protected static final float[] BLACK = {0, 0, 0, 1};
protected float panelHeight;
protected AxisAlignedBB aabb = null;
protected float x, y;
private final String type;
protected final static float[] GRAY = {.8F, .8F, .8F};
protected final static int GRAY_INT = 0xFFD0D0D0;
protected static final float[] BLACK = {0, 0, 0, 1};
protected TileEntityPanel panel;
protected ControlPanelNetwork network;
private Set<TriConsumer<Integer, Byte, PanelComponent>> outputs = new HashSet<>();
@ -95,33 +97,20 @@ public abstract class PanelComponent {
@Nonnull
public abstract AxisAlignedBB getBlockRelativeAABB();
public abstract void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player);
public abstract void interactWith(Vec3d hitRelative, EntityPlayerMP player);
public abstract void update(TileEntityPanel tile);
public abstract void update();
public abstract int getColor();
@Nullable
public Consumer<byte[]> getRSInputHandler(int id, TileEntityPanel panel) {
return null;
public abstract float getHeight();
public void setNetwork(ControlPanelNetwork net, TileEntityPanel panel) {
this.panel = panel;
this.network = net;
}
public void registerRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
outputs.add(out);
}
public void unregisterRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
outputs.remove(out);
}
protected boolean matchesId(int myId, int theirId) {
return myId==theirId||theirId<0;
}
public void dropItems(TileEntityPanel te) {
}
public void invalidate(TileEntityPanel te) {
public void dropItems() {
}
public float getX() {
@ -132,8 +121,6 @@ public abstract class PanelComponent {
return y;
}
public abstract float getHeight();
public void setX(float x) {
this.x = x;
aabb = null;
@ -148,6 +135,11 @@ public abstract class PanelComponent {
this.panelHeight = panelHeight;
}
@Override
public BlockPos getBlockPos() {
return panel.getBlockPos();
}
public void writeToNBT(NBTTagCompound nbt, boolean toItem) {
writeCustomNBT(nbt, toItem);
nbt.setFloat("x", getX());
@ -175,38 +167,6 @@ public abstract class PanelComponent {
setPanelHeight(nbt.getFloat("panelHeight"));
}
@SideOnly(Side.CLIENT)
public void renderBox(TileEntityPanel te) {
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
te.getComponents().transformGLForTop(te.getPos());
RenderGlobal.drawSelectionBoundingBox(getBlockRelativeAABB().grow(0.002),
0.0F, 0.0F, 0.0F, 0.4F);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
@SideOnly(Side.CLIENT)
public abstract void renderInGUI(GuiPanelCreator gui);
@SideOnly(Side.CLIENT)
public void renderInGUIDefault(GuiPanelCreator gui, int color) {
color |= 0xff000000;
AxisAlignedBB aabb = getBlockRelativeAABB();
int left = (int) (gui.getX0() + aabb.minX * gui.panelSize);
int top = (int) (gui.getY0() + aabb.minZ * gui.panelSize);
int right = (int) (gui.getX0() + aabb.maxX * gui.panelSize);
int bottom = (int) (gui.getY0() + aabb.maxZ * gui.panelSize);
Gui.drawRect(left, top, right, bottom, color);
}
public boolean isValidPos(List<PanelComponent> components, float height, float angle) {
float h = PanelUtils.getHeightWithComponent(this, angle, height);
if (h < 0 || h > 1) {
@ -233,12 +193,38 @@ public abstract class PanelComponent {
return true;
}
void setOut(int channel, int level) {
for (TriConsumer<Integer, Byte, PanelComponent> out : outputs) {
out.accept(channel, (byte) level, this);
}
@SideOnly(Side.CLIENT)
public void renderBox() {
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
panel.getComponents().transformGLForTop(panel.getBlockPos());
RenderGlobal.drawSelectionBoundingBox(getBlockRelativeAABB().grow(0.002),
0.0F, 0.0F, 0.0F, 0.4F);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
@SideOnly(Side.CLIENT)
public abstract void renderInGUI(GuiPanelCreator gui);
@SideOnly(Side.CLIENT)
public void renderInGUIDefault(GuiPanelCreator gui, int color) {
color |= 0xff000000;
AxisAlignedBB aabb = getBlockRelativeAABB();
int left = (int) (gui.getX0() + aabb.minX * gui.panelSize);
int top = (int) (gui.getY0() + aabb.minZ * gui.panelSize);
int right = (int) (gui.getX0() + aabb.maxX * gui.panelSize);
int bottom = (int) (gui.getY0() + aabb.maxZ * gui.panelSize);
Gui.drawRect(left, top, right, bottom, color);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View file

@ -21,6 +21,8 @@ import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.client.panelmodel.RawModelFontRenderer;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
@ -28,7 +30,6 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@ -45,33 +46,30 @@ import java.util.function.Consumer;
import static malte0811.industrialWires.util.NBTKeys.*;
public class PanelMeter extends PanelComponent implements IConfigurableComponent {
private int rsInputId, rsInputId2 = -1;
private byte rsInputChannel, rsInputChannel2;
@Nonnull
private RSChannel primary = RSChannel.INVALID_CHANNEL;
@Nonnull
private RSChannel secondary = RSChannel.INVALID_CHANNEL;
private int rsInput;
private boolean wide = true;
private boolean hasSecond;
public PanelMeter() {
super("panel_meter");
}
public PanelMeter(int rsId, byte rsChannel, int rsId2, byte rsChannel2, boolean wide, boolean hasSecond) {
public PanelMeter(@Nonnull RSChannel primary, @Nonnull RSChannel secondary, boolean wide) {
this();
rsInputChannel = rsChannel;
rsInputId = rsId;
rsInputChannel2 = rsChannel2;
rsInputId2 = rsId2;
this.hasSecond = hasSecond;
this.primary = primary;
this.secondary = secondary;
this.wide = wide;
}
@Override
protected void writeCustomNBT(NBTTagCompound nbt, boolean toItem) {
nbt.setInteger(RS_ID, rsInputId);
nbt.setByte(RS_CHANNEL, rsInputChannel);
nbt.setInteger(RS_ID2, rsInputId2);
nbt.setByte(RS_CHANNEL2, rsInputChannel2);
nbt.setInteger(RS_ID, primary.getController());
nbt.setByte(RS_CHANNEL, primary.getColor());
nbt.setInteger(RS_ID2, secondary.getController());
nbt.setByte(RS_CHANNEL2, secondary.getColor());
nbt.setBoolean(WIDE, wide);
if (!toItem) {
nbt.setInteger("rsInput", rsInput);
@ -80,20 +78,17 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
rsInputId = nbt.getInteger(RS_ID);
rsInputChannel = nbt.getByte(RS_CHANNEL);
int rsController = nbt.getInteger(RS_ID);
byte rsColor = nbt.getByte(RS_CHANNEL);
primary = new RSChannel(rsController, rsColor);
rsInput = nbt.getInteger("rsInput");
wide = nbt.getBoolean(WIDE);
if (nbt.hasKey(RS_ID2)) {
rsInputId2 = nbt.getInteger(RS_ID2);
rsInputChannel2 = nbt.getByte(RS_CHANNEL2);
hasSecond = rsInputId2>=0&&rsInputChannel2>=0;
rsController = nbt.getInteger(RS_ID2);
rsColor = nbt.getByte(RS_CHANNEL2);
secondary = new RSChannel(rsController, rsColor);
} else {
hasSecond = false;
}
if (!hasSecond) {
rsInputId2 = -1;
rsInputChannel2 = -1;
secondary = RSChannel.INVALID_CHANNEL;
}
}
@ -169,7 +164,7 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
@Nonnull
@Override
public PanelComponent copyOf() {
PanelMeter ret = new PanelMeter(rsInputId, rsInputChannel, rsInputId2, rsInputChannel2, wide, hasSecond);
PanelMeter ret = new PanelMeter(primary, secondary, wide);
ret.rsInput = rsInput;
ret.setX(x);
ret.setY(y);
@ -187,48 +182,40 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
}
@Override
public void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRelative, EntityPlayerMP player) {
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
}
private TileEntityPanel panel;
private Consumer<byte[]> handlerSec = (input) -> {
if (input[rsInputChannel2] != (rsInput&0xf)) {
rsInput = (input[rsInputChannel2]&0xf)|(rsInput&0xf0);
panel.markDirty();
panel.triggerRenderUpdate();
}
};
private Consumer<byte[]> handler = (input) -> {
if (input[rsInputChannel] != rsInput>>4) {
if (hasSecond) {
rsInput = (input[rsInputChannel]<<4)|(rsInput&0xf);
} else {
rsInput = input[rsInputChannel]*17;
@Override
public void setNetwork(ControlPanelNetwork net, TileEntityPanel panel) {
super.setNetwork(net, panel);
Consumer<RSChannelState> listenerPrimary = (input) -> {
byte strength = input.getStrength();
if (strength != rsInput >> 4) {
if (secondary.isValid()) {
rsInput = (strength << 4) | (rsInput & 0xf);
} else {
rsInput = strength * 17;
}
panel.markDirty();
panel.triggerRenderUpdate();
}
panel.markDirty();
panel.triggerRenderUpdate();
};
net.addListener(this, listenerPrimary, primary);
if (secondary.isValid()) {
Consumer<RSChannelState> listenerSec = (input) -> {
if (input.getStrength() != (rsInput & 0xf)) {
rsInput = (input.getStrength() & 0xf) | (rsInput & 0xf0);
panel.markDirty();
panel.triggerRenderUpdate();
}
};
net.addListener(this, listenerSec, secondary);
}
if (rsInputId2==rsInputId) {
handlerSec.accept(input);
}
};
@Nullable
@Override
public Consumer<byte[]> getRSInputHandler(int id, TileEntityPanel panel) {
if (matchesId(rsInputId, id)) {
this.panel = panel;
return handler;
} else if (matchesId(rsInputId2, id)) {
this.panel = panel;
return handlerSec;
}
return null;
}
@Override
@ -244,25 +231,19 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
PanelMeter that = (PanelMeter) o;
if (rsInputId != that.rsInputId) return false;
if (rsInputId2 != that.rsInputId2) return false;
if (rsInputChannel != that.rsInputChannel) return false;
if (rsInputChannel2 != that.rsInputChannel2) return false;
if (rsInput != that.rsInput) return false;
if (wide != that.wide) return false;
return hasSecond == that.hasSecond;
if (!primary.equals(that.primary)) return false;
return secondary.equals(that.secondary);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + rsInputId;
result = 31 * result + rsInputId2;
result = 31 * result + (int) rsInputChannel;
result = 31 * result + (int) rsInputChannel2;
result = 31 * result + primary.hashCode();
result = 31 * result + secondary.hashCode();
result = 31 * result + rsInput;
result = 31 * result + (wide ? 1 : 0);
result = 31 * result + (hasSecond ? 1 : 0);
return result;
}
@ -279,7 +260,6 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
GlStateManager.pushMatrix();
int border = (int) Math.ceil(BORDER*gui.panelSize);
int width = right-left;
int height = bottom-top;
if (wide) {
GlStateManager.translate(left+width/2D, bottom-2*border, 0);
GlStateManager.rotate(135, 0, 0, 1);
@ -300,17 +280,16 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
switch (type) {
case RS_CHANNEL:
if (id == 0) {
rsInputChannel = ((NBTTagByte) value).getByte();
primary = primary.withColor(value);
} else {
rsInputChannel2 = ((NBTTagByte) value).getByte();
secondary = secondary.withColor(value);
}
break;
case INT:
if (id == 0) {
rsInputId = ((NBTTagInt) value).getInt();
primary = primary.withController(value);
} else {
rsInputId2 = ((NBTTagInt) value).getInt();
hasSecond = rsInputId2>=0;
secondary = secondary.withController(value);
}
break;
case BOOL:
@ -320,6 +299,7 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -335,6 +315,7 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -349,18 +330,18 @@ public class PanelMeter extends PanelComponent implements IConfigurableComponent
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{
new RSChannelConfig("channel", 0, 0, rsInputChannel, false),
new RSChannelConfig("channel2", 60, 0, rsInputChannel2, false)
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{
new RSColorConfig("channel", 0, 0, primary.getColor(), false),
new RSColorConfig("channel2", 60, 0, secondary.getColor(), false)
};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{
new IntConfig("rsId", 0, 60, rsInputId, 2, false),
new IntConfig("rsId2", 60, 60, rsInputId2, 2, true)
new IntConfig("rsId", 0, 60, primary.getController(), 2, false),
new IntConfig("rsId2", 60, 60, secondary.getController(), 2, true)
};
}

View file

@ -18,12 +18,10 @@ package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.api.Lib;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.BlockPanel;
import malte0811.industrialWires.blocks.controlpanel.BlockTypes_Panel;
import malte0811.industrialWires.client.ClientUtilsIW;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.controlpanel.PropertyComponents.PanelRenderProperties;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@ -38,9 +36,7 @@ import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.obj.OBJModel;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
@ -52,9 +48,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiPredicate;
import static malte0811.industrialWires.util.MiscUtils.discoverLocal;
import static malte0811.industrialWires.util.NBTKeys.*;
public final class PanelUtils {
@ -367,27 +361,6 @@ public final class PanelUtils {
return panelBase;
}
public static List<BlockPos> discoverPanelParts(World w, BlockPos here, int maxCount) {
BiPredicate<BlockPos, Integer> isValid = (pos, count) -> {
if (pos.equals(here)) {
return true;
}
if (here.distanceSq(pos) > 25 || count > maxCount || !w.isBlockLoaded(pos)) {
return false;
}
IBlockState state = w.getBlockState(pos);
return state.getBlock() == IndustrialWires.panel && state.getValue(BlockPanel.type).isPanelConnector();
};
List<BlockPos> all = discoverLocal(w, here, isValid);
List<BlockPos> ret = new ArrayList<>();
for (BlockPos pos : all) {
if (w.getBlockState(pos).getBlock() == IndustrialWires.panel && w.getBlockState(pos).getValue(BlockPanel.type) != BlockTypes_Panel.DUMMY) {
ret.add(pos);
}
}
return ret;
}
public static float getAngle(ItemStack inv) {
float angle = 0;
NBTTagCompound nbt = inv.getTagCompound();

View file

@ -19,13 +19,13 @@ import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec2f;
@ -84,24 +84,23 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
private int color = 0xff00;
private byte input = 0;
private int rsInputId;
private byte rsInputChannel;
@Nonnull
private RSChannel inputChannel = RSChannel.INVALID_CHANNEL;
public SevenSegDisplay() {
super(NAME);
}
public SevenSegDisplay(int rsId, byte rsChannel, int color) {
public SevenSegDisplay(@Nonnull RSChannel in, int color) {
this();
this.color = color;
rsInputChannel = rsChannel;
rsInputId = rsId;
inputChannel = in;
}
@Override
protected void writeCustomNBT(NBTTagCompound nbt, boolean toItem) {
nbt.setInteger(RS_ID, rsInputId);
nbt.setByte(RS_CHANNEL, rsInputChannel);
nbt.setInteger(RS_ID, inputChannel.getController());
nbt.setByte(RS_CHANNEL, inputChannel.getColor());
nbt.setInteger(COLOR, color);
if (!toItem) {
nbt.setInteger("rsInput", input);
@ -110,29 +109,25 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
rsInputId = nbt.getInteger(RS_ID);
rsInputChannel = nbt.getByte(RS_CHANNEL);
int rsController = nbt.getInteger(RS_ID);
byte rsColor = nbt.getByte(RS_CHANNEL);
inputChannel = new RSChannel(rsController, rsColor);
color = nbt.getInteger(COLOR);
input = nbt.getByte("rsInput");
}
private TileEntityPanel panel;
private Consumer<byte[]> handler = (inputNew) -> {
if (inputNew[rsInputChannel] != input) {
input = inputNew[rsInputChannel];
panel.markDirty();
panel.triggerRenderUpdate();
}
};
@Nullable
@Override
public Consumer<byte[]> getRSInputHandler(int id, TileEntityPanel panel) {
if (matchesId(rsInputId, id)) {
this.panel = panel;
return handler;
}
return null;
public void setNetwork(ControlPanelNetwork net, TileEntityPanel panel) {
super.setNetwork(net, panel);
Consumer<RSChannelState> handler = (inputNew) -> {
if (inputNew.getStrength() != input) {
input = inputNew.getStrength();
panel.markDirty();
panel.triggerRenderUpdate();
}
};
net.addListener(this, handler, inputChannel);
}
@Override
@ -187,7 +182,7 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
@Nonnull
@Override
public PanelComponent copyOf() {
SevenSegDisplay ret = new SevenSegDisplay(rsInputId, rsInputChannel, color);
SevenSegDisplay ret = new SevenSegDisplay(inputChannel, color);
ret.input = input;
ret.setX(x);
ret.setY(y);
@ -204,12 +199,12 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
}
@Override
public void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRelative, EntityPlayerMP player) {
//NOP
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
//NOP
}
@ -244,10 +239,10 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
public void applyConfigOption(ConfigType type, int id, NBTBase value) {
switch (type) {
case RS_CHANNEL:
rsInputChannel = ((NBTTagByte) value).getByte();
inputChannel = inputChannel.withColor(value);
break;
case INT:
rsInputId = ((NBTTagInt) value).getInt();
inputChannel = inputChannel.withController(value);
break;
case FLOAT:
color = PanelUtils.setColor(color, id, value);
@ -257,6 +252,7 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -270,6 +266,7 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
@Nullable
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case FLOAT:
@ -284,16 +281,16 @@ public class SevenSegDisplay extends PanelComponent implements IConfigurableComp
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{
new RSChannelConfig("channel", 0, 0, rsInputChannel)
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{
new RSColorConfig("channel", 0, 0, inputChannel.getColor())
};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{
new IntConfig("rsId", 0, 45, rsInputId, 2, false)
new IntConfig("rsId", 0, 45, inputChannel.getController(), 2, false)
};
}

View file

@ -16,14 +16,17 @@
package malte0811.industrialWires.controlpanel;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.util.TriConsumer;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.*;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@ -33,9 +36,7 @@ import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static malte0811.industrialWires.util.NBTKeys.*;
@ -45,23 +46,18 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
private int color = 0xffff00;
private boolean horizontal;
private int out;
private byte rsChannel;
private int rsId;
private boolean hasSecond;
private byte rsChannel2;
private int rsId2 = -1;
private Set<TriConsumer<Integer, Byte, PanelComponent>> secOutputs = new HashSet<>();
@Nonnull
private RSChannel primary = RSChannel.INVALID_CHANNEL;
@Nonnull
private RSChannel secondary = RSChannel.INVALID_CHANNEL;
public Slider(float length, int color, boolean horizontal, int rsId, byte rsChannel, boolean hasSecond, int rsId2, byte rsChannel2) {
public Slider(float length, int color, boolean horizontal, @Nonnull RSChannel primary, @Nonnull RSChannel secondary) {
this();
this.color = color;
this.length = length;
this.horizontal = horizontal;
this.rsChannel = rsChannel;
this.rsId = rsId;
this.hasSecond = hasSecond;
this.rsChannel2 = rsChannel2;
this.rsId2 = rsId2;
this.primary = primary;
this.secondary = secondary;
}
public Slider() {
@ -75,10 +71,10 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
if (!toItem) {
nbt.setInteger("output", out);
}
nbt.setByte(RS_CHANNEL, rsChannel);
nbt.setInteger(RS_ID, rsId);
nbt.setByte(RS_CHANNEL2, rsChannel2);
nbt.setInteger(RS_ID2, rsId2);
nbt.setInteger(RS_ID, primary.getController());
nbt.setByte(RS_CHANNEL, primary.getColor());
nbt.setInteger(RS_ID2, secondary.getController());
nbt.setByte(RS_CHANNEL2, secondary.getColor());
nbt.setBoolean(HORIZONTAL, horizontal);
}
@ -88,14 +84,15 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
length = nbt.getFloat(LENGTH);
horizontal = nbt.getBoolean(HORIZONTAL);
out = nbt.getInteger("output");
rsChannel = nbt.getByte(RS_CHANNEL);
rsId = nbt.getInteger(RS_ID);
rsChannel2 = nbt.getByte(RS_CHANNEL2);
rsId2 = nbt.getInteger(RS_ID2);
hasSecond = rsId2>=0&&rsChannel2>=0;
if (!hasSecond) {
rsChannel2 = -1;
rsId2 = -1;
int rsController = nbt.getInteger(RS_ID);
byte rsColor = nbt.getByte(RS_CHANNEL);
primary = new RSChannel(rsController, rsColor);
if (nbt.hasKey(RS_ID2)) {
rsController = nbt.getInteger(RS_ID2);
rsColor = nbt.getByte(RS_CHANNEL2);
secondary = new RSChannel(rsController, rsColor);
} else {
secondary = RSChannel.INVALID_CHANNEL;
}
}
@ -129,7 +126,7 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
@Nonnull
@Override
public PanelComponent copyOf() {
Slider ret = new Slider(length, color, horizontal, rsId, rsChannel, hasSecond, rsId2, rsChannel2);
Slider ret = new Slider(length, color, horizontal, primary, secondary);
ret.out = out;
ret.setX(x);
ret.setY(y);
@ -147,37 +144,19 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
}
@Override
public void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRelative, EntityPlayerMP player) {
double pos = horizontal ? hitRelative.x : (length - hitRelative.z);
int newLevel = (int) Math.min(pos * 256 / length, 255);
if (newLevel != out) {
setOut(newLevel);
out = newLevel;
tile.markDirty();
tile.triggerRenderUpdate();
panel.markDirty();
panel.triggerRenderUpdate();
}
}
@Override
public void registerRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
if (matchesId(rsId, id)) {
super.registerRSOutput(id, out);
out.accept((int) rsChannel, (byte) (this.out>>4), this);
}
if (matchesId(rsId2, id)&&hasSecond) {
secOutputs.add(out);
out.accept((int) rsChannel2, (byte) (this.out&0xf), this);
}
}
@Override
public void unregisterRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
super.unregisterRSOutput(id, out);
secOutputs.remove(out);
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
}
@ -199,18 +178,9 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
Gui.drawRect(left, top, right, bottom, 0xff000000 | color);
}
@Override
public void invalidate(TileEntityPanel te) {
setOut(0);
}
public void setOut(int value) {
super.setOut(rsChannel, value>>4);
if (hasSecond) {
for (TriConsumer<Integer, Byte, PanelComponent> cons:secOutputs) {
cons.accept((int) rsChannel2, (byte) (value&0xf), this);
}
}
network.setOutputs(this, new RSChannelState(primary, (byte) (value>>4)));
network.setOutputs(this, new RSChannelState(secondary, (byte) (value&0xf)));
}
@Override
@ -225,11 +195,8 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
if (color != slider.color) return false;
if (horizontal != slider.horizontal) return false;
if (out != slider.out) return false;
if (rsChannel != slider.rsChannel) return false;
if (rsId != slider.rsId) return false;
if (hasSecond != slider.hasSecond) return false;
if (rsChannel2 != slider.rsChannel2) return false;
return rsId2 == slider.rsId2;
if (!primary.equals(slider.primary)) return false;
return secondary.equals(slider.secondary);
}
@Override
@ -239,42 +206,38 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
result = 31 * result + color;
result = 31 * result + (horizontal ? 1 : 0);
result = 31 * result + out;
result = 31 * result + (int) rsChannel;
result = 31 * result + rsId;
result = 31 * result + (hasSecond ? 1 : 0);
result = 31 * result + (int) rsChannel2;
result = 31 * result + rsId2;
result = 31 * result + primary.hashCode();
result = 31 * result + secondary.hashCode();
return result;
}
@Override
public void applyConfigOption(ConfigType type, int id, NBTBase value) {
switch (type) {
case BOOL:
horizontal = ((NBTTagByte) value).getByte() != 0;
break;
case RS_CHANNEL:
if (id==0) {
rsChannel = ((NBTTagByte) value).getByte();
} else {
rsChannel2 = ((NBTTagByte) value).getByte();
}
break;
case INT:
if (id==0) {
rsId = ((NBTTagInt) value).getInt();
} else {
rsId2 = ((NBTTagInt) value).getInt();
hasSecond = rsId2>=0;
}
break;
case FLOAT:
if (id < 3) {
color = PanelUtils.setColor(color, id, value);
} else {
length = scaleToRangePercent(((NBTTagFloat) value).getFloat(), .125F, 1);
}
break;
case BOOL:
horizontal = ((NBTTagByte) value).getByte() != 0;
break;
case RS_CHANNEL:
if (id == 0) {
primary = primary.withColor(value);
} else {
secondary = secondary.withColor(value);
}
break;
case INT:
if (id == 0) {
primary = primary.withController(value);
} else {
secondary = secondary.withController(value);
}
break;
case FLOAT:
if (id < 3) {
color = PanelUtils.setColor(color, id, value);
} else {
length = scaleToRangePercent(((NBTTagFloat) value).getFloat(), .125F, 1);
}
break;
}
}
@ -283,6 +246,7 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case BOOL:
@ -298,6 +262,7 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case BOOL:
@ -314,18 +279,18 @@ public class Slider extends PanelComponent implements IConfigurableComponent {
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{
new RSChannelConfig("channel", 0, 0, rsChannel, true),
new RSChannelConfig("channel", 30, 0, rsChannel2, true)
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{
new RSColorConfig("channel", 0, 0, primary.getColor(), false),
new RSColorConfig("channel2", 60, 0, secondary.getColor(), false)
};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{
new IntConfig("rsId", 0, 30, rsId, 2, false),
new IntConfig("rsId", 30, 30, rsId2, 2, true)
new IntConfig("rsId", 0, 60, primary.getController(), 2, false),
new IntConfig("rsId2", 60, 60, secondary.getController(), 2, true)
};
}

View file

@ -17,17 +17,15 @@ package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.util.TriConsumer;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannelState;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@ -43,23 +41,22 @@ import static malte0811.industrialWires.util.NBTKeys.RS_CHANNEL;
import static malte0811.industrialWires.util.NBTKeys.RS_ID;
public class ToggleSwitch extends PanelComponent implements IConfigurableComponent {
public boolean active;
public int rsOutputId;
public byte rsOutputChannel;
protected boolean active;
@Nonnull
protected RSChannel outputChannel = RSChannel.INVALID_CHANNEL;
public ToggleSwitch() {
super("toggle_switch");
}
public ToggleSwitch(String name) {
protected ToggleSwitch(String name) {
super(name);
}
public ToggleSwitch(boolean active, int rsOutputId, byte rsOutputChannel) {
public ToggleSwitch(boolean active, @Nonnull RSChannel outputChannel) {
this();
this.active = active;
this.rsOutputChannel = rsOutputChannel;
this.rsOutputId = rsOutputId;
this.outputChannel = outputChannel;
}
@Override
@ -67,15 +64,16 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
if (!toItem) {
nbt.setBoolean("active", active);
}
nbt.setByte(RS_CHANNEL, rsOutputChannel);
nbt.setInteger(RS_ID, rsOutputId);
nbt.setByte(RS_CHANNEL, outputChannel.getColor());
nbt.setInteger(RS_ID, outputChannel.getController());
}
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
active = nbt.getBoolean("active");
rsOutputChannel = nbt.getByte(RS_CHANNEL);
rsOutputId = nbt.getInteger(RS_ID);
int rsController = nbt.getInteger(RS_ID);
byte rsColor = nbt.getByte(RS_CHANNEL);
outputChannel = new RSChannel(rsController, rsColor);
}
protected float sizeX = .0625F;
@ -102,7 +100,7 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
@Override
@Nonnull
public PanelComponent copyOf() {
ToggleSwitch ret = new ToggleSwitch(active, rsOutputId, rsOutputChannel);
ToggleSwitch ret = new ToggleSwitch(active, outputChannel);
ret.setX(x);
ret.setY(y);
ret.panelHeight = panelHeight;
@ -119,25 +117,15 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
}
@Override
public void interactWith(Vec3d hitRel, TileEntityPanel tile, EntityPlayerMP player) {
setOut(!active, tile);
tile.markDirty();
tile.triggerRenderUpdate();
public void interactWith(Vec3d hitRel, EntityPlayerMP player) {
setOut(!active);
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
}
@Override
public void registerRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
if (matchesId(rsOutputId, id)) {
super.registerRSOutput(id, out);
out.accept((int) rsOutputChannel, (byte) (active ? 15 : 0), this);
}
}
@Override
public float getHeight() {
return .0625F * 3 / 2;
@ -162,16 +150,11 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
}
@Override
public void invalidate(TileEntityPanel te) {
setOut(rsOutputChannel, 0);
}
protected void setOut(boolean on, TileEntityPanel tile) {
protected void setOut(boolean on) {
active = on;
tile.markDirty();
tile.triggerRenderUpdate();
setOut(rsOutputChannel, active ? 15 : 0);
panel.markDirty();
panel.triggerRenderUpdate();
network.setOutputs(this, new RSChannelState(outputChannel, (byte) (active ? 15 : 0)));
}
@Override
@ -183,16 +166,22 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
ToggleSwitch that = (ToggleSwitch) o;
if (active != that.active) return false;
if (rsOutputId != that.rsOutputId) return false;
return rsOutputChannel == that.rsOutputChannel;
if (Float.compare(that.sizeX, sizeX) != 0) return false;
if (Float.compare(that.sizeY, sizeY) != 0) return false;
if (Float.compare(that.rodRadius, rodRadius) != 0) return false;
if (Float.compare(that.rodLength, rodLength) != 0) return false;
return outputChannel.equals(that.outputChannel);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (active ? 1 : 0);
result = 31 * result + rsOutputId;
result = 31 * result + (int) rsOutputChannel;
result = 31 * result + outputChannel.hashCode();
result = 31 * result + (sizeX != +0.0f ? Float.floatToIntBits(sizeX) : 0);
result = 31 * result + (sizeY != +0.0f ? Float.floatToIntBits(sizeY) : 0);
result = 31 * result + (rodRadius != +0.0f ? Float.floatToIntBits(rodRadius) : 0);
result = 31 * result + (rodLength != +0.0f ? Float.floatToIntBits(rodLength) : 0);
return result;
}
@ -200,19 +189,16 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
public void applyConfigOption(ConfigType type, int id, NBTBase value) {
switch (type) {
case RS_CHANNEL:
if (id == 0) {
rsOutputChannel = ((NBTTagByte) value).getByte();
}
outputChannel = outputChannel.withColor(value);
break;
case INT:
if (id == 0) {
rsOutputId = ((NBTTagInt) value).getInt();
}
outputChannel = outputChannel.withController(value);
break;
}
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigName(ConfigType type, int id) {
switch (type) {
case RS_CHANNEL:
@ -226,6 +212,7 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(ConfigType type, int id) {
switch (type) {
case RS_CHANNEL:
@ -240,13 +227,13 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone
}
@Override
public RSChannelConfig[] getRSChannelOptions() {
return new RSChannelConfig[]{new RSChannelConfig("channel", 0, 0, (byte) rsOutputChannel)};
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{new RSColorConfig("channel", 0, 0, outputChannel.getColor())};
}
@Override
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{new IntConfig("rsId", 0, 50, rsOutputId, 2, false)};
return new IntConfig[]{new IntConfig("rsId", 0, 50, outputChannel.getController(), 2, false)};
}
@Override

View file

@ -17,18 +17,15 @@ package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.client.RawQuad;
import malte0811.industrialWires.client.gui.GuiPanelCreator;
import malte0811.industrialWires.util.TriConsumer;
import malte0811.industrialWires.controlpanel.ControlPanelNetwork.RSChannel;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@ -38,9 +35,7 @@ import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static malte0811.industrialWires.util.NBTKeys.*;
@ -55,20 +50,15 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
private static final float arrowSize = .0625F / 2;
private int out;
private byte rsChannel;
private int rsId;
private boolean hasSecond;
private byte rsChannel2;
private int rsId2 = -1;
private Set<TriConsumer<Integer, Byte, PanelComponent>> secOutputs = new HashSet<>();
@Nonnull
private RSChannel primary = RSChannel.INVALID_CHANNEL;
@Nonnull
private RSChannel secondary = RSChannel.INVALID_CHANNEL;
public Variac(int rsId, byte rsChannel, int rsId2, byte rsChannel2, boolean hasSecond) {
public Variac(@Nonnull RSChannel primary, @Nonnull RSChannel secondary) {
this();
this.rsChannel = rsChannel;
this.rsId = rsId;
this.hasSecond = hasSecond;
this.rsChannel2 = rsChannel2;
this.rsId2 = rsId2;
this.primary = primary;
this.secondary = secondary;
}
public Variac() {
@ -80,23 +70,24 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
if (!toItem) {
nbt.setInteger("output", out);
}
nbt.setByte(RS_CHANNEL, rsChannel);
nbt.setInteger(RS_ID, rsId);
nbt.setByte(RS_CHANNEL2, rsChannel2);
nbt.setInteger(RS_ID2, rsId2);
nbt.setInteger(RS_ID, primary.getController());
nbt.setByte(RS_CHANNEL, primary.getColor());
nbt.setInteger(RS_ID2, secondary.getController());
nbt.setByte(RS_CHANNEL2, secondary.getColor());
}
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
out = nbt.getInteger("output");
rsChannel = nbt.getByte(RS_CHANNEL);
rsId = nbt.getInteger(RS_ID);
rsChannel2 = nbt.getByte(RS_CHANNEL2);
rsId2 = nbt.getInteger(RS_ID2);
hasSecond = rsChannel2>=0&&rsId2>=0;
if (!hasSecond) {
rsChannel2 = -1;
rsId2 = -1;
int rsController = nbt.getInteger(RS_ID);
byte rsColor = nbt.getByte(RS_CHANNEL);
primary = new RSChannel(rsController, rsColor);
if (nbt.hasKey(RS_ID2)) {
rsController = nbt.getInteger(RS_ID2);
rsColor = nbt.getByte(RS_CHANNEL2);
secondary = new RSChannel(rsController, rsColor);
} else {
secondary = RSChannel.INVALID_CHANNEL;
}
}
@ -130,7 +121,7 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
@Nonnull
@Override
public PanelComponent copyOf() {
Variac ret = new Variac(rsId, rsChannel, rsId2, rsChannel2, hasSecond);
Variac ret = new Variac(primary, secondary);
ret.out = out;
ret.setX(x);
ret.setY(y);
@ -148,7 +139,7 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
}
@Override
public void interactWith(Vec3d hitRelative, TileEntityPanel tile, EntityPlayerMP player) {
public void interactWith(Vec3d hitRelative, EntityPlayerMP player) {
double xRel = hitRelative.x - SIZE / 2;
double yRel = -(hitRelative.z - SIZE / 2);
double angle = 1.5 * Math.PI - Math.atan2(yRel, xRel);
@ -158,7 +149,7 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
angle -= 2 * Math.PI;
}
angle /= 2 * Math.PI;
int step = (hasSecond&&player.isSneaking())?1:16;
int step = (secondary.isValid()&&player.isSneaking())?1:16;
int newLevel = (int) ((angle-1/34F) * 17 * 16);
int diff = Math.abs(newLevel-out);
if (diff>step) {
@ -172,31 +163,13 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
if (newLevel != out) {
setOut(newLevel);
out = newLevel;
tile.markDirty();
tile.triggerRenderUpdate();
panel.markDirty();
panel.triggerRenderUpdate();
}
}
@Override
public void registerRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
if (matchesId(rsId, id)) {
super.registerRSOutput(id, out);
out.accept((int) rsChannel, (byte) (this.out>>4), this);
}
if (matchesId(rsId2, id)&&hasSecond) {
secOutputs.add(out);
out.accept((int)rsChannel2, (byte) (this.out&0xf), this);
}
}
@Override
public void unregisterRSOutput(int id, @Nonnull TriConsumer<Integer, Byte, PanelComponent> out) {
super.unregisterRSOutput(id, out);
secOutputs.remove(out);
}
@Override
public void update(TileEntityPanel tile) {
public void update() {
}
@ -226,18 +199,9 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
GlStateManager.popMatrix();
}
@Override
public void invalidate(TileEntityPanel te) {
setOut(0);
}
public void setOut(int level) {
if (hasSecond) {
for (TriConsumer<Integer, Byte, PanelComponent> cons:secOutputs) {
cons.accept((int)rsChannel2, (byte) (level&0xf), this);
}
}
super.setOut(rsChannel, (byte)(level>>4));
public void setOut(int value) {
network.setOutputs(this, new ControlPanelNetwork.RSChannelState(primary, (byte) (value>>4)));
network.setOutputs(this, new ControlPanelNetwork.RSChannelState(secondary, (byte) (value&0xf)));
}
@Override
@ -249,43 +213,36 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
Variac variac = (Variac) o;
if (out != variac.out) return false;
if (rsChannel != variac.rsChannel) return false;
if (rsId != variac.rsId) return false;
if (hasSecond != variac.hasSecond) return false;
if (rsChannel2 != variac.rsChannel2) return false;
return rsId2 == variac.rsId2;
if (!primary.equals(variac.primary)) return false;
return secondary.equals(variac.secondary);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + out;
result = 31 * result + (int) rsChannel;
result = 31 * result + rsId;
result = 31 * result + (hasSecond ? 1 : 0);
result = 31 * result + (int) rsChannel2;
result = 31 * result + rsId2;
result = 31 * result + primary.hashCode();
result = 31 * result + secondary.hashCode();
return result;
}
@Override
public void applyConfigOption(IConfigurableComponent.ConfigType type, int id, NBTBase value) {
switch (type) {
case RS_CHANNEL:
if (id==0) {
rsChannel = ((NBTTagByte) value).getByte();
} else {
rsChannel2 = ((NBTTagByte) value).getByte();
}
break;
case INT:
if (id==0) {
rsId = ((NBTTagInt) value).getInt();
} else {
rsId2 = ((NBTTagInt) value).getInt();
hasSecond = rsId2>=0;
}
break;
case RS_CHANNEL:
if (id == 0) {
primary = primary.withColor(value);
} else {
secondary = secondary.withColor(value);
}
break;
case INT:
if (id == 0) {
primary = primary.withController(value);
} else {
secondary = secondary.withController(value);
}
break;
}
}
@ -295,6 +252,7 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
}
@Override
@SideOnly(Side.CLIENT)
public String fomatConfigDescription(IConfigurableComponent.ConfigType type, int id) {
switch (type) {
case RS_CHANNEL:
@ -307,18 +265,18 @@ public class Variac extends PanelComponent implements IConfigurableComponent {
}
@Override
public IConfigurableComponent.RSChannelConfig[] getRSChannelOptions() {
return new IConfigurableComponent.RSChannelConfig[]{
new IConfigurableComponent.RSChannelConfig("channel", 0, 0, rsChannel),
new IConfigurableComponent.RSChannelConfig("channel", 90, 0, rsChannel2)
public RSColorConfig[] getRSChannelOptions() {
return new RSColorConfig[]{
new RSColorConfig("channel", 0, 0, primary.getColor(), false),
new RSColorConfig("channel2", 60, 0, secondary.getColor(), false)
};
}
@Override
public IConfigurableComponent.IntConfig[] getIntegerOptions() {
return new IConfigurableComponent.IntConfig[]{
new IConfigurableComponent.IntConfig("rsId", 0, 50, rsId, 2, false),
new IConfigurableComponent.IntConfig("rsId", 90, 50, rsId2, 2, true)
public IntConfig[] getIntegerOptions() {
return new IntConfig[]{
new IntConfig("rsId", 0, 60, primary.getController(), 2, false),
new IntConfig("rsId2", 60, 60, secondary.getController(), 2, true)
};
}

View file

@ -31,7 +31,7 @@ public class MessagePanelInteract implements IMessage {
private Vec3d hitRelative;
public MessagePanelInteract(TileEntityPanel tile, int id, Vec3d hit) {
pos = tile.getPos();
pos = tile.getBlockPos();
pcId = id;
hitRelative = hit;
}

View file

@ -46,7 +46,10 @@ public final class MiscUtils {
private MiscUtils() {
}
public static List<BlockPos> discoverLocal(World w, BlockPos here, BiPredicate<BlockPos, Integer> isValid) {
public static List<BlockPos> discoverLocal(BlockPos here, BiPredicate<BlockPos, Integer> isValid) {
if (!isValid.test(here, 0)) {
return new ArrayList<>();
}
List<BlockPos> ret = new ArrayList<>();
Queue<BlockPos> open = new ArrayDeque<>();
open.add(here);
@ -322,4 +325,15 @@ public final class MiscUtils {
}
return MultiblockMarx.INSTANCE;
}
public static <T extends TileEntity> T getExistingTE(World w, BlockPos pos, Class<T> clazz) {
if (w.isBlockLoaded(pos)) {
TileEntity te = w.getTileEntity(pos);
if (te!=null && clazz.isAssignableFrom(te.getClass())) {
//noinspection unchecked
return (T) te;
}
}
return null;
}
}