diff --git a/src/main/java/malte0811/industrialwires/client/ClientProxy.java b/src/main/java/malte0811/industrialwires/client/ClientProxy.java index 24fcf73..822e4f9 100644 --- a/src/main/java/malte0811/industrialwires/client/ClientProxy.java +++ b/src/main/java/malte0811/industrialwires/client/ClientProxy.java @@ -227,7 +227,8 @@ public class ClientProxy extends CommonProxy { new ManualPages.CraftingMulti(m, "industrialwires.lock", new ItemStack(IndustrialWires.panelComponent, 1, 7), new ItemStack(IndustrialWires.key)), new ManualPages.Crafting(m, "industrialwires.lock1", new ItemStack(IndustrialWires.key, 1, 2)), new ManualPages.Crafting(m, "industrialwires.panel_meter", new ItemStack(IndustrialWires.panelComponent, 1, 8)), - new ManualPages.Crafting(m, "industrialwires.7seg", new ItemStack(IndustrialWires.panelComponent, 1, 9)) + new ManualPages.Crafting(m, "industrialwires.7seg", new ItemStack(IndustrialWires.panelComponent, 1, 9)), + new ManualPages.Crafting(m, "industrialwires.rgb_led", new ItemStack(IndustrialWires.panelComponent, 1, 10)) ); List ores = MarxOreHandler.getRecipes(); text = I18n.format("ie.manual.entry.industrialwires.marx"); diff --git a/src/main/java/malte0811/industrialwires/controlpanel/PanelComponent.java b/src/main/java/malte0811/industrialwires/controlpanel/PanelComponent.java index 6f17210..afea1ca 100644 --- a/src/main/java/malte0811/industrialwires/controlpanel/PanelComponent.java +++ b/src/main/java/malte0811/industrialwires/controlpanel/PanelComponent.java @@ -66,6 +66,7 @@ public abstract class PanelComponent implements IOwner { baseCreaters.put("lock", Lock::new); baseCreaters.put("panel_meter", PanelMeter::new); baseCreaters.put(SevenSegDisplay.NAME, SevenSegDisplay::new); + baseCreaters.put("rgb_led", RGBIndicator::new); //Check that all components implement equals+hashCode if in a dev env boolean isDevEnv = "NBTTagCompound".equals(NBTTagCompound.class.getSimpleName()); if (isDevEnv) { diff --git a/src/main/java/malte0811/industrialwires/controlpanel/PropertyComponents.java b/src/main/java/malte0811/industrialwires/controlpanel/PropertyComponents.java index 7765e55..6836dd4 100644 --- a/src/main/java/malte0811/industrialwires/controlpanel/PropertyComponents.java +++ b/src/main/java/malte0811/industrialwires/controlpanel/PropertyComponents.java @@ -179,6 +179,7 @@ public class PropertyComponents implements IUnlistedProperty. + */ + +package malte0811.industrialwires.controlpanel; + +import malte0811.industrialwires.IndustrialWires; +import malte0811.industrialwires.client.RawQuad; +import malte0811.industrialwires.client.gui.GuiPanelCreator; +import malte0811.industrialwires.controlpanel.ControlPanelNetwork.RSChannel; +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.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.lwjgl.util.vector.Vector3f; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static malte0811.industrialwires.util.NBTKeys.RS_CHANNEL; +import static malte0811.industrialwires.util.NBTKeys.RS_ID; + +public class RGBIndicator extends PanelComponent implements IConfigurableComponent { + @Nonnull + private RSChannel[] input = {RSChannel.DEFAULT_CHANNEL, RSChannel.DEFAULT_CHANNEL, RSChannel.DEFAULT_CHANNEL}; + private int rgbState; + + public RGBIndicator() { + super("rgb_led"); + } + + public RGBIndicator(@Nonnull RSChannel[] input) { + this(); + this.input = input; + } + + @Override + protected void writeCustomNBT(NBTTagCompound nbt, boolean toItem) { + NBTTagList channels = new NBTTagList(); + for (RSChannel c : input) { + NBTTagCompound ch = new NBTTagCompound(); + ch.setInteger(RS_ID, c.getController()); + ch.setByte(RS_CHANNEL, c.getColor()); + channels.appendTag(ch); + } + nbt.setTag("channels", channels); + if (!toItem) { + nbt.setInteger("rgb", rgbState); + } + } + + @Override + protected void readCustomNBT(NBTTagCompound nbt) { + NBTTagList channels = nbt.getTagList("channels", Constants.NBT.TAG_COMPOUND); + if (channels.tagCount() == 3) { + RSChannel[] in = new RSChannel[channels.tagCount()]; + for (int i = 0; i < in.length; i++) { + NBTTagCompound ch = channels.getCompoundTagAt(i); + int rsController = ch.getInteger(RS_ID); + byte rsColor = ch.getByte(RS_CHANNEL); + in[i] = new RSChannel(rsController, rsColor); + } + input = in; + } + rgbState = nbt.getInteger("rgb"); + } + + private static final float size = .0625F; + + @Override + @SideOnly(Side.CLIENT) + public List getQuads() { + float[] color = new float[4]; + color[3] = 1; + for (int i = 0; i < 3; i++) { + color[i] = ((rgbState >> (i * 8)) & 255) / 255F; + } + List ret = new ArrayList<>(1); + PanelUtils.addColoredQuad(ret, new Vector3f(), new Vector3f(0, 0, size), new Vector3f(size, 0, size), new Vector3f(size, 0, 0), EnumFacing.UP, color); + if (rgbState > 0) { + ret.get(ret.size() - 1).light = 0xff0ff; + } + return ret; + } + + @Nonnull + @Override + public PanelComponent copyOf() { + RGBIndicator ret = new RGBIndicator(Arrays.copyOf(input, input.length)); + ret.rgbState = rgbState; + ret.setX(x); + ret.setY(y); + ret.panelHeight = panelHeight; + return ret; + } + + @Nonnull + @Override + public AxisAlignedBB getBlockRelativeAABB() { + if (aabb == null) { + aabb = new AxisAlignedBB(x, 0, y, x + size, 0, y + size); + } + return aabb; + } + + @Override + public void interactWith(Vec3d hitRelative, EntityPlayerMP player) { + } + + @Override + public void update() { + + } + + + @Override + public void setNetwork(ControlPanelNetwork net) { + super.setNetwork(net); + for (int i = 0; i < input.length; i++) { + int finalI = i; + net.addListener(this, (state) -> { + byte currState = (byte) ((rgbState >> (8 * finalI + 4)) & 15); + if (state.getStrength() != currState) { + rgbState &= ~(255 << (8 * finalI)); + rgbState |= state.getStrength() << (8 * finalI + 4); + panel.markDirty(); + panel.triggerRenderUpdate(); + } + }, input[i]); + } + } + + @Override + public float getHeight() { + return 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + RGBIndicator that = (RGBIndicator) o; + + return rgbState == that.rgbState; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + rgbState; + return result; + } + + @Override + @SideOnly(Side.CLIENT) + public void renderInGUI(GuiPanelCreator gui) { + 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); + int width = right - left; + int height = bottom - top; + for (int colorId = 0; colorId < 3; ++colorId) { + int color = (0xff << (colorId * 8)) | 0xff000000; + for (int row = 0; row < 3; ++row) { + int col = (row * (row + 1) + colorId) % 3; + Gui.drawRect(Math.round(left + width * col / 3.0F), + Math.round(top + height * row / 3.0F), + Math.round(left + width * (col + 1) / 3.0F), + Math.round(top + height * (row + 1) / 3.0F), + color); + } + } + } + + @Override + public void applyConfigOption(ConfigType type, int id, NBTBase value) { + switch (type) { + case RS_CHANNEL: + input[id] = input[id].withColor(value); + break; + case INT: + input[id] = input[id].withController(value); + break; + } + } + + @Nullable + @Override + @SideOnly(Side.CLIENT) + public String fomatConfigName(ConfigType type, int id) { + switch (type) { + case FLOAT: + return I18n.format(IndustrialWires.MODID + ".desc." + (id == 0 ? "red" : (id == 1 ? "green" : "blue"))); + case RS_CHANNEL: + case INT: + default: + return null; + } + } + + @Nullable + @Override + @SideOnly(Side.CLIENT) + public String fomatConfigDescription(ConfigType type, int id) { + String color = null; + switch (id) { + case 0: + color = "red"; + break; + case 1: + color = "green"; + break; + case 2: + color = "blue"; + break; + } + switch (type) { + case FLOAT: + return null; + case RS_CHANNEL: + return I18n.format(IndustrialWires.MODID + ".desc.rschannel_" + color); + case INT: + return I18n.format(IndustrialWires.MODID + ".desc.rsid_" + color); + default: + return null; + } + } + + @Override + public RSColorConfig[] getRSChannelOptions() { + return new RSColorConfig[]{ + new RSColorConfig("channelR", 0, 10, input[0].getColor()), + new RSColorConfig("channelG", 50, 10, input[1].getColor()), + new RSColorConfig("channelB", 0, 70, input[2].getColor()) + }; + } + + @Override + public IntConfig[] getIntegerOptions() { + return new IntConfig[]{ + new IntConfig("rsIdR", 0, 0, input[0].getController(), 2, false), + new IntConfig("rsIdG", 50, 0, input[1].getController(), 2, false), + new IntConfig("rsIdB", 0, 60, input[2].getController(), 2, false) + }; + } + + @Override + public int getColor() { + return 0xffffff; + } +} \ No newline at end of file diff --git a/src/main/java/malte0811/industrialwires/controlpanel/Variac.java b/src/main/java/malte0811/industrialwires/controlpanel/Variac.java index 7a84c45..af7eaf4 100644 --- a/src/main/java/malte0811/industrialwires/controlpanel/Variac.java +++ b/src/main/java/malte0811/industrialwires/controlpanel/Variac.java @@ -193,13 +193,13 @@ public class Variac extends PanelComponent implements IConfigurableComponent { int bottom = (int) Math.floor(gui.getY0() + (aabb.maxZ - offset) * gui.panelSize); GlStateManager.pushMatrix(); - GlStateManager.translate((left + right) / 2, (top + bottom) / 2, 0); + GlStateManager.translate((left + right) / 2F, (top + bottom) / 2F, 0); GlStateManager.rotate(360 / 17F, 0, 0, 1); - GlStateManager.translate(-(left + right) / 2, -(top + bottom) / 2, 0); + GlStateManager.translate(-(left + right) / 2F, -(top + bottom) / 2F, 0); Gui.drawRect(left, top, right, bottom, 0xff333333); - GlStateManager.translate((left + right) / 2, (top + bottom) / 2, 0); + GlStateManager.translate((left + right) / 2F, (top + bottom) / 2F, 0); GlStateManager.rotate(45, 0, 0, 1); - GlStateManager.translate(-(left + right) / 2, -(top + bottom) / 2, 0); + GlStateManager.translate(-(left + right) / 2F, -(top + bottom) / 2F, 0); Gui.drawRect(left, top, right, bottom, 0xff333333); GlStateManager.popMatrix(); } diff --git a/src/main/java/malte0811/industrialwires/items/ItemPanelComponent.java b/src/main/java/malte0811/industrialwires/items/ItemPanelComponent.java index 880be06..2db17c7 100644 --- a/src/main/java/malte0811/industrialwires/items/ItemPanelComponent.java +++ b/src/main/java/malte0811/industrialwires/items/ItemPanelComponent.java @@ -53,7 +53,7 @@ import static malte0811.industrialwires.util.NBTKeys.*; public class ItemPanelComponent extends Item implements INetGUIItem { public static final String[] types = { "lighted_button", "label", "indicator_light", "slider", "variac", "toggle_switch", "toggle_switch_covered", - "lock", "panel_meter", SevenSegDisplay.NAME + "lock", "panel_meter", SevenSegDisplay.NAME, "rgb_led" }; public static final String NAME = "panel_component"; diff --git a/src/main/resources/assets/industrialwires/lang/en_US.lang b/src/main/resources/assets/industrialwires/lang/en_US.lang index 89472cf..2cf83ab 100644 --- a/src/main/resources/assets/industrialwires/lang/en_US.lang +++ b/src/main/resources/assets/industrialwires/lang/en_US.lang @@ -45,6 +45,7 @@ item.industrialwires.panel_component.toggle_switch_covered.name=Covered Toggle S item.industrialwires.panel_component.lock.name=Lock Switch item.industrialwires.panel_component.panel_meter.name=Panel Meter item.industrialwires.panel_component.7seg.name=7-Segment Display +item.industrialwires.panel_component.rgb_led.name=RGB Indicator item.industrialwires.key.key.name=Key item.industrialwires.key.key_named.name=Key for item.industrialwires.key.blank_key.name=Blank Key @@ -82,6 +83,12 @@ industrialwires.desc.rsid_info=The ID of the redstone wire controller to interac industrialwires.desc.rschannel_info=The color of the channel to use industrialwires.desc.rsid_info2=The ID of the redstone wire controller for the second signal. -1 to disable. industrialwires.desc.rschannel_info2=The color of the channel to use for the second signal +industrialwires.desc.rschannel_red=The color of the channel to use for the red signal +industrialwires.desc.rschannel_green=The color of the channel to use for the green signal +industrialwires.desc.rschannel_blue=The color of the channel to use for the blue signal +industrialwires.desc.rsid_red=The ID of the redstone wire controller for the red signal +industrialwires.desc.rsid_green=The ID of the redstone wire controller for the green signal +industrialwires.desc.rsid_blue=The ID of the redstone wire controller for the blue signal industrialwires.desc.label_text=The text in this label industrialwires.desc.red=Red industrialwires.desc.green=Green @@ -192,4 +199,5 @@ ie.manual.entry.industrialwires.variac=A VariacĀ® is a variable autotransformer. ie.manual.entry.industrialwires.lock=A lock switch activates a redstone signal when a key is inserted and turned. A newly crafted lock will have a unique key configuration. By placing a blank key and a lock in a crafting table a key for the lock can be created. Multiple locks fitting the same key can be created using component copying (see page 1). Keys can be named in a GUI opened by right-clicking with them. ie.manual.entry.industrialwires.lock1=Up to can be combined on a key ring. Keys are added to the ring by placing both in a crafting table. Shift-right-click the key ring to cycle through the keys on the ring. The selected key can be removed from the ring by placing the ring in a crafting table. The key ring will work just as the selected key would on lock switches. ie.manual.entry.industrialwires.panel_meter=A panel meter can be used to show display analog redstone signals with some accuracy. Panel meters are available in two different formats, wide and narrow. The difference between the formats is purely visual. -ie.manual.entry.industrialwires.7seg=Seven-Segment Displays are a way of displaying analog redstone signals precisely. Signal strengths 0-9 are displayed as one would expect, levels 10-15 are represented by the letters A-E. Some of the letters are lower-case to differentiate them from digits (e.g. 8 vs B). \ No newline at end of file +ie.manual.entry.industrialwires.7seg=Seven-Segment Displays are a way of displaying analog redstone signals precisely. Signal strengths 0-9 are displayed as one would expect, levels 10-15 are represented by the letters A-E. Some of the letters are lower-case to differentiate them from digits (e.g. 8 vs B). +ie.manual.entry.industrialwires.rgb_led=RGB Indicators consist of 3 indicator lights placed close together: one is red, one green and one blue. They can be controlled independently, allowing for many different colors to be shown without having to disassemble and recreate the panel. \ No newline at end of file diff --git a/src/main/resources/assets/industrialwires/recipes/panel_component_rgb_led.json b/src/main/resources/assets/industrialwires/recipes/panel_component_rgb_led.json new file mode 100644 index 0000000..df0c633 --- /dev/null +++ b/src/main/resources/assets/industrialwires/recipes/panel_component_rgb_led.json @@ -0,0 +1,25 @@ +{ + "result": { + "item": "industrialwires:panel_component", + "data": 10 + }, + "ingredients": [ + { + "type": "forge:ore_dict", + "ore": "dustRedstone" + }, + { + "item": "industrialwires:panel_component", + "data": 2 + }, + { + "item": "industrialwires:panel_component", + "data": 2 + }, + { + "item": "industrialwires:panel_component", + "data": 2 + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file