Started work on lain down wires

This commit is contained in:
Calclavia 2013-12-21 14:23:59 +08:00
parent 3261ce11c3
commit f9a4efa89b
19 changed files with 1473 additions and 355 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 702 B

After

Width:  |  Height:  |  Size: 702 B

View file

@ -1,7 +1,8 @@
package resonantinduction;
import resonantinduction.wire.EnumWireMaterial;
import resonantinduction.wire.PartWire;
import resonantinduction.wire.part.PartLainWire;
import resonantinduction.wire.part.PartWire;
import universalelectricity.api.energy.IConductor;
import codechicken.multipart.MultiPartRegistry;
import codechicken.multipart.MultiPartRegistry.IPartFactory;
import codechicken.multipart.MultipartGenerator;
@ -19,18 +20,20 @@ public class MultipartRI implements IPartFactory
public TMultiPart createPart(String name, boolean client)
{
if (name == "resonant_induction_wire")
return new PartWire(EnumWireMaterial.COPPER.ordinal());
return new PartWire();
if (name == "resonant_induction_lain_wire")
return new PartLainWire();
return null;
}
public void init()
{
MultiPartRegistry.registerParts(this, new String[] { "resonant_induction_wire" });
MultipartGenerator.registerPassThroughInterface("universalelectricity.core.block.IConductor");
MultiPartRegistry.registerParts(this, new String[] { "resonant_induction_wire", "resonant_induction_lain_wire" });
MultipartGenerator.registerPassThroughInterface(IConductor.class.getName());
MultipartGenerator.registerPassThroughInterface("buildcraft.api.power.IPowerReceptor");
MultipartGenerator.registerPassThroughInterface("resonantinduction.wire.IInsulatedMaterial");
MultipartGenerator.registerPassThroughInterface("resonantinduction.wire.multipart.IBlockableConnection");
MultipartGenerator.registerTrait("ic2.api.energy.tile.IEnergySink", "resonantinduction.wire.multipart.javatraits.TEnergySink");
MultipartGenerator.registerPassThroughInterface("resonantinduction.wire.IBlockableConnection");
MultipartGenerator.registerTrait("ic2.api.energy.tile.IEnergySink", "resonantinduction.wire.TEnergySink");
}
}

View file

@ -0,0 +1,36 @@
package resonantinduction;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import codechicken.lib.vec.BlockCoord;
import codechicken.multipart.TileMultipart;
/**
* @author Calclavia
*
*/
public class Utility
{
public static TileMultipart getMultipartTile(IBlockAccess access, BlockCoord pos)
{
TileEntity te = access.getBlockTileEntity(pos.x, pos.y, pos.z);
return te instanceof TileMultipart ? (TileMultipart) te : null;
}
public static boolean canPlaceWireOnSide(World w, int x, int y, int z, ForgeDirection side, boolean _default)
{
if (!w.blockExists(x, y, z))
return _default;
Block b = Block.blocksList[w.getBlockId(x, y, z)];
if (b == null)
return false;
// Manual list of allowed blocks that wire can sit on.
if (b == Block.glowStone || b == Block.pistonBase || b == Block.pistonStickyBase || b == Block.pistonMoving)
return true;
return b.isBlockSolidOnSide(w, x, y, z, side);
}
}

View file

@ -1,4 +1,4 @@
package resonantinduction.wire;
package resonantinduction.base;
import net.minecraft.block.Block;
import codechicken.multipart.TMultiPart;

View file

