package erogenousbeef.bigreactors.client.gui; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import net.minecraft.client.gui.GuiButton; import net.minecraft.inventory.Container; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import erogenousbeef.bigreactors.common.BigReactors; import erogenousbeef.bigreactors.common.multiblock.block.BlockReactorPart; import erogenousbeef.bigreactors.common.multiblock.tileentity.TileEntityReactorControlRod; import erogenousbeef.bigreactors.common.multiblock.tileentity.TileEntityReactorRedNetPort; import erogenousbeef.bigreactors.common.multiblock.tileentity.TileEntityReactorRedNetPort.CircuitType; import erogenousbeef.bigreactors.gui.IBeefGuiControl; import erogenousbeef.bigreactors.gui.controls.BeefGuiLabel; import erogenousbeef.bigreactors.gui.controls.BeefGuiRedNetChannelSelector; import erogenousbeef.bigreactors.gui.controls.grab.BeefGuiGrabSource; import erogenousbeef.bigreactors.gui.controls.grab.RedNetConfigGrabTarget; import erogenousbeef.bigreactors.gui.controls.grab.RedNetConfigGrabbable; import erogenousbeef.bigreactors.net.CommonPacketHandler; import erogenousbeef.bigreactors.net.helpers.RedNetChange; import erogenousbeef.bigreactors.net.message.ReactorRedNetPortChangeMessage; import erogenousbeef.core.common.CoordTriplet; public class GuiReactorRedNetPort extends BeefGuiBase { protected static final int numChannels = 16; TileEntityReactorRedNetPort port; BeefGuiLabel titleString; BeefGuiLabel settingsString; BeefGuiLabel subSettingString; BeefGuiLabel subSettingValueString; private GuiButton commitBtn; private GuiButton subSettingForwardBtn; private GuiButton subSettingBackBtn; private ResourceLocation _guiBackground; protected static final String[] channelLabelStrings = new String[] { "White", "Orange", "Magenta", "LightBlue", "Yellow", "Lime", "Pink", "Gray", "LightGray", "Cyan", "Purple", "Blue", "Brown", "Green", "Red", "Black" }; public static final String[] grabbableTooltips = { "Input: Toggle reactor on/off", "Input: Change control rod insertion", "Input: Eject Waste", "Output: Fuel Temp (C)", "Output: Casing Temp (C)", "Output: Fuel mix (% fuel, 0-100)", "Output: Fuel amount", "Output: Waste amount", "Output: Energy amount (%)" }; BeefGuiRedNetChannelSelector[] channelSelectors = new BeefGuiRedNetChannelSelector[numChannels]; RedNetConfigGrabTarget[] grabTargets = new RedNetConfigGrabTarget[numChannels]; private CoordTriplet[] subSettingCoords = new CoordTriplet[numChannels]; private boolean[] pulseActivated = new boolean[numChannels]; private int selectedChannel = 0; public GuiReactorRedNetPort(Container container, TileEntityReactorRedNetPort redNetPort) { super(container); port = redNetPort; xSize = 255; ySize = 214; _guiBackground = new ResourceLocation(BigReactors.GUI_DIRECTORY + "RedNetPort.png"); } @Override public ResourceLocation getGuiBackground() { return _guiBackground; } @Override public void initGui() { super.initGui(); int leftX = guiLeft + 4; int topY = guiTop + 4; titleString = new BeefGuiLabel(this, "Reactor RedNet Port", leftX+2, topY+2); settingsString = new BeefGuiLabel(this, "Settings", leftX+154, topY+2); subSettingString = new BeefGuiLabel(this, "", leftX+154, topY+80); subSettingValueString = new BeefGuiLabel(this, "", leftX+154, topY+94); topY += titleString.getHeight() + 8; selectedChannel = 0; for(int i = 0; i < channelLabelStrings.length; i+=2) { channelSelectors[i] = new BeefGuiRedNetChannelSelector(this, channelLabelStrings[i], i, leftX, topY, 60, 20); grabTargets[i] = new RedNetConfigGrabTarget(this, leftX + 42, topY+2, port, i); if(i == 0) { channelSelectors[i].setSelected(true); } leftX += 74; channelSelectors[i + 1] = new BeefGuiRedNetChannelSelector(this, channelLabelStrings[i+1], i+1, leftX, topY, 60, 20); grabTargets[i + 1] = new RedNetConfigGrabTarget(this, leftX + 42, topY+2, port, i + 1); topY += 24; leftX = guiLeft + 4; registerControl(channelSelectors[i]); registerControl(channelSelectors[i+1]); registerControl(grabTargets[i]); registerControl(grabTargets[i+1]); } TileEntityReactorRedNetPort.CircuitType[] circuitTypes = TileEntityReactorRedNetPort.CircuitType.values(); BlockReactorPart reactorPartBlock = (BlockReactorPart)BigReactors.blockReactorPart; RedNetConfigGrabbable[] grabbables = new RedNetConfigGrabbable[circuitTypes.length - 1]; topY = guiTop + 21; leftX = guiLeft + 156; for(int i = 1; i < circuitTypes.length; i++) { grabbables[i-1] = new RedNetConfigGrabbable(grabbableTooltips[i-1], reactorPartBlock.getRedNetConfigIcon(circuitTypes[i]), circuitTypes[i]); BeefGuiGrabSource source = new BeefGuiGrabSource(this, leftX, topY, grabbables[i - 1]); registerControl(source); leftX += 20; if(leftX >= guiLeft + 230) { leftX = guiLeft + 156; topY += 20; } } registerControl(titleString); registerControl(settingsString); registerControl(subSettingString); registerControl(subSettingValueString); commitBtn = new GuiButton(0, guiLeft + 190, guiTop + 190, 56, 20, "Commit"); commitBtn.enabled = false; this.subSettingForwardBtn = new GuiButton(1, guiLeft + 178, guiTop + 114, 20, 20, ">"); this.subSettingBackBtn = new GuiButton(2, guiLeft + 154, guiTop + 114, 20, 20, "<"); this.subSettingForwardBtn.visible = false; this.subSettingBackBtn.visible = false; this.buttonList.add(commitBtn); this.buttonList.add(subSettingForwardBtn); this.buttonList.add(subSettingBackBtn); // Populate all the channels with existing settings TileEntityReactorRedNetPort.CircuitType currentCircuitType; for(int i = 0; i < TileEntityReactorRedNetPort.numChannels; i++) { currentCircuitType = port.getChannelCircuitType(i); pulseActivated[i] = port.isInputActivatedOnPulse(i); if(currentCircuitType == TileEntityReactorRedNetPort.CircuitType.DISABLED) { grabTargets[i].setSlotContents(null); } else { grabTargets[i].setSlotContents( grabbables[currentCircuitType.ordinal() - 1 ]); } } for(int i = 0; i < subSettingCoords.length; i++) { subSettingCoords[i] = port.getMappedCoord(i); } updateSubSettingValueText(); } @Override public void updateScreen() { super.updateScreen(); boolean hasChanges = false; boolean invalidSetting = false; for(RedNetConfigGrabTarget target : grabTargets) { if(target.hasChanged()) { hasChanges = true; } } // See if any subsettings changed for(int i = 0; i < subSettingCoords.length; i++) { if(hasSubSettingChanged(i)) { hasChanges = true; break; } } for(int i = 0; i < numChannels; i++) { if(port.isInputActivatedOnPulse(i) != pulseActivated[i]) { hasChanges = true; break; } } commitBtn.enabled = hasChanges && !invalidSetting; } protected boolean hasSubSettingChanged(int idx) { if(subSettingCoords[idx] == null) { if(port.getMappedCoord(idx) != null) { return true; } } else if(port.getMappedCoord(idx) == null) { return true; } else if(!subSettingCoords[idx].equals(port.getMappedCoord(idx))) { return true; } return false; } protected boolean hasSettingChanged(int idx) { return grabTargets[idx].hasChanged() || hasSubSettingChanged(idx) || (port.isInputActivatedOnPulse(idx) != pulseActivated[idx]); } @Override protected void actionPerformed(GuiButton button) { if(button.id == 0) { RedNetChange[] packetData = getUpdatePacketData(); if(packetData == null) { return; } CommonPacketHandler.INSTANCE.sendToServer(new ReactorRedNetPortChangeMessage(port, packetData)); } if(button.id == 1 || button.id == 2) { changeSubSetting(button.id == 1); } } private RedNetChange[] getUpdatePacketData() { List<RedNetChange> packetData = new LinkedList<RedNetChange>(); for(int i = 0; i < TileEntityReactorRedNetPort.numChannels; i++) { if(hasSettingChanged(i)) { CircuitType circuitType = grabTargets[i].getCircuitType(); RedNetChange change = new RedNetChange(i, circuitType, pulseActivated[i], subSettingCoords[i]); packetData.add(change); } } if(packetData.size() < 1) { return null; } RedNetChange[] changes = new RedNetChange[packetData.size()]; changes = packetData.toArray(changes); return changes; } @Override public void onControlClicked(IBeefGuiControl clickedControl) { if(clickedControl instanceof BeefGuiRedNetChannelSelector) { // Set all selectors to unselected, except the one we clicked // Also change the subsetting selectors, in case those are visible for(IBeefGuiControl control : controls) { if(control instanceof BeefGuiRedNetChannelSelector) { BeefGuiRedNetChannelSelector selector = (BeefGuiRedNetChannelSelector)control; boolean wasSelected = selector.isSelected(); selector.setSelected(control == clickedControl); if(control == clickedControl) { this.selectedChannel = selector.getChannel(); } onChannelChanged(selector.getChannel()); } } } } public void onChannelChanged(int changedChannel) { if(this.selectedChannel != changedChannel) { return; } CircuitType currentCircuitType = grabTargets[selectedChannel].getCircuitType(); if(CircuitType.hasCoordinate(currentCircuitType)) { subSettingString.setLabelText("Control Rod: "); subSettingForwardBtn.visible = true; subSettingBackBtn.visible = true; } else if(TileEntityReactorRedNetPort.isInput(currentCircuitType) && CircuitType.canBeToggledBetweenPulseAndNormal(currentCircuitType)) { subSettingString.setLabelText("Activates On:"); subSettingForwardBtn.visible = true; subSettingBackBtn.visible = true; } else if(currentCircuitType == CircuitType.inputEjectWaste) { subSettingString.setLabelText("Activates On:"); subSettingForwardBtn.visible = false; subSettingBackBtn.visible = false; } else { subSettingString.setLabelText(""); subSettingForwardBtn.visible = false; subSettingBackBtn.visible = false; } updateSubSettingValueText(); } private String getControlRodLabelFromLocation(CircuitType circuitType, CoordTriplet location) { if(location == null) { return "-- ALL --"; } else { TileEntity te = port.getWorldObj().getTileEntity(location.x, location.y, location.z); if( te instanceof TileEntityReactorControlRod ) { TileEntityReactorControlRod rod = (TileEntityReactorControlRod)te; if( rod.getName().equals("")) { return location.toString(); } else { return rod.getName(); } } else { return "INVALID: " + location.toString(); } } } private void changeSubSetting(boolean forward) { CircuitType circuitType = grabTargets[selectedChannel].getCircuitType(); if( CircuitType.hasCoordinate(circuitType) ) { // Select a new control rod CoordTriplet[] controlRodLocations = port.getReactorController().getControlRodLocations(); int newIdx = 0; // Locate current idx; will be -1 if not found, which is expected. int oldIdx = Arrays.asList(controlRodLocations).indexOf( subSettingCoords[selectedChannel] ); if(forward) { newIdx = oldIdx + 1; } else { if(oldIdx == -1) { newIdx = controlRodLocations.length - 1; } else { newIdx = oldIdx - 1; } } if(newIdx < 0 || newIdx >= controlRodLocations.length) { subSettingCoords[selectedChannel] = null; } else { subSettingCoords[selectedChannel] = controlRodLocations[newIdx]; } } else if( CircuitType.canBeToggledBetweenPulseAndNormal(circuitType) ) { pulseActivated[selectedChannel] = !pulseActivated[selectedChannel]; } updateSubSettingValueText(); } private void updateSubSettingValueText() { subSettingValueString.setLabelTooltip(""); CircuitType circuitType = grabTargets[selectedChannel].getCircuitType(); if( CircuitType.hasCoordinate(circuitType) ) { subSettingValueString.setLabelText( getControlRodLabelFromLocation(circuitType, subSettingCoords[selectedChannel]) ); } else if(TileEntityReactorRedNetPort.isInput(circuitType) && CircuitType.canBeToggledBetweenPulseAndNormal(circuitType)) { subSettingValueString.setLabelText(pulseActivated[selectedChannel]?"Pulse":"Level"); } else if(circuitType == CircuitType.inputEjectWaste) { subSettingValueString.setLabelText("Pulse"); } else { subSettingValueString.setLabelText(""); } } }