started adding control panels. Very much WIP!

This commit is contained in:
malte0811 2017-03-24 17:40:05 +01:00
parent 4a4360c98b
commit 34bf534b1c
16 changed files with 1138 additions and 8 deletions

View file

@ -30,6 +30,8 @@ import blusunrize.immersiveengineering.common.blocks.stone.BlockTypes_StoneDecor
import ic2.api.item.IC2Items;
import malte0811.industrialWires.blocks.BlockJacobsLadder;
import malte0811.industrialWires.blocks.TileEntityJacobsLadder;
import malte0811.industrialWires.blocks.controlpanel.BlockPanel;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.blocks.converter.BlockMechanicalConverter;
import malte0811.industrialWires.blocks.converter.TileEntityIEMotor;
import malte0811.industrialWires.blocks.converter.TileEntityMechICtoIE;
@ -69,6 +71,7 @@ public class IndustrialWires {
public static BlockIC2Connector ic2conn;
public static BlockMechanicalConverter mechConv;
public static BlockJacobsLadder jacobsLadder;
public static BlockPanel panel;
public static ItemIC2Coil coil;
public static final SimpleNetworkWrapper packetHandler = NetworkRegistry.INSTANCE.newSimpleChannel(MODID);
public static CreativeTabs creativeTab = new CreativeTabs(MODID) {
@ -92,6 +95,7 @@ public class IndustrialWires {
mechConv = new BlockMechanicalConverter();
jacobsLadder = new BlockJacobsLadder();
coil = new ItemIC2Coil();
panel = new BlockPanel();
//TODO change to MODID+ when changing to a new MC version
GameRegistry.registerTileEntity(TileEntityIC2ConnectorTin.class, "ic2ConnectorTin");
GameRegistry.registerTileEntity(TileEntityIC2ConnectorCopper.class, "ic2ConnectorCopper");
@ -99,6 +103,7 @@ public class IndustrialWires {
GameRegistry.registerTileEntity(TileEntityIC2ConnectorHV.class, "ic2ConnectorHV");
GameRegistry.registerTileEntity(TileEntityIC2ConnectorGlass.class, "ic2ConnectorGlass");
GameRegistry.registerTileEntity(TileEntityJacobsLadder.class, MODID+":jacobsLadder");
GameRegistry.registerTileEntity(TileEntityPanel.class, MODID+":control_panels");
if (mechConv!=null) {
GameRegistry.registerTileEntity(TileEntityIEMotor.class, MODID+":ieMotor");
GameRegistry.registerTileEntity(TileEntityMechICtoIE.class, MODID+":mechIcToIe");

View file

@ -57,7 +57,6 @@ public abstract class BlockIWBase extends Block {
setCreativeTab(IndustrialWires.creativeTab);
}
@Override
protected BlockStateContainer createBlockState() {
if (properties==null) {
@ -79,7 +78,11 @@ public abstract class BlockIWBase extends Block {
state = applyProperty(state, IEProperties.MULTIBLOCKSLAVE, ((IHasDummyBlocksIW) tile).isDummy());
}
if (tile instanceof IEBlockInterfaces.IDirectionalTile) {
state = state.withProperty(IEProperties.FACING_ALL, ((IEBlockInterfaces.IDirectionalTile) tile).getFacing());
if (((IEBlockInterfaces.IDirectionalTile) tile).getFacingLimitation()==2) {
state = state.withProperty(IEProperties.FACING_HORIZONTAL, ((IEBlockInterfaces.IDirectionalTile) tile).getFacing());
} else {
state = state.withProperty(IEProperties.FACING_ALL, ((IEBlockInterfaces.IDirectionalTile) tile).getFacing());
}
}
return state;
}
@ -103,7 +106,8 @@ public abstract class BlockIWBase extends Block {
super.onBlockPlacedBy(worldIn, pos, state, placer, stack);
TileEntity te = worldIn.getTileEntity(pos);
if (te instanceof IEBlockInterfaces.IDirectionalTile) {
((IEBlockInterfaces.IDirectionalTile)te).setFacing(state.getValue(IEProperties.FACING_ALL));
((IEBlockInterfaces.IDirectionalTile)te).setFacing(
state.getValue(((IEBlockInterfaces.IDirectionalTile) te).getFacingLimitation()==2?IEProperties.FACING_HORIZONTAL:IEProperties.FACING_ALL));
}
if (te instanceof IHasDummyBlocksIW) {
((IHasDummyBlocksIW) te).placeDummies(state);
@ -164,7 +168,9 @@ public abstract class BlockIWBase extends Block {
return true;
}
} else if (te instanceof IEBlockInterfaces.IPlayerInteraction) {
((IEBlockInterfaces.IPlayerInteraction) te).interact(side, player, hand, heldItem, hitX, hitY, hitZ);
if (((IEBlockInterfaces.IPlayerInteraction) te).interact(side, player, hand, heldItem, hitX, hitY, hitZ)) {
return true;
}
}
return false;
}

View file

@ -29,17 +29,24 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class ItemBlockIW extends ItemBlock {
Object[] values;
private final Object[] values;
public ItemBlockIW(Block b) {
super(b);
assert b instanceof IMetaEnum;
values = ((IMetaEnum)b).getValues();
if (b instanceof IMetaEnum) {
values = ((IMetaEnum)b).getValues();
} else {
values = null;
}
hasSubtypes = true;
}
@Override
public String getUnlocalizedName(ItemStack stack) {
int meta = stack.getMetadata();
return block.getUnlocalizedName()+"."+values[meta].toString().toLowerCase();
if (values!=null) {
return block.getUnlocalizedName() + "." + values[meta].toString().toLowerCase();
} else {
return block.getUnlocalizedName();
}
}
@Override
public int getMetadata(int damage) {

View file

@ -0,0 +1,86 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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 blusunrize.immersiveengineering.api.IEProperties;
import malte0811.industrialWires.blocks.BlockIWBase;
import malte0811.industrialWires.blocks.IPlacementCheck;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
public class BlockPanel extends BlockIWBase implements IPlacementCheck {
public BlockPanel() {
super(Material.IRON, "control_panel");
}
@Override
public boolean canPlaceBlockAt(World w, BlockPos pos, ItemStack stack) {
return true;//TODO actually check for space
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileEntityPanel();
}
@Override
public boolean hasTileEntity(IBlockState state) {
return true;
}
@Override
protected IProperty[] getProperties() {
return new IProperty[]{IEProperties.FACING_HORIZONTAL};
}
@Override
protected BlockStateContainer createBlockState() {
BlockStateContainer base = super.createBlockState();
return new ExtendedBlockState(this, base.getProperties().toArray(new IProperty[0]), new IUnlistedProperty[]{
PropertyComponents.INSTANCE
});
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
state = super.getExtendedState(state, world, pos);
if (state instanceof IExtendedBlockState) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof TileEntityPanel) {
state = ((IExtendedBlockState) state).withProperty(PropertyComponents.INSTANCE, ((TileEntityPanel) te).components);
}
}
return state;
}
@Override
public int getMetaFromState(IBlockState state) {
return 0;
}
}

View file

@ -0,0 +1,139 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.client.RawQuad;
import malte0811.industrialWires.client.panelmodel.PanelUtils;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
public class LightedButton extends PanelComponent {
public int color;
public boolean active;
public boolean latching;
private AxisAlignedBB aabb;
private int ticksTillOff;
public LightedButton() {
super("lightedButton");
}
public LightedButton(int color, boolean active, boolean latching) {
this();
this.color = color;
this.active = active;
this.latching = latching;
}
@Override
protected void writeCustomNBT(NBTTagCompound nbt) {
nbt.setInteger("color", color);
nbt.setInteger("timeout", ticksTillOff);
nbt.setBoolean("active", active);
nbt.setBoolean("latching", latching);
}
@Override
protected void readCustomNBT(NBTTagCompound nbt) {
color = nbt.getInteger("color");
ticksTillOff = nbt.getInteger("timeout");
active = nbt.getBoolean("active");
latching = nbt.getBoolean("latching");
}
private final static float[] sideColor = {.8F, .8F, .8F};
private final static float size = .0625F;
@Override
public List<RawQuad> getQuads() {
float[] color = new float[4];
color[3] = 1;
for (int i = 0;i<3;i++) {
color[i] = ((this.color>>(8*(2-i)))&255)/255F*(active?1:.5F);
}
List<RawQuad> ret = new ArrayList<>(5);
PanelUtils.addColoredBox(color, sideColor, null, new Vector3f(0, 0, 0), new Vector3f(size, size/2, size), ret, false);
return ret;
}
@Override
@Nonnull
public PanelComponent copyOf() {
LightedButton ret = new LightedButton(color, active, latching);
ret.setX(x);
ret.setY(y);
return ret;
}
@Override
public AxisAlignedBB getBlockRelativeAABB() {
if (aabb==null) {
aabb = new AxisAlignedBB(x, panelHeight, y, x+size, panelHeight+size/2, y+size);
}
return aabb;
}
@Override
public boolean interactWith(Vec3d hitRel, TileEntityPanel tile) {
if (!latching&&active) {
return false;
}
active = !active;
if (!latching) {
ticksTillOff = 10;
}
tile.markDirty();
tile.triggerRenderUpdate();
return true;
}
@Override
public void update(TileEntityPanel tile) {
if (!latching&&ticksTillOff>0) {
ticksTillOff--;
tile.markDirty();
if (ticksTillOff==0) {
active = false;
tile.triggerRenderUpdate();
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LightedButton that = (LightedButton) o;
if (color != that.color) return false;
if (active != that.active) return false;
return latching == that.latching;
}
@Override
public int hashCode() {
int result = color;
result = 31 * result + (active ? 1 : 0);
result = 31 * result + (latching ? 1 : 0);
return result;
}
}

View file

@ -0,0 +1,116 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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 blusunrize.immersiveengineering.common.util.IELogger;
import malte0811.industrialWires.client.RawQuad;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public abstract class PanelComponent {
protected float panelHeight;
protected float x, y;
private final String type;
protected PanelComponent(String type) {
this.type = type;
}
private static final Map<String, Supplier<PanelComponent>> baseCreaters = new HashMap<>();
static {
baseCreaters.put("lightedButton", LightedButton::new);
}
protected abstract void writeCustomNBT(NBTTagCompound nbt);
protected abstract void readCustomNBT(NBTTagCompound nbt);
// DON'T OFFSET BY x, y IN THIS METHOD!
public abstract List<RawQuad> getQuads();
@Nonnull
public abstract PanelComponent copyOf();
public abstract AxisAlignedBB getBlockRelativeAABB();
public abstract boolean interactWith(Vec3d hitRelative, TileEntityPanel tile);
public abstract void update(TileEntityPanel tile);
public float getX() {
return x;
}
public float getY() {
return y;
}
public void setX(float x) {
this.x = x;
}
public void setY(float y) {
this.y = y;
}
public void setPanelHeight(float panelHeight) {
this.panelHeight = panelHeight;
}
public void writeToNBT(NBTTagCompound nbt) {
writeCustomNBT(nbt);
nbt.setFloat("x", getX());
nbt.setFloat("y", getY());
nbt.setFloat("panelHeight", panelHeight);
nbt.setString("type", type);
}
public static PanelComponent read(NBTTagCompound nbt) {
String type = nbt.getString("type");
if (baseCreaters.containsKey(type)) {
PanelComponent ret = baseCreaters.get(type).get();
ret.readCustomNBT(nbt);
ret.setX(nbt.getFloat("x"));
ret.setY(nbt.getFloat("y"));
ret.setPanelHeight(nbt.getFloat("panelHeight"));
return ret;
} else {
IELogger.info("(IndustrialWires) Unknown panel component: "+type);
return null;
}
}
public void renderBox(TileEntityPanel te) {
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);
double px = te.getPos().getX()-TileEntityRendererDispatcher.staticPlayerX;
double py = te.getPos().getY()-TileEntityRendererDispatcher.staticPlayerY;
double pz = te.getPos().getZ()-TileEntityRendererDispatcher.staticPlayerZ;
RenderGlobal.func_189697_a(getBlockRelativeAABB().expandXyz(0.002).offset(px, py, pz), 0.0F, 0.0F, 0.0F, 0.4F);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
}
}

View file

@ -0,0 +1,71 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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 net.minecraftforge.common.property.IUnlistedProperty;
import java.util.ArrayList;
public class PropertyComponents implements IUnlistedProperty<PropertyComponents.ComponentList> {
public static PropertyComponents INSTANCE = new PropertyComponents();
@Override
public String getName() {
return "components";
}
@Override
public boolean isValid(ComponentList value) {
return value!=null;
}
@Override
public Class<ComponentList> getType() {
return ComponentList.class;
}
@Override
public String valueToString(ComponentList value) {
return value.toString();
}
public static class ComponentList extends ArrayList<PanelComponent> {
public ComponentList() {
super();
}
public ComponentList(int length) {
super(length);
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder("[");
for (int i = 0;i<size();i++) {
ret.append(get(i));
if (i<size()-1) {
ret.append(", ");
}
}
return ret+"]";
}
public ComponentList copyOf() {
ComponentList ret = new ComponentList(size());
ret.addAll(this);
return ret;
}
}
}

View file

@ -0,0 +1,168 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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 blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IDirectionalTile;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IPlayerInteraction;
import blusunrize.immersiveengineering.common.util.IELogger;
import malte0811.industrialWires.blocks.IBlockBoundsIW;
import malte0811.industrialWires.blocks.TileEntityIWBase;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import javax.annotation.Nullable;
import java.util.Random;
public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTile, IBlockBoundsIW, IPlayerInteraction, ITickable {
PropertyComponents.ComponentList components = new PropertyComponents.ComponentList();
EnumFacing facing = EnumFacing.NORTH;
public float height = .5F;
{
Random r = new Random();
LightedButton b = new LightedButton(0xff<<(8*r.nextInt(3)), false, false);
IELogger.info(Integer.toHexString(b.color));
b.setX(3/16F);
b.setY(.5F);
b.setPanelHeight(height);
components.add(b);
b = new LightedButton(0xff<<(8*r.nextInt(3)), false, true);
IELogger.info(Integer.toHexString(b.color));
b.setX(8/16F);
b.setY(.5F);
b.setPanelHeight(height);
components.add(b);
b = new LightedButton(0xff<<(8*r.nextInt(3)), false, true);
IELogger.info(Integer.toHexString(b.color));
b.setX(13/16F);
b.setY(.5F);
b.setPanelHeight(height);
components.add(b);
}
@Override
public void update() {
for (PanelComponent pc:components) {
pc.update(this);
}
}
@Override
public void writeNBT(NBTTagCompound out, boolean updatePacket) {
NBTTagList comps = new NBTTagList();
for (PanelComponent p:components) {
NBTTagCompound nbt = new NBTTagCompound();
p.writeToNBT(nbt);
comps.appendTag(nbt);
}
out.setTag("components", comps);
out.setInteger("facing", facing.getHorizontalIndex());
}
@Override
public void readNBT(NBTTagCompound in, boolean updatePacket) {
NBTTagList l = in.getTagList("components", 10);
components.clear();
for (int i = 0;i<l.tagCount();i++) {
PanelComponent pc = PanelComponent.read(l.getCompoundTagAt(i));
if (pc!=null) {
components.add(pc);
}
}
facing = EnumFacing.getHorizontal(in.getInteger("facing"));
}
@Override
public EnumFacing getFacing() {
return facing;
}
@Override
public void setFacing(EnumFacing facing) {
this.facing = facing;
}
@Override
public int getFacingLimitation() {
return 2;
}
@Override
public boolean mirrorFacingOnPlacement(EntityLivingBase placer) {
return false;
}
@Override
public boolean canHammerRotate(EnumFacing side, float hitX, float hitY, float hitZ, EntityLivingBase entity) {
return false;
}
@Override
public boolean canRotate(EnumFacing axis) {
return false;
}
private static final AxisAlignedBB defAABB = new AxisAlignedBB(0, 0, 0, 1, .5, 1);
@Override
public AxisAlignedBB getBoundingBox() {
return defAABB;
}
public PropertyComponents.ComponentList getComponents() {
return components;
}
@Nullable
public PanelComponent getSelectedComponent(EntityPlayer player, Vec3d hit, boolean hitAbs) {
for (PanelComponent pc : components) {
AxisAlignedBB box = pc.getBlockRelativeAABB().expandXyz(.002);
Vec3d hitVec = hitAbs?hit.addVector(-pos.getX(), -pos.getY(), -pos.getZ()):hit;
Vec3d playerPos = Minecraft.getMinecraft().thePlayer.getPositionVector().addVector(-pos.getX(), player.getEyeHeight()-pos.getY(), -pos.getZ());
if (box.calculateIntercept(playerPos, hitVec)!=null) {
return pc;
}
}
return null;
}
@Override
public boolean interact(EnumFacing side, EntityPlayer player, EnumHand hand, ItemStack heldItem, float hitX, float hitY, float hitZ) {
PanelComponent pc = getSelectedComponent(player, new Vec3d(hitX, hitY, hitZ), false);
if (pc!=null) {
Vec3d hitRel = new Vec3d(hitX-pc.getX(), hitY-height, hitZ-pc.getY());
return pc.interactWith(hitRel, this);
}
return false;
}
public void triggerRenderUpdate() {
IBlockState state = worldObj.getBlockState(pos);
worldObj.notifyBlockUpdate(pos,state,state,3);
worldObj.addBlockEvent(pos, state.getBlock(), 255, 0);
}
}

View file

@ -21,14 +21,19 @@ import blusunrize.immersiveengineering.api.Lib;
import blusunrize.immersiveengineering.client.ClientUtils;
import blusunrize.immersiveengineering.common.util.ItemNBTHelper;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.controlpanel.PanelComponent;
import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel;
import malte0811.industrialWires.items.ItemIC2Coil;
import malte0811.industrialWires.wires.IC2Wiretype;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.client.GuiIngameForge;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.oredict.OreDictionary;
@ -70,4 +75,19 @@ public class ClientEventHandler {
}
}
}
@SubscribeEvent
public void renderBoundingBoxes(DrawBlockHighlightEvent event) {
if (!event.isCanceled() && event.getSubID() == 0 && event.getTarget().typeOfHit == RayTraceResult.Type.BLOCK) {
TileEntity tile = event.getPlayer().worldObj.getTileEntity(event.getTarget().getBlockPos());
if (tile instanceof TileEntityPanel) {
TileEntityPanel panel = (TileEntityPanel) tile;
PanelComponent pc = panel.getSelectedComponent(Minecraft.getMinecraft().thePlayer, event.getTarget().hitVec, true);
if (pc != null) {
pc.renderBox(panel);
event.setCanceled(true);
}
}
}
}
}

View file

@ -31,6 +31,7 @@ import malte0811.industrialWires.IWConfig;
import malte0811.industrialWires.IndustrialWires;
import malte0811.industrialWires.blocks.IMetaEnum;
import malte0811.industrialWires.blocks.TileEntityJacobsLadder;
import malte0811.industrialWires.client.panelmodel.PanelModelLoader;
import malte0811.industrialWires.client.render.TileRenderJacobsLadder;
import malte0811.industrialWires.items.ItemIC2Coil;
import net.minecraft.block.Block;
@ -47,6 +48,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.obj.OBJLoader;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
@ -116,6 +118,7 @@ public class ClientProxy extends CommonProxy {
}
}
OBJLoader.INSTANCE.addDomain(IndustrialWires.MODID);
ModelLoaderRegistry.registerLoader(new PanelModelLoader());
MinecraftForge.EVENT_BUS.register(new ClientEventHandler());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityJacobsLadder.class, new TileRenderJacobsLadder());
}

View file

@ -0,0 +1,52 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.client;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import org.lwjgl.util.vector.Vector3f;
import java.util.Arrays;
public class RawQuad {
public final Vector3f[] vertices = new Vector3f[4];
public final EnumFacing facing;
public final TextureAtlasSprite tex;
public final float[] colorA;
public final Vector3f normal;
public final float[] uvs;
public RawQuad(Vector3f v0, Vector3f v1, Vector3f v2, Vector3f v3,
EnumFacing facing, TextureAtlasSprite tex, float[] colorA,
Vector3f normal, float[] uvs) {
vertices[0] = v0;
vertices[1] = v1;
vertices[2] = v2;
vertices[3] = v3;
this.facing = facing;
this.tex = tex;
if (colorA.length==3) {
this.colorA = Arrays.copyOf(colorA, 4);
this.colorA[3] = 1;
} else {
this.colorA = colorA;
}
this.normal = normal;
this.uvs = uvs;
}
}

View file

@ -0,0 +1,151 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.client.panelmodel;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import malte0811.industrialWires.blocks.controlpanel.PropertyComponents;
import malte0811.industrialWires.blocks.controlpanel.PropertyComponents.ComponentList;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.property.IExtendedBlockState;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class PanelModel implements IBakedModel {
public final static Cache<ComponentList, AssembledBakedModel> modelCache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterAccess(60, TimeUnit.SECONDS)
.build();//TODO make all components implement equals+hashCode
private IBakedModel base;
public PanelModel(IBakedModel base) {
this.base = base;
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
if (state instanceof IExtendedBlockState) {
ComponentList cl = ((IExtendedBlockState) state).getValue(PropertyComponents.INSTANCE);
if (cl == null) {
return base.getQuads(state, side, rand);
}
//modelCache.invalidateAll();//TODO remove
AssembledBakedModel m = modelCache.getIfPresent(cl);
if (m == null) {
m = new AssembledBakedModel(cl, base, rand);
modelCache.put(cl.copyOf(), m);
}
return m.getQuads(state, side, rand);
}
return base.getQuads(state, side, rand);
}
@Override
public boolean isAmbientOcclusion() {
return false;
}
@Override
public boolean isGui3d() {
return false;
}
@Override
public boolean isBuiltInRenderer() {
return false;
}
@Override
public TextureAtlasSprite getParticleTexture() {
return base.getParticleTexture();
}
@Override
public ItemCameraTransforms getItemCameraTransforms() {
return ItemCameraTransforms.DEFAULT;
}
@Override
public ItemOverrideList getOverrides() {
return ItemOverrideList.NONE;
}
public class AssembledBakedModel implements IBakedModel {
IBakedModel basic;
ComponentList components;
List<BakedQuad> quads;
public AssembledBakedModel(ComponentList comp, IBakedModel b, long posRand) {
basic = b;
components = comp;
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
if (quads == null) {
quads = PanelUtils.generateQuads(components);
quads.addAll(basic.getQuads(state, side, rand));
quads = Collections.synchronizedList(quads);
}
return quads;
}
@Override
public boolean isAmbientOcclusion() {
return false;
}
@Override
public boolean isGui3d() {
return false;
}
@Override
public boolean isBuiltInRenderer() {
return false;
}
@Override
public TextureAtlasSprite getParticleTexture() {
return basic.getParticleTexture();
}
@Override
public ItemCameraTransforms getItemCameraTransforms() {
return ItemCameraTransforms.DEFAULT;
}
@Override
public ItemOverrideList getOverrides() {
return ItemOverrideList.NONE;
}
}
}

View file

@ -0,0 +1,119 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.client.panelmodel;
import blusunrize.immersiveengineering.common.util.IELogger;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import malte0811.industrialWires.IndustrialWires;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.obj.OBJModel;
import net.minecraftforge.common.model.IModelState;
import java.io.IOException;
import java.util.*;
public class PanelModelLoader implements ICustomModelLoader {
public static final String RESOURCE_BASE = "models/block/";
public static final String RESOURCE_LOCATION = "smartmodel/panel_";
public static final Map<String, ResourceLocation> baseModels = new HashMap<>();
static {
baseModels.put("normal", new ResourceLocation(IndustrialWires.MODID, "block/panel_normal"));
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
PanelModel.modelCache.invalidateAll();
}
@Override
public boolean accepts(ResourceLocation modelLocation) {
return modelLocation.getResourcePath().contains(RESOURCE_BASE+RESOURCE_LOCATION);
}
@Override
public IModel loadModel(ResourceLocation modelLocation) throws IOException {
String resourcePath = modelLocation.getResourcePath();
int pos = resourcePath.indexOf(RESOURCE_LOCATION);
if (pos >= 0) {
pos += RESOURCE_LOCATION.length();
String name = resourcePath.substring(pos);
ResourceLocation r = baseModels.get(name);
if (r != null) {
return new PanelModelBase(r);
}
}
return ModelLoaderRegistry.getMissingModel();
}
private class PanelModelBase implements IModel {
ResourceLocation base;
public PanelModelBase(ResourceLocation b) {
base = b;
}
@Override
public Collection<ResourceLocation> getDependencies() {
return ImmutableList.of(base);
}
@Override
public Collection<ResourceLocation> getTextures() {
try {
List<ResourceLocation> ret = new ArrayList<>(ModelLoaderRegistry.getModel(base).getTextures());
//ret.add(ModelLoader.White.LOCATION);
for (ResourceLocation res:ret) {
IELogger.info(res);
}
return ret;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
try {
IModel model = ModelLoaderRegistry.getModel(base);
if (model instanceof OBJModel) {
OBJModel obj = (OBJModel) model;
model = obj.process(ImmutableMap.of("flip-v", "true"));
}
return new PanelModel(model.bake(state, format, bakedTextureGetter));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public IModelState getDefaultState() {
return null;
}
}
}

View file

@ -0,0 +1,133 @@
/*
* This file is part of Industrial Wires.
* Copyright (C) 2016-2017 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.client.panelmodel;
import blusunrize.immersiveengineering.client.ClientUtils;
import blusunrize.immersiveengineering.common.util.IELogger;
import com.google.common.collect.ImmutableList;
import malte0811.industrialWires.blocks.controlpanel.PanelComponent;
import malte0811.industrialWires.blocks.controlpanel.PropertyComponents;
import malte0811.industrialWires.client.RawQuad;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.obj.OBJModel;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import org.lwjgl.util.vector.Vector3f;
import java.util.ArrayList;
import java.util.List;
public final class PanelUtils {
private PanelUtils() {}
public static List<BakedQuad> generateQuads(PropertyComponents.ComponentList components) {
//TODO different sizes of panels?
List<BakedQuad> ret = new ArrayList<>();
final float panelHeight = .5F;
for (PanelComponent pc:components) {
List<RawQuad> compQuads = pc.getQuads();
for (RawQuad bq:compQuads) {
ret.add(bakeQuad(bq, new Vector3f(pc.getX(), panelHeight, pc.getY())));
}
}
return ret;
}
public static BakedQuad bakeQuad(RawQuad raw, Vector3f offset) {
VertexFormat format = DefaultVertexFormats.ITEM;
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadOrientation(raw.facing);
builder.setTexture(raw.tex);
Vector3f[] vertices = raw.vertices;
float[] uvs = raw.uvs;
OBJModel.Normal faceNormal = new OBJModel.Normal(raw.normal.x, raw.normal.y, raw.normal.z);
putVertexData(format, builder, vertices[0].translate(offset.x, offset.y, offset.z), faceNormal, uvs[0], uvs[1], raw.tex,
raw.colorA);
putVertexData(format, builder, vertices[1].translate(offset.x, offset.y, offset.z), faceNormal, uvs[0], uvs[3], raw.tex,
raw.colorA);
putVertexData(format, builder, vertices[2].translate(offset.x, offset.y, offset.z), faceNormal, uvs[2], uvs[3], raw.tex,
raw.colorA);
putVertexData(format, builder, vertices[3].translate(offset.x, offset.y, offset.z), faceNormal, uvs[2], uvs[1], raw.tex,
raw.colorA);
return builder.build();
}
//mostly copied from IE's ClientUtils, it has protected access there...
public static void putVertexData(VertexFormat format, UnpackedBakedQuad.Builder builder, Vector3f pos, OBJModel.Normal faceNormal, double u, double v, TextureAtlasSprite sprite, float[] colorA)
{
for(int e = 0; e < format.getElementCount(); e++)
switch(format.getElement(e).getUsage())
{
case POSITION:
builder.put(e, pos.getX(), pos.getY(), pos.getZ(), 0);
break;
case COLOR:
builder.put(e, colorA[0], colorA[1], colorA[2], colorA[3]);
break;
case UV:
if(sprite == null)//Double Safety. I have no idea how it even happens, but it somehow did .-.
sprite = Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite();
builder.put(e,
sprite.getInterpolatedU(u),
sprite.getInterpolatedV((v)),
0, 1);
break;
case NORMAL:
builder.put(e, faceNormal.x, faceNormal.y, faceNormal.z, 0);
break;
default:
builder.put(e);
}
}
public static void addColoredBox(float[] colorTop, float[] colorSides, float[] colorBottom, Vector3f min, Vector3f size, List<RawQuad> out, boolean doBottom) {
addQuad(out, new Vector3f(min.x, min.y+size.y, min.z), new Vector3f(min.x, min.y+size.y, min.z+size.z),
new Vector3f(min.x+size.x, min.y+size.y, min.z+size.z), new Vector3f(min.x+size.x, min.y+size.y, min.z),
EnumFacing.UP, colorTop);
if (doBottom) {
addQuad(out, new Vector3f(min.x, min.y, min.z), new Vector3f(min.x+size.x, min.y, min.z),
new Vector3f(min.x+size.x, min.y, min.z+size.z), new Vector3f(min.x, min.y, min.z+size.z),
EnumFacing.UP, colorBottom);
}
addQuad(out, new Vector3f(min.x, min.y, min.z), new Vector3f(min.x, min.y, min.z+size.z),
new Vector3f(min.x, min.y+size.y, min.z+size.z), new Vector3f(min.x, min.y+size.y, min.z),
EnumFacing.WEST, colorSides);
addQuad(out, new Vector3f(min.x+size.x, min.y, min.z), new Vector3f(min.x+size.x, min.y+size.y, min.z),
new Vector3f(min.x+size.x, min.y+size.y, min.z+size.z), new Vector3f(min.x+size.x, min.y, min.z+size.z),
EnumFacing.EAST, colorSides);
addQuad(out, new Vector3f(min.x, min.y, min.z), new Vector3f(min.x, min.y+size.y, min.z),
new Vector3f(min.x+size.x, min.y+size.y, min.z), new Vector3f(min.x+size.x, min.y, min.z),
EnumFacing.NORTH, colorSides);
addQuad(out, new Vector3f(min.x, min.y, min.z+size.z), new Vector3f(min.x+size.x, min.y, min.z+size.z),
new Vector3f(min.x+size.x, min.y+size.y, min.z+size.z), new Vector3f(min.x, min.y+size.y, min.z+size.z),
EnumFacing.SOUTH, colorSides);
}
private static final float[] UV_FULL = {0, 0, 1, 1};
public static void addQuad(List<RawQuad> out, Vector3f v0, Vector3f v1, Vector3f v2, Vector3f v3, EnumFacing dir, float[] color) {
Vec3i dirV = dir.getDirectionVec();
out.add(new RawQuad(v0, v1, v2, v3, dir, Minecraft.getMinecraft().getTextureMapBlocks().getTextureExtry(ModelLoader.White.LOCATION.toString()),
color, new Vector3f(dirV.getX(), dirV.getY(), dirV.getZ()), UV_FULL));
}
}

View file

@ -0,0 +1,33 @@
{
"forge_marker": 1,
"defaults": {
"transform": "forge:default-block",
"textures": {
},
"model": "industrialwires:smartmodel/panel_normal",
"custom": {
"flip-v": true
}
},
"variants": {
"facing":
{
"north": { "transform": {
"rotation": {"y": 0 }
}},
"south": { "transform": {
"rotation": {"y": 180 }
}},
"west": { "transform": {
"rotation": {"y": 90 }
}},
"east": { "transform": {
"rotation": {"y": -90 }
}}
},
"inventory": {
"model":"industrialwires:panel_normal"
}
}
}

View file

@ -0,0 +1,21 @@
{ "parent": "block/block",
"textures": {
"particle": "#side",
"bottom": "blocks/iron_block",
"top": "blocks/iron_block",
"side": "blocks/iron_block"
},
"elements": [
{ "from": [ 0, 0, 0 ],
"to": [ 16, 8, 16 ],
"faces": {
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom"},
"up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" },
"north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side"},
"south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side"},
"west": { "uv": [ 0, 8, 16, 16 ], "texture": "#side"},
"east": { "uv": [ 0, 8, 16, 16 ], "texture": "#side"}
}
}
]
}