@ -13,12 +13,12 @@ import universalelectricity.core.grid.IEnergyNetwork;
*/
public class MultimeterEventHandler
{
private static final HashMap<IEnergyNetwork, Integer> networkEnergyCache = new HashMap<IEnergyNetwork, Integer>();
private static final HashMap<IEnergyNetwork, Long> networkEnergyCache = new HashMap<IEnergyNetwork, Long>();
private static long lastCheckTime = 0;
public static HashMap<IEnergyNetwork, Float> getCache(World worldObj)
public static HashMap<IEnergyNetwork, Long> getCache(World worldObj)
{
HashMap<IEnergyNetwork, Float> returnCache = (HashMap<IEnergyNetwork, Float>) networkEnergyCache.clone();
HashMap<IEnergyNetwork, Long> returnCache = new HashMap<IEnergyNetwork, Long>(networkEnergyCache);
if (Math.abs(worldObj.getWorldTime() - lastCheckTime) >= 40)
{

View file

@ -176,7 +176,7 @@ public class TileEntityMultimeter extends TileEntityAdvanced implements IConnect
{
IElectricityNetwork network = ((IConductor) tileEntity).getNetwork();
if (MultimeterEventHandler.getCache(tileEntity.worldObj).containsKey(network) && MultimeterEventHandler.getCache(tileEntity.worldObj).get(network) instanceof Float)
if (MultimeterEventHandler.getCache(tileEntity.worldObj).containsKey(network) && MultimeterEventHandler.getCache(tileEntity.worldObj).get(network) instanceof Long)
{
return MultimeterEventHandler.getCache(tileEntity.worldObj).get(network);
}

View file

@ -3,19 +3,12 @@ package resonantinduction.render;
import codechicken.lib.vec.Matrix4;
import codechicken.lib.vec.Transformation;
import codechicken.lib.vec.VariableTransformation;
import codechicken.lib.vec.Vector3;
public class InvertX extends VariableTransformation
{
public InvertX()
{
super(new Matrix4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1));
}
@Override
public void apply(Vector3 vec)
{
this.mat.apply(vec);
super(new Matrix4(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1));
}
@Override
@ -23,4 +16,10 @@ public class InvertX extends VariableTransformation
{
return this;
}
@Override
public void apply(codechicken.lib.vec.Vector3 vec)
{
vec.x = -vec.x;
}
}

View file

@ -4,7 +4,7 @@ import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import universalelectricity.api.vector.Vector3;
import codechicken.lib.colour.ColourRGBA;
/**
* An enumerator for different wire materials. The metadata of the wire determines the type of the
@ -16,27 +16,25 @@ import universalelectricity.api.vector.Vector3;
public enum EnumWireMaterial
{
COPPER("Copper", 12.5F, 3, 2, new Vector3(184, 115, 51)),
TIN("Tin", 13, 2, 0.5F, new Vector3(132, 132, 130)),
IRON("Iron", 0.1F, 2, 4, new Vector3(97, 102, 105)),
ALUMINUM("Aluminum", 0.025F, 6, 0.15F, new Vector3(215, 205, 181)),
SILVER("Silver", 0.005F, 1, 2, new Vector3(192, 192, 192)),
SUPERCONDUCTOR("Superconductor", 0, 1, 2, new Vector3(192, 192, 192));
COPPER("Copper", 12.5F, 3, 2, 184, 115, 51), TIN("Tin", 13, 2, 0.5F, 132, 132, 130),
IRON("Iron", 0.1F, 2, 4, 97, 102, 105), ALUMINUM("Aluminum", 0.025F, 6, 0.15F, 215, 205, 181),
SILVER("Silver", 0.005F, 1, 2, 192, 192, 192),
SUPERCONDUCTOR("Superconductor", 0, 1, 2, 192, 192, 192);
public final float resistance;
public final float damage;
public final float maxAmps;
public final Vector3 color;
public final ColourRGBA color;
private ItemStack wire;
private final String name;
private EnumWireMaterial(String s, float resist, float electrocution, float max, Vector3 vec)
private EnumWireMaterial(String s, float resist, float electrocution, float max, int r, int g, int b)
{
name = s;
resistance = resist;
damage = electrocution;
maxAmps = max;
color = vec.scale(1D / 255D);
color = new ColourRGBA(r, g, b, 1);
}
public String getName()

View file

@ -1,61 +0,0 @@
package resonantinduction.wire;
import java.util.List;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import universalelectricity.api.electricity.ElectricityDisplay;
import universalelectricity.api.electricity.ElectricityDisplay.ElectricUnit;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ItemBlockWire extends ItemBlock
{
private Icon[] icons = new Icon[EnumWireMaterial.values().length];
public ItemBlockWire(int id)
{
super(id);
this.setHasSubtypes(true);
this.setMaxDamage(0);
}
@Override
public int getMetadata(int damage)
{
return damage;
}
@Override
public String getUnlocalizedName(ItemStack itemStack)
{
return this.getUnlocalizedName() + "." + EnumWireMaterial.values()[itemStack.getItemDamage()].name().toLowerCase();
}
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List par3List, boolean par4)
{
par3List.add("Resistance: " + ElectricityDisplay.getDisplay(EnumWireMaterial.values()[itemstack.getItemDamage()].resistance, ElectricUnit.RESISTANCE));
par3List.add("Max Amperage: " + ElectricityDisplay.getDisplay(EnumWireMaterial.values()[itemstack.getItemDamage()].maxAmps, ElectricUnit.AMPERE));
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister iconRegister)
{
for (int i = 0; i < EnumWireMaterial.values().length; i++)
{
this.icons[i] = iconRegister.registerIcon(this.getUnlocalizedName(new ItemStack(this.itemID, 1, i)).replaceAll("tile.", ""));
}
}
@Override
@SideOnly(Side.CLIENT)
public Icon getIconFromDamage(int meta)
{
return this.icons[meta];
}
}

View file

@ -11,7 +11,9 @@ import net.minecraft.world.World;
import net.minecraftforge.common.Configuration;
import resonantinduction.ResonantInduction;
import resonantinduction.TabRI;
import resonantinduction.render.RenderPartWire;
import resonantinduction.wire.part.PartLainWire;
import resonantinduction.wire.part.PartWire;
import resonantinduction.wire.render.RenderPartWire;
import universalelectricity.api.electricity.ElectricityDisplay;
import universalelectricity.api.electricity.ElectricityDisplay.ElectricUnit;
import codechicken.lib.vec.BlockCoord;
@ -35,9 +37,14 @@ public class ItemPartWire extends JItemMultiPart
}
@Override
public TMultiPart newPart(ItemStack arg0, EntityPlayer arg1, World arg2, BlockCoord arg3, int arg4, Vector3 arg5)
public TMultiPart newPart(ItemStack arg0, EntityPlayer player, World arg2, BlockCoord arg3, int arg4, Vector3 arg5)
{
return new PartWire(getDamage(arg0));
if (player.isSneaking())
{
return new PartWire(getDamage(arg0));
}
return new PartLainWire(getDamage(arg0));
}
@Override
@ -64,7 +71,7 @@ public class ItemPartWire extends JItemMultiPart
public void registerIcons(IconRegister register)
{
for (EnumWireMaterial material : EnumWireMaterial.values())
{System.out.println(ResonantInduction.PREFIX + "wire." + EnumWireMaterial.values()[material.ordinal()].getName().toLowerCase());
{
icons[material.ordinal()] = register.registerIcon(ResonantInduction.PREFIX + "wire." + EnumWireMaterial.values()[material.ordinal()].getName().toLowerCase());
}

View file

@ -1,11 +1,9 @@
package resonantinduction.wire;
package resonantinduction.wire.part;
import resonantinduction.ResonantInduction;
import calclavia.lib.prefab.block.EnergyStorage;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.api.IConnector;
import universalelectricity.api.INetworkProvider;
import resonantinduction.ResonantInduction;
import resonantinduction.base.PartAdvanced;
import universalelectricity.api.UniversalClass;
import universalelectricity.api.energy.IConductor;
import universalelectricity.api.energy.IEnergyInterface;
@ -13,6 +11,7 @@ import universalelectricity.api.vector.Vector3;
import universalelectricity.api.vector.VectorHelper;
import universalelectricity.core.grid.EnergyNetworkLoader;
import universalelectricity.core.grid.IEnergyNetwork;
import calclavia.lib.prefab.block.EnergyStorage;
import codechicken.multipart.TileMultipart;
@UniversalClass
@ -21,26 +20,26 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
private IEnergyNetwork network;
private EnergyStorage buffer = new EnergyStorage(ResonantInduction.FURNACE_WATTAGE * 5);
public TileEntity[] adjacentConnections = null;
public TileEntity[] cachedConnections = null;
public byte currentWireConnections = 0x00;
public byte currentAcceptorConnections = 0x00;
@Override
public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
{
return buffer.receiveEnergy(receive, doReceive);
return this.buffer.receiveEnergy(receive, doReceive);
}
@Override
public long onExtractEnergy(ForgeDirection from, long request, boolean doExtract)
{
return buffer.extractEnergy(request, doExtract);
return this.buffer.extractEnergy(request, doExtract);
}
@Override
public void distribute()
{
Object[] receivers = this.getAdjacentConnections();
Object[] receivers = this.getConnections();
int energyUsed = 0;
for (int i = 0; i < receivers.length; i++)
@ -133,9 +132,9 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
{
boolean notPrevented = !isConnectionPrevented(tile, side);
if (tile instanceof IConnector)
if (tile instanceof IConductor)
{
notPrevented &= ((IConnector) tile).canConnect(side.getOpposite());
notPrevented &= ((IConductor) tile).canConnect(side.getOpposite());
}
return notPrevented;
@ -166,8 +165,9 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tileEntity = VectorHelper.getTileEntityFromSide(world(), new Vector3(tile()), side);
System.out.println("WORK"+tileEntity + " : "+(tileEntity instanceof IConductor));
if (tileEntity instanceof INetworkProvider && canConnectBothSides(tileEntity, side))
if (tileEntity instanceof IConductor && canConnectBothSides(tileEntity, side))
{
connections |= 1 << side.ordinal();
}
@ -198,19 +198,20 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
*/
public boolean isValidAcceptor(TileEntity tile)
{
return tile instanceof IConnector;
return tile instanceof IConductor;
}
public void refresh()
{
if (!world().isRemote)
{
adjacentConnections = null;
this.cachedConnections = null;
byte possibleWireConnections = getPossibleWireConnections();
byte possibleAcceptorConnections = getPossibleAcceptorConnections();
System.out.println(possibleWireConnections);
if (possibleWireConnections != currentWireConnections)
if (possibleWireConnections != this.currentWireConnections)
{
byte or = (byte) (possibleWireConnections | currentWireConnections);
@ -237,7 +238,6 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
}
this.currentAcceptorConnections = possibleAcceptorConnections;
this.sendDescUpdate();
}
@ -249,11 +249,11 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
* aren't allowed any more. This is so that networks split correctly.
*/
@Override
public TileEntity[] getAdjacentConnections()
public TileEntity[] getConnections()
{
if (this.adjacentConnections == null)
if (this.cachedConnections == null)
{
this.adjacentConnections = new TileEntity[6];
this.cachedConnections = new TileEntity[6];
for (byte i = 0; i < 6; i++)
{
@ -262,11 +262,11 @@ public abstract class PartConductor extends PartAdvanced implements IConductor
if (isCurrentlyConnected(side))
{
this.adjacentConnections[i] = tileEntity;
this.cachedConnections[i] = tileEntity;
}
}
}
return this.adjacentConnections;
return this.cachedConnections;
}
public boolean isCurrentlyConnected(ForgeDirection side)

View file

@ -0,0 +1,618 @@
package resonantinduction.wire.part;
import java.util.Arrays;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Icon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraftforge.common.ForgeDirection;
import org.lwjgl.opengl.GL11;
import resonantinduction.Utility;
import resonantinduction.wire.EnumWireMaterial;
import resonantinduction.wire.render.RenderLainWire;
import resonantinduction.wire.render.RenderPartWire;
import universalelectricity.api.energy.IConductor;
import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput;
import codechicken.lib.lighting.LazyLightMatrix;
import codechicken.lib.raytracer.IndexedCuboid6;
import codechicken.lib.render.CCRenderState;
import codechicken.lib.render.TextureUtils;
import codechicken.lib.vec.BlockCoord;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Vector3;
import codechicken.multipart.JNormalOcclusion;
import codechicken.multipart.NormalOcclusionTest;
import codechicken.multipart.PartMap;
import codechicken.multipart.TFacePart;
import codechicken.multipart.TMultiPart;
import codechicken.multipart.TileMultipart;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* This is the base class for all wire types. It can be used for any sub type,
* as it contains the base calculations necessary to create a working wire. This
* calculates all possible connections to sides, around corners, and inside
* corners, while checking for microblock obstructions.
*
* @author Modified by Calclavia, MrTJP
*
*/
public class PartLainWire extends PartWireBase implements IConductor, TFacePart, JNormalOcclusion
{
public static Cuboid6[][] selectionBounds = new Cuboid6[3][6];
public static Cuboid6[][] occlusionBounds = new Cuboid6[3][6];
static
{
for (int t = 0; t < 3; t++)
{
// subtract the box a little because we'd like things like posts to get first hit
Cuboid6 selection = new Cuboid6(0, 0, 0, 1, (t + 2) / 16D, 1).expand(-0.005);
Cuboid6 occlusion = new Cuboid6(2 / 8D, 0, 2 / 8D, 6 / 8D, (t + 2) / 16D, 6 / 8D);
for (int s = 0; s < 6; s++)
{
selectionBounds[t][s] = selection.copy().apply(Rotation.sideRotations[s].at(Vector3.center));
occlusionBounds[t][s] = occlusion.copy().apply(Rotation.sideRotations[s].at(Vector3.center));
}
}
}
public byte side;
/**
* A map of the corners.
*
*
* Currently split into 4 nybbles (from lowest)
* 0 = Corner connections (this wire should connect around a corner to something external)
* 1 = Straight connections (this wire should connect to something external)
* 2 = Internal connections (this wire should connect to something internal)
* 3 = Internal open connections (this wire is not blocked by a cover/edge part and *could*
* connect through side)
* bit 16 = connection to the centerpart
* 5 = Render corner connections. Like corner connections but set to low if the other wire part
* is smaller than this (they render to us not us to them)
*/
public int connMap;
public PartLainWire()
{
super();
}
public PartLainWire(int typeID)
{
this(EnumWireMaterial.values()[typeID]);
}
public PartLainWire(EnumWireMaterial type)
{
super();
material = type;
}
public void preparePlacement(int side, int meta)
{
this.side = (byte) (side ^ 1);
}
/**
* PACKET and NBT Methods
*/
@Override
public void load(NBTTagCompound tag)
{
super.load(tag);
this.side = tag.getByte("side");
this.connMap = tag.getInteger("connMap");
}
@Override
public void save(NBTTagCompound tag)
{
super.save(tag);
tag.setByte("side", side);
tag.setInteger("connMap", connMap);
}
@Override
public void readDesc(MCDataInput packet)
{
super.readDesc(packet);
/*this.side = packet.readByte();
this.connMap = packet.readInt();*/
}
@Override
public void writeDesc(MCDataOutput packet)
{
super.writeDesc(packet);
/*packet.writeByte(this.side);
packet.writeInt(this.connMap);*/
}
@Override
public void read(MCDataInput packet)
{
read(packet, packet.readUByte());
}
public void read(MCDataInput packet, int switch_key)
{
if (switch_key == 0)
{
connMap = packet.readInt();
tile().markRender();
}
}
public void sendConnUpdate()
{
tile().getWriteStream(this).writeByte(0).writeInt(connMap);
}
@Override
public void onRemoved()
{
super.onRemoved();
if (!world().isRemote)
for (int r = 0; r < 4; r++)
if (maskConnects(r))
if ((connMap & 1 << r) != 0)
notifyCornerChange(r);
else if ((connMap & 0x10 << r) != 0)
notifyStraightChange(r);
}
@Override
public void onChunkLoad()
{
if ((connMap & 0x80000000) != 0) // compat with converters, recalc connections
{
if (dropIfCantStay())
return;
connMap = 0;
updateInternalConnections();
if (updateOpenConnections())
updateExternalConnections();
tile().markDirty();
}
}
public boolean canStay()
{
BlockCoord pos = new BlockCoord(tile()).offset(side);
return Utility.canPlaceWireOnSide(world(), pos.x, pos.y, pos.z, ForgeDirection.getOrientation(side ^ 1), false);
}
public boolean dropIfCantStay()
{
if (!canStay())
{
drop();
return true;
}
return false;
}
public void drop()
{
TileMultipart.dropItem(getItem(), world(), Vector3.fromTileEntityCenter(tile()));
tile().remPart(this);
}
/**
* Recalculates connections to blocks outside this space
*
* @return true if a new connection was added or one was removed
*/
protected boolean updateExternalConnections()
{
int newConn = 0;
for (int r = 0; r < 4; r++)
{
if (!maskOpen(r))
continue;
if (connectStraight(r))
newConn |= 0x10 << r;
else
{
int cnrMode = connectCorner(r);
if (cnrMode != 0)
{
newConn |= 1 << r;
if (cnrMode == 2)
newConn |= 0x100000 << r;// render flag
}
}
}
if (newConn != (connMap & 0xF000FF))
{
int diff = connMap ^ newConn;
connMap = connMap & ~0xF000FF | newConn;
// notify corner disconnections
for (int r = 0; r < 4; r++)
if ((diff & 1 << r) != 0)
notifyCornerChange(r);
return true;
}
return false;
}
/**
* Recalculates connections to other parts within this space
*
* @return true if a new connection was added or one was removed
*/
protected boolean updateInternalConnections()
{
int newConn = 0;
for (int r = 0; r < 4; r++)
if (connectInternal(r))
newConn |= 0x100 << r;
if (connectCenter())
newConn |= 0x10000;
if (newConn != (connMap & 0x10F00))
{
connMap = connMap & ~0x10F00 | newConn;
return true;
}
return false;
}
/**
* Recalculates connections that can be made to other parts outside of this
* space
*
* @return true if external connections should be recalculated
*/
protected boolean updateOpenConnections()
{
int newConn = 0;
for (int r = 0; r < 4; r++)
if (connectionOpen(r))
newConn |= 0x1000 << r;
if (newConn != (connMap & 0xF000))
{
connMap = connMap & ~0xF000 | newConn;
return true;
}
return false;
}
public boolean connectionOpen(int r)
{
int absDir = Rotation.rotateSide(side, r);
TMultiPart facePart = tile().partMap(absDir);
if (facePart != null && (!(facePart instanceof PartLainWire) || !canConnectToType((PartLainWire) facePart)))
return false;
if (tile().partMap(PartMap.edgeBetween(side, absDir)) != null)
return false;
return true;
}
/**
* Return a corner connection state.
* 0 = No connection
* 1 = Physical connection
* 2 = Render connection
*/
public int connectCorner(int r)
{
int absDir = Rotation.rotateSide(side, r);
BlockCoord pos = new BlockCoord(tile());
pos.offset(absDir);
if (!canConnectThroughCorner(pos, absDir ^ 1, side))
return 0;
pos.offset(side);
TileMultipart t = Utility.getMultipartTile(world(), pos);
if (t != null)
{
TMultiPart tp = t.partMap(absDir ^ 1);
if (tp instanceof IConductor)
{
boolean b = ((PartLainWire) tp).connectCorner(this, Rotation.rotationTo(absDir ^ 1, side ^ 1));
if (b)
{
// let them connect to us
if (tp instanceof PartLainWire && !renderThisCorner((PartLainWire) tp))
return 1;
return 2;
}
}
}
return 0;
}
public boolean canConnectThroughCorner(BlockCoord pos, int side1, int side2)
{
if (world().isAirBlock(pos.x, pos.y, pos.z))
return true;
TileMultipart t = Utility.getMultipartTile(world(), pos);
if (t != null)
return t.partMap(side1) == null && t.partMap(side2) == null && t.partMap(PartMap.edgeBetween(side1, side2)) == null;
return false;
}
public boolean connectStraight(int r)
{
int absDir = Rotation.rotateSide(side, r);
BlockCoord pos = new BlockCoord(tile()).offset(absDir);
TileMultipart t = Utility.getMultipartTile(world(), pos);
if (t != null)
{
TMultiPart tp = t.partMap(side);
if (tp instanceof PartLainWire)
return ((PartLainWire) tp).connectStraight(this, (r + 2) % 4);
}
return connectStraightOverride(absDir);
}
public boolean connectStraightOverride(int absDir)
{
return false;
}
public boolean connectInternal(int r)
{
int absDir = Rotation.rotateSide(side, r);
if (tile().partMap(PartMap.edgeBetween(absDir, side)) != null)
return false;
TMultiPart tp = tile().partMap(absDir);
if (tp instanceof PartLainWire)
return ((PartLainWire) tp).connectInternal(this, Rotation.rotationTo(absDir, side));
return connectInternalOverride(tp, r);
}
public boolean connectInternalOverride(TMultiPart p, int r)
{
return false;
}
public boolean connectCenter()
{
TMultiPart t = tile().partMap(6);
if (t instanceof PartLainWire)
return ((PartLainWire) t).connectInternal(this, side);
return false;
}
public boolean renderThisCorner(IConductor part)
{
if (!(part instanceof PartLainWire))
return false;
PartLainWire wire = (PartLainWire) part;
if (wire.getThickness() == getThickness())
return side < wire.side;
return wire.getThickness() > getThickness();
}
public boolean connectCorner(IConductor wire, int r)
{
if (canConnectToType(wire) && maskOpen(r))
{
int oldConn = connMap;
connMap |= 0x1 << r;
if (renderThisCorner(wire))// render connection
connMap |= 0x100000 << r;
if (oldConn != connMap)
sendConnUpdate();
return true;
}
return false;
}
public boolean connectStraight(IConductor wire, int r)
{
if (canConnectToType(wire) && maskOpen(r))
{
int oldConn = connMap;
connMap |= 0x10 << r;
if (oldConn != connMap)
sendConnUpdate();
return true;
}
return false;
}
public boolean connectInternal(IConductor wire, int r)
{
if (canConnectToType(wire))
{
int oldConn = connMap;
connMap |= 0x100 << r;
if (oldConn != connMap)
sendConnUpdate();
return true;
}
return false;
}
public boolean canConnectCorner(int r)
{
return true;
}
public void notifyCornerChange(int r)
{
int absDir = Rotation.rotateSide(side, r);
BlockCoord pos = new BlockCoord(tile()).offset(absDir).offset(side);
world().notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, tile().getBlockType().blockID);
}
public void notifyStraightChange(int r)
{
int absDir = Rotation.rotateSide(side, r);
BlockCoord pos = new BlockCoord(tile()).offset(absDir);
world().notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, tile().getBlockType().blockID);
}
public boolean maskConnects(int r)
{
return (connMap & 0x111 << r) != 0;
}
public boolean maskOpen(int r)
{
return (connMap & 0x1000 << r) != 0;
}
public boolean isWireSide(int side)
{
return true;
}
/** START TILEMULTIPART INTERACTIONS **/
@Override
public float getStrength(MovingObjectPosition hit, EntityPlayer player)
{
return 4;
}
@Override
public int getSlotMask()
{
return 1 << side;
}
@Override
public Iterable<IndexedCuboid6> getSubParts()
{
return Arrays.asList(new IndexedCuboid6(0, selectionBounds[getThickness()][side]));
}
@Override
public boolean occlusionTest(TMultiPart npart)
{
return NormalOcclusionTest.apply(this, npart);
}
@Override
public Iterable<Cuboid6> getOcclusionBoxes()
{
return Arrays.asList(occlusionBounds[getThickness()][side]);
}
public int getThickness()
{
return 1;
}
@Override
public int redstoneConductionMap()
{
return 0xF;
}
@Override
public boolean solid(int arg0)
{
return false;
}
@Override
public boolean isBlockedOnSide(ForgeDirection side)
{
return false;
}
@Override
public String getType()
{
return "resonant_induction_lain_wire";
}
/**
* RENDERING
*/
@SideOnly(Side.CLIENT)
public Icon getIcon()
{
return RenderPartWire.lainWireIcon;
}
public int getColour()
{
return this.getMaterial().color.pack();
}
public boolean useStaticRenderer()
{
return true;
}
@Override
@SideOnly(Side.CLIENT)
public void renderStatic(Vector3 pos, LazyLightMatrix olm, int pass)
{
if (pass == 0 && useStaticRenderer())
{
CCRenderState.setBrightness(world(), x(), y(), z());
RenderLainWire.render(this, pos);
CCRenderState.setColour(-1);
}
}
@Override
@SideOnly(Side.CLIENT)
public void renderDynamic(Vector3 pos, float frame, int pass)
{
if (pass == 0 && !useStaticRenderer())
{
GL11.glDisable(GL11.GL_LIGHTING);
TextureUtils.bindAtlas(0);
CCRenderState.useModelColours(true);
CCRenderState.startDrawing(7);
RenderLainWire.render(this, pos);
CCRenderState.draw();
CCRenderState.setColour(-1);
GL11.glEnable(GL11.GL_LIGHTING);
}
}
@Override
@SideOnly(Side.CLIENT)
public void drawBreaking(RenderBlocks renderBlocks)
{
CCRenderState.reset();
RenderLainWire.renderBreakingOverlay(renderBlocks.overrideBlockTexture, this);
}
}

View file

@ -1,28 +1,20 @@
package resonantinduction.wire;
package resonantinduction.wire.part;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.BlockColored;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemShears;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.render.RenderPartWire;
import universalelectricity.api.Compatibility;
import buildcraft.api.power.PowerHandler;
import resonantinduction.wire.EnumWireMaterial;
import resonantinduction.wire.IBlockableConnection;
import resonantinduction.wire.render.RenderPartWire;
import universalelectricity.api.energy.IConductor;
import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput;
import codechicken.lib.lighting.LazyLightMatrix;
@ -43,18 +35,29 @@ import codechicken.multipart.TSlottedPart;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PartWire extends PartConductor implements TSlottedPart, JNormalOcclusion, IHollowConnect, JIconHitEffects, IInsulatedMaterial, IBlockableConnection
public class PartWire extends PartWireBase implements TSlottedPart, JNormalOcclusion, IHollowConnect, JIconHitEffects
{
public static final int DEFAULT_COLOR = 16;
public int dyeID = DEFAULT_COLOR;
public boolean isInsulated = false;
/** Client Side Connection Check */
private ForgeDirection testingSide;
public static IndexedCuboid6[] sides = new IndexedCuboid6[7];
public static IndexedCuboid6[] insulatedSides = new IndexedCuboid6[7];
public EnumWireMaterial material = EnumWireMaterial.COPPER;
/** Client Side Connection Check */
private ForgeDirection testingSide;
public PartWire()
{
super();
}
public PartWire(int typeID)
{
this(EnumWireMaterial.values()[typeID]);
}
public PartWire(EnumWireMaterial type)
{
super();
material = type;
}
static
{
@ -74,22 +77,6 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
insulatedSides[6] = new IndexedCuboid6(6, new Cuboid6(0.3, 0.3, 0.3, 0.7, 0.7, 0.7));
}
public PartWire(int typeID)
{
this(EnumWireMaterial.values()[typeID]);
}
public PartWire(EnumWireMaterial type)
{
super();
material = type;
}
public PartWire()
{
super();
}
@Override
public boolean canConnect(ForgeDirection direction)
{
@ -104,27 +91,7 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
@Override
public boolean isConnectionPrevented(TileEntity tile, ForgeDirection side)
{
if (tile instanceof IWireMaterial)
{
IWireMaterial wireTile = (IWireMaterial) tile;
if (wireTile.getMaterial() != getMaterial())
{
return true;
}
}
if (isInsulated() && tile instanceof IInsulation)
{
IInsulation insulatedTile = (IInsulation) tile;
if ((insulatedTile.isInsulated() && insulatedTile.getInsulationColor() != getInsulationColor() && getInsulationColor() != DEFAULT_COLOR && insulatedTile.getInsulationColor() != DEFAULT_COLOR))
{
return true;
}
}
return (isBlockedOnSide(side) || tile instanceof IBlockableConnection && ((IBlockableConnection) tile).isBlockedOnSide(side.getOpposite()));
return (tile instanceof IConductor ? this.canConnectToType((IConductor) tile) : false) || (isBlockedOnSide(side) || tile instanceof IBlockableConnection && ((IBlockableConnection) tile).isBlockedOnSide(side.getOpposite()));
}
@Override
@ -149,30 +116,6 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
return super.getPossibleAcceptorConnections();
}
@Override
public EnumWireMaterial getMaterial()
{
return material;
}
public int getTypeID()
{
return material.ordinal();
}
public void setDye(int dye)
{
dyeID = dye;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
public void setMaterialFromID(int id)
{
material = EnumWireMaterial.values()[id];
}
@Override
public String getType()
{
@ -214,20 +157,6 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
return collisionBoxes;
}
@Override
public Iterable<ItemStack> getDrops()
{
List<ItemStack> drops = new ArrayList<ItemStack>();
drops.add(pickItem(null));
if (isInsulated)
{
drops.add(new ItemStack(Block.cloth, 1, BlockColored.getBlockFromDye(dyeID)));
}
return drops;
}
@Override
public float getStrength(MovingObjectPosition hit, EntityPlayer player)
{
@ -261,90 +190,6 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
RenderUtils.renderBlock(sides[6], 0, new Translation(x(), y(), z()), new IconTransformation(renderBlocks.overrideBlockTexture), null);
}
@Override
public void readDesc(MCDataInput packet)
{
setMaterialFromID(packet.readInt());
dyeID = packet.readInt();
isInsulated = packet.readBoolean();
currentWireConnections = packet.readByte();
currentAcceptorConnections = packet.readByte();
if (tile() != null)
{
tile().markRender();
}
}
@Override
public void writeDesc(MCDataOutput packet)
{
packet.writeInt(getTypeID());
packet.writeInt(dyeID);
packet.writeBoolean(isInsulated);
packet.writeByte(currentWireConnections);
packet.writeByte(currentAcceptorConnections);
}
@Override
public void save(NBTTagCompound nbt)
{
super.save(nbt);
nbt.setInteger("typeID", getTypeID());
nbt.setInteger("dyeID", dyeID);
nbt.setBoolean("isInsulated", isInsulated);
}
@Override
public void load(NBTTagCompound nbt)
{
super.load(nbt);
setMaterialFromID(nbt.getInteger("typeID"));
dyeID = nbt.getInteger("dyeID");
isInsulated = nbt.getBoolean("isInsulated");
}
@Override
public ItemStack pickItem(MovingObjectPosition hit)
{
return EnumWireMaterial.values()[getTypeID()].getWire();
}
@Override
public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item)
{
if (item != null)
{
if (item.itemID == Item.dyePowder.itemID && isInsulated())
{
setDye(item.getItemDamage());
return true;
}
else if (item.itemID == Block.cloth.blockID)
{
if (isInsulated() && !world().isRemote)
{
tile().dropItems(Collections.singletonList(new ItemStack(Block.cloth, 1, BlockColored.getBlockFromDye(dyeID))));
}
setInsulated(BlockColored.getDyeFromBlock(item.getItemDamage()));
player.inventory.decrStackSize(player.inventory.currentItem, 1);
return true;
}
else if ((item.itemID == Item.shears.itemID || item.getItem() instanceof ItemShears) && isInsulated())
{
if (!world().isRemote)
{
tile().dropItems(Collections.singletonList(new ItemStack(Block.cloth, 1, BlockColored.getBlockFromDye(dyeID))));
}
setInsulated(false);
return true;
}
}
return false;
}
@Override
public Iterable<Cuboid6> getOcclusionBoxes()
{
@ -363,54 +208,6 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
return isInsulated ? 8 : 6;
}
@Override
public boolean isInsulated()
{
return isInsulated;
}
@Override
public int getInsulationColor()
{
return isInsulated ? dyeID : -1;
}
@Override
public void setInsulationColor(int dye)
{
dyeID = dye;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
@Override
public void setInsulated(boolean insulated)
{
isInsulated = insulated;
dyeID = DEFAULT_COLOR;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
public void setInsulated(int dyeColour)
{
isInsulated = true;
dyeID = dyeColour;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
public void setInsulated()
{
setInsulated(true);
}
@Override
public Cuboid6 getBounds()
{
@ -441,6 +238,12 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
IconHitEffects.addDestroyEffects(this, effectRenderer, false);
}
@Override
public void onPartChanged(TMultiPart part)
{
refresh();
}
@Override
public boolean isBlockedOnSide(ForgeDirection side)
{
@ -450,10 +253,4 @@ public class PartWire extends PartConductor implements TSlottedPart, JNormalOccl
testingSide = null;
return !expandable;
}
@Override
public void onPartChanged(TMultiPart part)
{
refresh();
}
}

View file

@ -0,0 +1,241 @@
package resonantinduction.wire.part;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput;
import codechicken.multipart.NormalOcclusionTest;
import codechicken.multipart.TMultiPart;
import net.minecraft.block.Block;
import net.minecraft.block.BlockColored;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemShears;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MovingObjectPosition;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.wire.EnumWireMaterial;
import resonantinduction.wire.IBlockableConnection;
import resonantinduction.wire.IInsulatedMaterial;
import resonantinduction.wire.IInsulation;
import resonantinduction.wire.IWireMaterial;
import universalelectricity.api.energy.IConductor;
/**
* @author Calclavia
*
*/
public abstract class PartWireBase extends PartConductor implements IInsulatedMaterial, IBlockableConnection
{
public static final int DEFAULT_COLOR = 16;
public int dyeID = DEFAULT_COLOR;
public EnumWireMaterial material = EnumWireMaterial.COPPER;
public boolean isInsulated = false;
public boolean canConnectToType(IConductor wire)
{
if (wire instanceof IWireMaterial)
{
IWireMaterial wireTile = (IWireMaterial) wire;
if (wireTile.getMaterial() != getMaterial())
{
return true;
}
}
if (isInsulated() && wire instanceof IInsulation)
{
IInsulation insulatedTile = (IInsulation) wire;
if ((insulatedTile.isInsulated() && insulatedTile.getInsulationColor() != getInsulationColor() && getInsulationColor() != DEFAULT_COLOR && insulatedTile.getInsulationColor() != DEFAULT_COLOR))
{
return true;
}
}
return false;
}
@Override
public EnumWireMaterial getMaterial()
{
return material;
}
public void setMaterialFromID(int id)
{
material = EnumWireMaterial.values()[id];
}
public int getMaterialID()
{
return material.ordinal();
}
@Override
public boolean isInsulated()
{
return isInsulated;
}
@Override
public int getInsulationColor()
{
return isInsulated ? dyeID : -1;
}
@Override
public void setInsulationColor(int dye)
{
dyeID = dye;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
@Override
public void setInsulated(boolean insulated)
{
isInsulated = insulated;
dyeID = DEFAULT_COLOR;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
public void setInsulated(int dyeColour)
{
isInsulated = true;
dyeID = dyeColour;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
public void setInsulated()
{
setInsulated(true);
}
public void setDye(int dye)
{
dyeID = dye;
refresh();
world().markBlockForUpdate(x(), y(), z());
tile().notifyPartChange(this);
}
/**
* Changes the wire's color.
*/
@Override
public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item)
{
if (item != null)
{
if (item.itemID == Item.dyePowder.itemID && isInsulated())
{
setDye(item.getItemDamage());
return true;
}
else if (item.itemID == Block.cloth.blockID)
{
if (isInsulated() && !world().isRemote)
{
tile().dropItems(Collections.singletonList(new ItemStack(Block.cloth, 1, BlockColored.getBlockFromDye(dyeID))));
}
setInsulated(BlockColored.getDyeFromBlock(item.getItemDamage()));
player.inventory.decrStackSize(player.inventory.currentItem, 1);
return true;
}
else if ((item.itemID == Item.shears.itemID || item.getItem() instanceof ItemShears) && isInsulated())
{
if (!world().isRemote)
{
tile().dropItems(Collections.singletonList(new ItemStack(Block.cloth, 1, BlockColored.getBlockFromDye(dyeID))));
}
setInsulated(false);
return true;
}
}
return false;
}
protected ItemStack getItem()
{
return EnumWireMaterial.values()[getMaterialID()].getWire();
}
@Override
public Iterable<ItemStack> getDrops()
{
List<ItemStack> drops = new ArrayList<ItemStack>();
drops.add(getItem());
if (this.isInsulated)
{
drops.add(new ItemStack(Block.cloth, 1, BlockColored.getBlockFromDye(dyeID)));
}
return drops;
}
@Override
public ItemStack pickItem(MovingObjectPosition hit)
{
return getItem();
}
@Override
public void readDesc(MCDataInput packet)
{
this.setMaterialFromID(packet.readByte());
this.dyeID = packet.readByte();
this.isInsulated = packet.readBoolean();
this.currentWireConnections = packet.readByte();
this.currentAcceptorConnections = packet.readByte();
if (tile() != null)
{
tile().markRender();
}
}
@Override
public void writeDesc(MCDataOutput packet)
{
packet.writeByte((byte) this.getMaterialID());
packet.writeByte((byte) this.dyeID);
packet.writeBoolean(this.isInsulated);
packet.writeByte(this.currentWireConnections);
packet.writeByte(this.currentAcceptorConnections);
}
@Override
public void save(NBTTagCompound nbt)
{
super.save(nbt);
nbt.setInteger("typeID", getMaterialID());
nbt.setBoolean("isInsulated", isInsulated);
nbt.setInteger("dyeID", dyeID);
}
@Override
public void load(NBTTagCompound nbt)
{
super.load(nbt);
setMaterialFromID(nbt.getInteger("typeID"));
dyeID = nbt.getInteger("dyeID");
isInsulated = nbt.getBoolean("isInsulated");
}
}

View file

@ -0,0 +1,475 @@
package resonantinduction.wire.render;
import java.util.Arrays;
import java.util.LinkedList;
import net.minecraft.util.Icon;
import resonantinduction.wire.part.PartLainWire;
import codechicken.lib.lighting.LightModel;
import codechicken.lib.math.MathHelper;
import codechicken.lib.render.CCModel;
import codechicken.lib.render.ColourModifier;
import codechicken.lib.render.ColourMultiplier;
import codechicken.lib.render.IUVTransformation;
import codechicken.lib.render.IVertexModifier;
import codechicken.lib.render.IconTransformation;
import codechicken.lib.render.RenderUtils;
import codechicken.lib.render.UV;
import codechicken.lib.render.UVScale;
import codechicken.lib.render.UVTranslation;
import codechicken.lib.render.Vertex5;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Transformation;
import codechicken.lib.vec.Translation;
import codechicken.lib.vec.Vector3;
/**
*
* @author MrTJP, ChickenBones
*
*/
public class RenderLainWire
{
public static class UVT implements IUVTransformation
{
public Transformation t;
private Vector3 vec = new Vector3();
public UVT(Transformation t)
{
this.t = t;
}
@Override
public void transform(UV uv)
{
vec.set(uv.u, 0, uv.v).apply(t);
uv.set(vec.x, vec.z);
}
}
public static int[] reorientSide = new int[] { 0, 3, 3, 0, 0, 3 };
/*
* All generations are done on side 0 so know that for rotation r
* 0 = side 3 = +Z = SOUTH
* 1 = side 4 = -X = WEST
* 2 = side 2 = -Z = NORTH
* 3 = side 5 = +X = EAST
*/
private static class WireModelGenerator
{
int side;
int tw;
int th;
double w;
double h;
int mask;
int connMask;
int connCount;
CCModel model;
int i = 0;
boolean inv;
public static int countConnections(int connMask)
{
int n = 0;
for (int r = 0; r < 4; r++)
if ((connMask & 1 << r) != 0)
n += 1;
return n;
}
public int numFaces()
{
if (inv)
return 22;
int conns;
if (connCount <= 2)
conns = 2;
else
conns = connCount;
int faces = conns * 3 + 5;
for (int i = 0; i < 4; i++)
if ((mask >> i & 0x11) == 1)
faces++;
return faces;
}
public CCModel generateInvModel(int thickness)
{
return generateModel(modelKey(0, thickness, 0xF0), true);
}
public CCModel generateModel(int key, boolean inv)
{
this.inv = inv;
side = (key >> 8) % 6;
tw = (key >> 8) / 6 + 1;
w = tw / 16D;
th = tw + 1;
h = th / 16D;
mask = key & 0xFF;
connMask = (mask & 0xF0) >> 4 | mask & 0xF;
connCount = countConnections(connMask);
model = CCModel.quadModel(numFaces() * 4);
i = 0;
generateCenter();
for (int r = 0; r < 4; r++)
generateSide(r);
model.apply(Rotation.sideOrientation(side, 0).at(Vector3.center));
return finishModel(model);
}
private void generateSide(int r)
{
int type = mask >> r & 0x11;
Vertex5[] verts;
if (inv)
verts = generateSideInv(r);
else if (connCount == 0)
if (r % 2 == 1)
verts = generateStub(r);
else
verts = generateFlat(r);
else if (connCount == 1)
if (connMask == 1 << (r + 2) % 4)// this side is opposite the one with a connection
verts = generateStub(r);
else
verts = generateSideFromType(type, r);
else
verts = generateSideFromType(type, r);
Transformation t = Rotation.quarterRotations[r].at(Vector3.center);
for (Vertex5 vert : verts)
vert.apply(t);
i = addVerts(model, verts, i);
}
private Vertex5[] generateSideInv(int r)
{
return withBottom(generateStraight(r), 4, 4);
}
private Vertex5[] generateSideFromType(int type, int r)
{
if (type == 0x00)
return generateFlat(r);
else if (type == 0x01)
return generateCorner(r);
else if (type == 0x10)
return generateStraight(r);
else
return generateInternal(r);
}
private Vertex5[] generateFlat(int r)
{
Vertex5[] verts = new Vertex5[] { new Vertex5(0.5 - w, 0, 0.5 + w, 16, 16 + tw), new Vertex5(0.5 + w, 0, 0.5 + w, 16, 16 - tw), new Vertex5(0.5 + w, h, 0.5 + w, 16 - th, 16 - tw), new Vertex5(0.5 - w, h, 0.5 + w, 16 - th, 16 + tw) };
if (Rotation.rotateSide(side, r) % 2 == 0) // red is on the negative side
{
UVT uvt = new UVT(Rotation.quarterRotations[2].at(new Vector3(8, 0, 16)));
for (Vertex5 vert : verts)
vert.apply(uvt);
}
return verts;
}
private Vertex5[] generateStub(int r)
{
Vertex5[] verts = generateExtension(4);
for (int i = 0; i < 4; i++)
verts[i].vec.z -= 0.002;// pull the stub in a little so it
// doesn't z fight with jacketed cables
reflectSide(verts, r);
return verts;
}
private Vertex5[] generateStraight(int r)
{
Vertex5[] verts = generateExtension(8);
reflectSide(verts, r);
return verts;
}
private Vertex5[] generateCorner(int r)
{
Vertex5[] verts = generateExtension(8 + th);
// retexture cap
for (int i = 0; i < 4; i++)
verts[i].apply(new UVTranslation(0, -th));
// add end face extending around block
verts = Arrays.copyOf(verts, 20);
verts[16] = new Vertex5(0.5 - w, 0, 1, 8 - tw, 24 + 2 * th);
verts[17] = new Vertex5(0.5 + w, 0, 1, 8 + tw, 24 + 2 * th);
verts[18] = new Vertex5(0.5 + w, 0, 1 + h, 8 + tw, 24 + th);
verts[19] = new Vertex5(0.5 - w, 0, 1 + h, 8 - tw, 24 + th);
reflectSide(verts, r);
return verts;
}
private Vertex5[] generateInternal(int r)
{
Vertex5[] verts = generateExtension(8);
// retexture cap
verts[0].uv.set(8 + tw, 24);
verts[1].uv.set(8 - tw, 24);
verts[2].uv.set(8 - tw, 24 + tw);
verts[3].uv.set(8 + tw, 24 + tw);
reflectSide(verts, r);
// offset side textures
for (int i = 4; i < 16; i++)
verts[i].apply(new UVTranslation(16, 0));
return verts;
}
private Vertex5[] generateExtension(int tl)
{
double l = tl / 16D;
return new Vertex5[] {// cap
new Vertex5(0.5 - w, 0, 0.5 + l, 8 - tw, 24 + 2 * th), new Vertex5(0.5 + w, 0, 0.5 + l, 8 + tw, 24 + 2 * th), new Vertex5(0.5 + w, h, 0.5 + l, 8 + tw, 24 + th), new Vertex5(0.5 - w, h, 0.5 + l, 8 - tw, 24 + th),
// top
new Vertex5(0.5 - w, h, 0.5 + l, 8 - tw, 16 + tl), new Vertex5(0.5 + w, h, 0.5 + l, 8 + tw, 16 + tl), new Vertex5(0.5 + w, h, 0.5 + w, 8 + tw, 16 + tw), new Vertex5(0.5 - w, h, 0.5 + w, 8 - tw, 16 + tw),
// left
new Vertex5(0.5 - w, 0, 0.5 + w, 0, 16 + tw), new Vertex5(0.5 - w, 0, 0.5 + l, 0, 16 + tl), new Vertex5(0.5 - w, h, 0.5 + l, th, 16 + tl), new Vertex5(0.5 - w, h, 0.5 + w, th, 16 + tw),
// right
new Vertex5(0.5 + w, 0, 0.5 + l, 16, 16 + tl), new Vertex5(0.5 + w, 0, 0.5 + w, 16, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + w, 16 - th, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + l, 16 - th, 16 + tl) };
}
private void generateCenter()
{
int tex;// 0 = straight n/s, 1 = straight e/w, 2 = circle
if (connCount == 0)
tex = 1;
else if (connCount == 1)
tex = (connMask & 5) != 0 ? 0 : 1;// if there is one connection, and it is
// north/south then north/south, otherwise
// east/west
else if (connMask == 5)
tex = 0;
else if (connMask == 10)
tex = 1;
else
tex = 2;
Vertex5[] verts = new Vertex5[] { new Vertex5(0.5 - w, h, 0.5 + w, 8 - tw, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + w, 8 + tw, 16 + tw), new Vertex5(0.5 + w, h, 0.5 - w, 8 + tw, 16 - tw), new Vertex5(0.5 - w, h, 0.5 - w, 8 - tw, 16 - tw) };
if (tex == 0 || tex == 1)
tex = (tex + reorientSide[side]) % 2;
int r = reorientSide[side];
if (tex == 1)
r += 3;
if (r != 0)
{
IUVTransformation uvt = new UVT(Rotation.quarterRotations[r % 4].at(new Vector3(8, 0, 16)));
for (Vertex5 vert : verts)
vert.apply(uvt);
}
if (tex == 2)
{// circle (translate across to u = 24)
UVTranslation uvt = new UVTranslation(16, 0);
for (Vertex5 vert : verts)
vert.apply(uvt);
}
if (inv)
verts = withBottom(verts, 0, 4);
i = addVerts(model, verts, i);
}
private static UVT sideReflect = new UVT(Rotation.quarterRotations[2].at(new Vector3(8, 0, 16)));
private void reflectSide(Vertex5[] verts, int r)
{
if ((r + reorientSide[side]) % 4 >= 2)// rotate the texture about
// the y center
for (Vertex5 vert : verts)
vert.apply(sideReflect);
}
/**
* Returns a copy of vertices with the bottom face added at the start.
*
* @param start The index of the first vertex making up the top face
* @param count The number of vertices making up the top face
*/
private Vertex5[] withBottom(Vertex5[] verts, int start, int count)
{
Vertex5[] i_verts = new Vertex5[verts.length + count];
// add the bottom face, just a copy of the top, rotated about the z
// axis
Transformation r = new Rotation(MathHelper.pi, 0, 0, 1).at(new Vector3(0.5, h / 2, 0));
for (int i = 0; i < count; i++)
i_verts[i] = verts[i + start].copy().apply(r);
System.arraycopy(verts, 0, i_verts, count, verts.length);
return i_verts;
}
}
/**
* Array of all built models. These will be generated on demand.
*/
public static CCModel[] wireModels = new CCModel[3 * 6 * 256];
public static CCModel[] invModels = new CCModel[3];
private static WireModelGenerator gen_inst = new WireModelGenerator();
/**
* Puts verts into model m starting at index k
*/
public static int addVerts(CCModel m, Vertex5[] verts, int k)
{
for (int i = 0; i < verts.length; i++)
m.verts[k + i] = verts[i];
return k + verts.length;
}
public static CCModel finishModel(CCModel m)
{
m.apply(new UVScale(1 / 32D));
m.shrinkUVs(0.0005);
m.computeNormals();
m.computeLighting(LightModel.standardLightModel);
return m;
}
/**
* Returns a tightly packed unique index for the specific model represented
* by this wire. The mask is split into 3 sections the combination of
* corresponding bits from the two lowest nybbles gives the connection type
* in that direction.
* 00 = none
* 01 = corner
* 10 = straight
* 11 = internal The
* second byte contains the thickness*6+side
*
* @param side The side the wire is attached to
* @param thickness The thickness of the wire -1 in 1/8th blocks. Supported
* values 0, 1, 2
* @param connMap The connection mask of the wire
*/
public static int modelKey(int side, int thickness, int connMap)
{
int key = connMap & 0xFF;// take the straight and corner connections
int renderCorner = connMap >> 20 & 0xF;
key |= (renderCorner ^ key & 0xF) << 4;// any corner connections that aren't rendered
// convert to straight
key &= ~0xF | renderCorner;// set corners to renderCorners
int internal = (connMap & 0xF00) >> 8;// internal connections
key |= internal << 4 | internal;// if internal is set, set both straight and corner to 1
key |= side + thickness * 6 << 8;// add side and thickness
return key;
}
public static int modelKey(PartLainWire w)
{
return modelKey(w.side, w.getThickness(), w.connMap);
}
public static CCModel getOrGenerateModel(int key)
{
CCModel m = wireModels[key];
if (m == null)
wireModels[key] = m = gen_inst.generateModel(key, false);
return m;
}
public static void render(PartLainWire w, Vector3 pos)
{
IVertexModifier m = w.getColour() == -1 ? ColourModifier.instance : new ColourMultiplier(w.getColour());
getOrGenerateModel(modelKey(w)).render(new Translation(pos), new IconTransformation(w.getIcon()), m);
}
public static void renderInv(int thickness, Transformation t, Icon icon)
{
CCModel m = invModels[thickness];
if (m == null)
invModels[thickness] = m = gen_inst.generateInvModel(thickness);
m.render(t, new IconTransformation(icon));
}
public static void renderBreakingOverlay(Icon icon, PartLainWire wire)
{
int key = modelKey(wire);
int side = (key >> 8) % 6;
double w = ((key >> 8) / 6 + 1) / 16D;
double h = w + 1 / 16D;
int mask = key & 0xFF;
int connMask = (mask & 0xF0) >> 4 | mask & 0xF;
int connCount = WireModelGenerator.countConnections(connMask);
LinkedList<Cuboid6> boxes = new LinkedList<Cuboid6>();
boxes.add(new Cuboid6(0.5 - w, 0, 0.5 - w, 0.5 + w, h, 0.5 + w).apply(Rotation.sideRotations[side].at(Vector3.center)));// center
for (int r = 0; r < 4; r++)
{
int length;
if (connCount == 0)
{
if (r % 2 == 1)
length = 4;
else
length = 0;
}
else if (connCount == 1)
{
if (connMask == 1 << (r + 2) % 4)// this side is opposite the one with a connection
length = 4;
else if (connMask == 1 << r)
length = 8;
else
length = 0;
}
else
length = (connMask & 1 << r) != 0 ? 8 : 0;
if (length > 0)
{
double l = length / 16D;
boxes.add(new Cuboid6(0.5 - w, 0, 0.5 + w, 0.5 + w, h, 0.5 + l).apply(Rotation.sideOrientation(side, r).at(Vector3.center)));
}
}
for (Cuboid6 box : boxes)
RenderUtils.renderBlock(box, 0, new Translation(wire.x(), wire.y(), wire.z()), new IconTransformation(icon), null);
}
}

View file

@ -1,4 +1,4 @@
package resonantinduction.render;
package resonantinduction.wire.render;
import java.nio.FloatBuffer;
import java.util.Map;
@ -12,8 +12,9 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import resonantinduction.ResonantInduction;
import resonantinduction.wire.PartConductor;
import resonantinduction.wire.PartWire;
import resonantinduction.render.InvertX;
import resonantinduction.wire.part.PartConductor;
import resonantinduction.wire.part.PartWire;
import universalelectricity.api.vector.Vector3;
import codechicken.lib.colour.Colour;
import codechicken.lib.colour.ColourRGBA;
@ -40,6 +41,7 @@ public class RenderPartWire
public static final Map<String, CCModel> models;
public static final Map<String, CCModel> shinyModels;
public static Icon wireIcon;
public static Icon lainWireIcon;
public static Icon insulationIcon;
public static Icon breakIcon;
public static FloatBuffer location = BufferUtils.createFloatBuffer(4);
@ -134,6 +136,7 @@ public class RenderPartWire
public static void registerIcons(IconRegister iconReg)
{
wireIcon = iconReg.registerIcon(ResonantInduction.PREFIX + "models/wire");
lainWireIcon = iconReg.registerIcon(ResonantInduction.PREFIX + "models/lainWire");
insulationIcon = iconReg.registerIcon(ResonantInduction.PREFIX + "models/insulation" + (ResonantInduction.LO_FI_INSULATION ? "tiny" : ""));
breakIcon = iconReg.registerIcon(ResonantInduction.PREFIX + "wire");
}
@ -146,10 +149,13 @@ public class RenderPartWire
CCRenderState.setBrightness(wire.world(), wire.x(), wire.y(), wire.z());
renderSide(ForgeDirection.UNKNOWN, wire);
byte renderSides = wire.getAllCurrentConnections();
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
if (PartConductor.connectionMapContainsSide(renderSides, side))
{
renderSide(side, wire);
}
}
}
@ -157,9 +163,9 @@ public class RenderPartWire
{
String name = side.name().toLowerCase();
name = name.equals("unknown") ? "center" : name;
Vector3 materialColour = wire.getMaterial().color;
Colour colour = new ColourRGBA(materialColour.x, materialColour.y, materialColour.z, 1);
Colour colour = wire.getMaterial().color;
renderPart(wireIcon, models.get(name), wire.x(), wire.y(), wire.z(), colour);
if (wire.isInsulated())
{
Vector3 vecColour = ResonantInduction.DYE_COLORS[wire.dyeID];
@ -172,7 +178,6 @@ public class RenderPartWire
{
String name = side.name().toLowerCase();
name = name.equals("unknown") ? "center" : name;
Vector3 materialColour = wire.getMaterial().color;
renderPartShine(shinyModels.get(name));
}