Start work on multipart integration. Needs some edits to UE to not crash when placing a wire next to an old wire.

Won't PR to UE yet in case CB can apply a fix for it to stop it being an issue. Might push the UE changes to my github.
This commit is contained in:
Ben Spiers 2013-09-17 04:20:18 +01:00
parent 7d996229d7
commit 4ba7492601
7 changed files with 862 additions and 0 deletions

View file

@ -0,0 +1,28 @@
package resonantinduction;
import resonantinduction.wire.multipart.PartWire;
import codechicken.multipart.MultiPartRegistry;
import codechicken.multipart.MultiPartRegistry.IPartFactory;
import codechicken.multipart.MultipartGenerator;
import codechicken.multipart.TMultiPart;
public class MultipartRI implements IPartFactory
{
@Override
public TMultiPart createPart(String name, boolean client)
{
if (name == "resonant_induction_wire")
return new PartWire();
return null;
}
public void init()
{
MultiPartRegistry.registerParts(this, new String[]{"resonant_induction_wire"});
MultipartGenerator.registerPassThroughInterface("universalelectricity.core.block.IConductor");
//MultipartGenerator.registerPassThroughInterface("ic2.api.energy.tile.IEnergySink");
MultipartGenerator.registerPassThroughInterface("buildcraft.api.power.IPowerReceptor");
MultipartGenerator.registerPassThroughInterface("resonantinduction.base.IPacketReceiver");
}
}

View file

@ -0,0 +1,135 @@
package resonantinduction.render;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import codechicken.multipart.TMultiPart;
import resonantinduction.ResonantInduction;
import resonantinduction.model.ModelInsulation;
import resonantinduction.model.ModelWire;
import resonantinduction.wire.EnumWireMaterial;
import resonantinduction.wire.multipart.PartWire;
import universalelectricity.core.vector.Vector3;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* TODO: Use ISBRH.
*
* @author Calclavia
*
*/
@SideOnly(Side.CLIENT)
public class RenderWirePart
{
private static final ResourceLocation WIRE_TEXTURE = new ResourceLocation(ResonantInduction.DOMAIN, ResonantInduction.MODEL_TEXTURE_DIRECTORY + "wire.png");
private static final ResourceLocation INSULATION_TEXTURE = new ResourceLocation(ResonantInduction.DOMAIN, ResonantInduction.MODEL_TEXTURE_DIRECTORY + "insulation.png");
public static final ModelWire WIRE_MODEL = new ModelWire();
public static final ModelInsulation INSULATION_MODEL = new ModelInsulation();
public void renderModelAt(PartWire part, double x, double y, double z, float f)
{
if (part != null)
{
GL11.glPushMatrix();
GL11.glTranslatef((float) x + 0.5F, (float) y + 1.5F, (float) z + 0.5F);
GL11.glScalef(1, -1, -1);
EnumWireMaterial material = part.getMaterial();
// Texture file
FMLClientHandler.instance().getClient().renderEngine.bindTexture(WIRE_TEXTURE);
GL11.glColor4d(material.color.x, material.color.y, material.color.z, 1);
part.adjacentConnections = null;
TileEntity[] adjacentConnections = part.getAdjacentConnections();
if (adjacentConnections != null)
{
if (adjacentConnections[0] != null)
{
WIRE_MODEL.renderBottom();
}
if (adjacentConnections[1] != null)
{
WIRE_MODEL.renderTop();
}
if (adjacentConnections[2] != null)
{
WIRE_MODEL.renderBack();
}
if (adjacentConnections[3] != null)
{
WIRE_MODEL.renderFront();
}
if (adjacentConnections[4] != null)
{
WIRE_MODEL.renderLeft();
}
if (adjacentConnections[5] != null)
{
WIRE_MODEL.renderRight();
}
}
WIRE_MODEL.renderMiddle();
if (part.isInsulated)
{
// Texture file
FMLClientHandler.instance().getClient().renderEngine.bindTexture(INSULATION_TEXTURE);
Vector3 insulationColor = ResonantInduction.DYE_COLORS[part.dyeID];
GL11.glColor4d(insulationColor.x, insulationColor.y, insulationColor.z, 1);
if (adjacentConnections != null)
{
if (adjacentConnections[0] != null)
{
INSULATION_MODEL.renderBottom(0.0625f);
}
if (adjacentConnections[1] != null)
{
INSULATION_MODEL.renderTop(0.0625f);
}
if (adjacentConnections[2] != null)
{
INSULATION_MODEL.renderBack(0.0625f);
}
if (adjacentConnections[3] != null)
{
INSULATION_MODEL.renderFront(0.0625f);
}
if (adjacentConnections[4] != null)
{
INSULATION_MODEL.renderLeft(0.0625f);
}
if (adjacentConnections[5] != null)
{
INSULATION_MODEL.renderRight(0.0625f);
}
}
INSULATION_MODEL.renderMiddle(0.0625f);
}
GL11.glPopMatrix();
}
}
public void renderWirePartAt(TMultiPart part, double var2, double var4, double var6, float var8)
{
this.renderModelAt((PartWire) part, var2, var4, var6, var8);
}
}

View file

@ -0,0 +1,26 @@
package resonantinduction.wire.multipart;
import resonantinduction.ResonantInduction;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.common.Configuration;
import codechicken.lib.vec.BlockCoord;
import codechicken.lib.vec.Vector3;
import codechicken.multipart.JItemMultiPart;
import codechicken.multipart.TMultiPart;
public class ItemPartWire extends JItemMultiPart
{
public ItemPartWire(int id)
{
super(ResonantInduction.CONFIGURATION.get(Configuration.CATEGORY_ITEM, "wireMultipart", id).getInt(id));
}
@Override
public TMultiPart newPart(ItemStack arg0, EntityPlayer arg1, World arg2, BlockCoord arg3, int arg4, Vector3 arg5)
{
return new PartWire();
}
}

View file

@ -0,0 +1,31 @@
package resonantinduction.wire.multipart;
import codechicken.multipart.TMultiPart;
public abstract class PartAdvanced extends TMultiPart
{
protected long ticks = 0;
@Override
public void update()
{
if (this.ticks == 0)
{
this.initiate();
}
if (this.ticks >= Long.MAX_VALUE)
{
this.ticks = 1;
}
this.ticks++;
}
/**
* Called on the TileEntity's first tick.
*/
public void initiate()
{
}
}

View file

@ -0,0 +1,113 @@
package resonantinduction.wire.multipart;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.block.IConductor;
import universalelectricity.core.block.IConnector;
import universalelectricity.core.block.INetworkProvider;
import universalelectricity.core.electricity.NetworkLoader;
import universalelectricity.core.grid.IElectricityNetwork;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
public abstract class PartConductor extends PartAdvanced implements IConductor
{
private IElectricityNetwork network;
public TileEntity[] adjacentConnections = null;
@Override
public void preRemove()
{
if (!this.world().isRemote && this.getTile() instanceof IConductor)
{
this.getNetwork().split((IConductor)this.getTile());
}
super.preRemove();
}
@Override
public boolean doesTick()
{
return false;
}
@Override
public IElectricityNetwork getNetwork()
{
if (this.network == null && this.getTile() instanceof IConductor)
{
this.setNetwork(NetworkLoader.getNewNetwork((IConductor)this.getTile()));
}
return this.network;
}
@Override
public void setNetwork(IElectricityNetwork network)
{
this.network = network;
}
@Override
public void refresh()
{
if (!this.world().isRemote)
{
this.adjacentConnections = null;
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tileEntity = VectorHelper.getConnectorFromSide(this.world(), new Vector3(tile()), side);
if (tileEntity != null)
{
if (tileEntity.getClass() == tile().getClass() && tileEntity instanceof INetworkProvider)
{
this.getNetwork().merge(((INetworkProvider) tileEntity).getNetwork());
}
}
}
this.getNetwork().refresh();
}
}
@Override
public TileEntity[] getAdjacentConnections()
{
/**
* Cache the adjacentConnections.
*/
if (this.adjacentConnections == null)
{
this.adjacentConnections = new TileEntity[6];
for (byte i = 0; i < 6; i++)
{
ForgeDirection side = ForgeDirection.getOrientation(i);
TileEntity tileEntity = VectorHelper.getConnectorFromSide(this.world(), new Vector3(tile()), side);
if (tileEntity instanceof IConnector)
{
if (((IConnector) tileEntity).canConnect(side.getOpposite()))
{
this.adjacentConnections[i] = tileEntity;
}
}
}
}
return this.adjacentConnections;
}
@Override
public boolean canConnect(ForgeDirection direction)
{
return true;
}
}

View file

@ -0,0 +1,205 @@
package resonantinduction.wire.multipart;
import java.util.HashSet;
import java.util.Set;
import universalelectricity.compatibility.Compatibility;
import universalelectricity.core.block.IConnector;
import universalelectricity.core.electricity.ElectricityPack;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.MinecraftForge;
import ic2.api.energy.event.EnergyTileLoadEvent;
import ic2.api.energy.event.EnergyTileUnloadEvent;
import ic2.api.energy.tile.IEnergyAcceptor;
import ic2.api.energy.tile.IEnergyEmitter;
import ic2.api.energy.tile.IEnergySink;
import ic2.api.energy.tile.IEnergyTile;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.power.PowerHandler;
import buildcraft.api.power.PowerHandler.PowerReceiver;
import buildcraft.api.power.PowerHandler.Type;
public abstract class PartUniversalConductor extends PartConductor implements IEnergySink, IPowerReceptor
{
protected boolean isAddedToEnergyNet;
public PowerHandler powerHandler;
public float buildcraftBuffer = Compatibility.BC3_RATIO * 50;
public PartUniversalConductor()
{
this.powerHandler = new PowerHandler(this, Type.PIPE);
this.powerHandler.configure(0, this.buildcraftBuffer, this.buildcraftBuffer, this.buildcraftBuffer * 2);
this.powerHandler.configurePowerPerdition(0, 0);
}
@Override
public TileEntity[] getAdjacentConnections()
{
if (this.adjacentConnections == null)
{
this.adjacentConnections = new TileEntity[6];
for (byte i = 0; i < 6; i++)
{
ForgeDirection side = ForgeDirection.getOrientation(i);
TileEntity tileEntity = VectorHelper.getTileEntityFromSide(this.world(), new Vector3(tile()), side);
if (tileEntity instanceof IConnector)
{
if (((IConnector) tileEntity).canConnect(side.getOpposite()))
{
this.adjacentConnections[i] = tileEntity;
}
}
else if (Compatibility.isIndustrialCraft2Loaded() && tileEntity instanceof IEnergyTile)
{
if (tileEntity instanceof IEnergyAcceptor)
{
if (((IEnergyAcceptor) tileEntity).acceptsEnergyFrom(tile(), side.getOpposite()))
{
this.adjacentConnections[i] = tileEntity;
continue;
}
}
if (tileEntity instanceof IEnergyEmitter)
{
if (((IEnergyEmitter) tileEntity).emitsEnergyTo(tileEntity, side.getOpposite()))
{
this.adjacentConnections[i] = tileEntity;
continue;
}
}
this.adjacentConnections[i] = tileEntity;
}
else if (Compatibility.isBuildcraftLoaded() && tileEntity instanceof IPowerReceptor)
{
this.adjacentConnections[i] = tileEntity;
}
}
}
return this.adjacentConnections;
}
/*
* @Override public boolean canUpdate() { return !this.isAddedToEnergyNet; }
*/
@Override
public void update()
{
if (!this.world().isRemote)
{
if (!this.isAddedToEnergyNet)
{
this.initIC();
}
}
}
@Override
public void onWorldSeparate()
{
this.unloadTileIC2();
super.onWorldSeparate();
}
@Override
public void onChunkUnload()
{
this.unloadTileIC2();
super.onChunkUnload();
}
protected void initIC()
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
}
this.isAddedToEnergyNet = true;
}
private void unloadTileIC2()
{
if (this.isAddedToEnergyNet && this.world() != null)
{
if (Compatibility.isIndustrialCraft2Loaded())
{
MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
}
this.isAddedToEnergyNet = false;
}
}
@Override
public double demandedEnergyUnits()
{
if (this.getNetwork() == null)
{
return 0.0;
}
return this.getNetwork().getRequest(tile()).getWatts() * Compatibility.TO_IC2_RATIO;
}
@Override
public double injectEnergyUnits(ForgeDirection directionFrom, double amount)
{
TileEntity tile = VectorHelper.getTileEntityFromSide(this.world(), new Vector3(tile()), directionFrom);
ElectricityPack pack = ElectricityPack.getFromWatts((float) (amount * Compatibility.IC2_RATIO), 120);
return this.getNetwork().produce(pack, tile(), tile) * Compatibility.TO_IC2_RATIO;
}
@Override
public int getMaxSafeInput()
{
return Integer.MAX_VALUE;
}
@Override
public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction)
{
return true;
}
/**
* BuildCraft functions
*/
@Override
public PowerReceiver getPowerReceiver(ForgeDirection side)
{
return this.powerHandler.getPowerReceiver();
}
@Override
public void doWork(PowerHandler workProvider)
{
Set<TileEntity> ignoreTiles = new HashSet<TileEntity>();
ignoreTiles.add(tile());
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tile = new Vector3(tile()).modifyPositionFromSide(direction).getTileEntity(this.world());
ignoreTiles.add(tile);
}
ElectricityPack pack = ElectricityPack.getFromWatts(workProvider.useEnergy(0, this.getNetwork().getRequest(tile()).getWatts() * Compatibility.TO_BC_RATIO, true) * Compatibility.BC3_RATIO, 120);
this.getNetwork().produce(pack, ignoreTiles.toArray(new TileEntity[0]));
}
@Override
public World getWorld()
{
return world();
}
}

View file

@ -0,0 +1,324 @@
package resonantinduction.wire.multipart;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import resonantinduction.base.IPacketReceiver;
import resonantinduction.render.RenderWirePart;
import resonantinduction.wire.EnumWireMaterial;
import resonantinduction.wire.TileEntityWire;
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.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraft.util.MovingObjectPosition;
import net.minecraftforge.common.ForgeDirection;
import com.google.common.io.ByteArrayDataInput;
import universalelectricity.compatibility.Compatibility;
import universalelectricity.core.block.INetworkProvider;
import universalelectricity.core.vector.Vector3;
import universalelectricity.core.vector.VectorHelper;
import buildcraft.api.power.PowerHandler;
import codechicken.lib.raytracer.IndexedCuboid6;
import codechicken.lib.vec.Cuboid6;
import codechicken.microblock.IHollowConnect;
import codechicken.multipart.JNormalOcclusion;
import codechicken.multipart.NormalOcclusionTest;
import codechicken.multipart.PartMap;
import codechicken.multipart.TMultiPart;
import codechicken.multipart.TNormalOcclusion;
import codechicken.multipart.TSlottedPart;
import codechicken.multipart.TileMultipart;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PartWire extends PartUniversalConductor implements IPacketReceiver, TSlottedPart, JNormalOcclusion, IHollowConnect
{
public static final int DEFAULT_COLOR = 16;
public int dyeID = DEFAULT_COLOR;
public boolean isInsulated = false;
public static RenderWirePart renderer = new RenderWirePart();
public static IndexedCuboid6[] sides = new IndexedCuboid6[7];
/** Client Side Connection Check */
public boolean isTick = false;
static {
sides[0] = new IndexedCuboid6(0, new Cuboid6(0.3, 0.0, 0.3, 0.7, 0.3, 0.7));
sides[1] = new IndexedCuboid6(1, new Cuboid6(0.3, 0.7, 0.3, 0.7, 1.0, 0.7));
sides[2] = new IndexedCuboid6(2, new Cuboid6(0.3, 0.3, 0.0, 0.7, 0.7, 0.3));
sides[3] = new IndexedCuboid6(3, new Cuboid6(0.3, 0.3, 0.7, 0.7, 0.7, 1.0));
sides[4] = new IndexedCuboid6(4, new Cuboid6(0.0, 0.3, 0.3, 0.3, 0.7, 0.7));
sides[5] = new IndexedCuboid6(5, new Cuboid6(0.7, 0.3, 0.3, 1.0, 0.7, 0.7));
sides[6] = new IndexedCuboid6(6, new Cuboid6(0.3, 0.3, 0.3, 0.7, 0.7, 0.7));
}
@Override
public boolean canConnect(ForgeDirection direction)
{
if (this.world().isBlockIndirectlyGettingPowered(this.x(), this.y(), this.z()))
{
return false;
}
Vector3 connectPos = new Vector3(tile()).modifyPositionFromSide(direction);
if (connectPos.getTileEntity(this.world()) instanceof TileEntityWire)
{
TileEntityWire tileWire = (TileEntityWire) connectPos.getTileEntity(this.world());
if ((tileWire.isInsulated && this.isInsulated && tileWire.dyeID != this.dyeID && this.dyeID != DEFAULT_COLOR && tileWire.dyeID != DEFAULT_COLOR) || connectPos.getBlockMetadata(this.world()) != this.getTypeID())
{
return false;
}
}
return true;
}
@Override
public void refresh()
{
if (!this.world().isRemote)
{
this.adjacentConnections = null;
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
if (this.canConnect(side.getOpposite()))
{
TileEntity tileEntity = VectorHelper.getConnectorFromSide(this.world(), new Vector3(tile()), side);
if (tileEntity != null)
{
if (tileEntity.getClass().isInstance(this) && tileEntity instanceof INetworkProvider)
{
this.getNetwork().merge(((INetworkProvider) tileEntity).getNetwork());
}
}
}
}
this.getNetwork().refresh();
}
}
@Override
public float getResistance()
{
return getMaterial().resistance;
}
@Override
public float getCurrentCapacity()
{
return getMaterial().maxAmps;
}
public EnumWireMaterial getMaterial()
{
return EnumWireMaterial.values()[this.getTypeID()];
}
public int getTypeID()
{
return this.world().getBlockMetadata(this.x(), this.y(), this.z());
}
/**
* @param dyeID
*/
public void setDye(int dyeID)
{
this.dyeID = dyeID;
this.refresh();
this.world().markBlockForUpdate(this.x(), this.y(), this.z());
}
public void setInsulated()
{
this.isInsulated = true;
this.refresh();
this.world().markBlockForUpdate(this.x(), this.y(), this.z());
((TileMultipart)this.getTile()).notifyPartChange(this);
}
/*
@Override
public Packet getDescriptionPacket()
{
return PacketHandler.getTileEntityPacket(tile(), this.isInsulated, this.dyeID, this instanceof TileEntityTickWire);
}
*/
@Override
public void handle(ByteArrayDataInput input)
{
try
{
this.isInsulated = input.readBoolean();
this.dyeID = input.readInt();
this.isTick = input.readBoolean();
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* Reads a tile entity from NBT.
*/
@Override
public void load(NBTTagCompound nbt)
{
super.load(nbt);
this.dyeID = nbt.getInteger("dyeID");
this.isInsulated = nbt.getBoolean("isInsulated");
}
/**
* Furnace connection for tick wires
*/
@Override
public TileEntity[] getAdjacentConnections()
{
super.getAdjacentConnections();
if (this.isTick)
{
for (byte i = 0; i < 6; i++)
{
ForgeDirection side = ForgeDirection.getOrientation(i);
TileEntity tileEntity = VectorHelper.getTileEntityFromSide(this.world(), new Vector3(tile()), side);
if (tileEntity instanceof TileEntityFurnace)
{
this.adjacentConnections[i] = tileEntity;
}
}
}
return this.adjacentConnections;
}
/**
* Writes a tile entity to NBT.
*/
@Override
public void save(NBTTagCompound nbt)
{
super.save(nbt);
nbt.setInteger("dyeID", this.dyeID);
nbt.setBoolean("isInsulated", this.isInsulated);
}
@Override
public ArrayList getNetworkedData(ArrayList data)
{
return null;
}
@Override
public void doWork(PowerHandler workProvider)
{
this.buildcraftBuffer = Compatibility.BC3_RATIO * 25 * this.getMaterial().maxAmps;
this.powerHandler.configure(0, this.buildcraftBuffer, this.buildcraftBuffer, this.buildcraftBuffer * 2);
super.doWork(workProvider);
}
@Override
public Iterable<IndexedCuboid6> getSubParts()
{
Set<IndexedCuboid6> subParts = new HashSet<IndexedCuboid6>();
if(getTile() != null)
{
TileEntity[] connections = getAdjacentConnections();
for(ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
int ord = side.ordinal();
if(connections[ord] != null) subParts.add(sides[ord]);
}
}
subParts.add(sides[6]);
return subParts;
}
@Override
public Iterable<Cuboid6> getCollisionBoxes()
{
Set<Cuboid6> collisionBoxes = new HashSet<Cuboid6>();
collisionBoxes.addAll((Collection<? extends Cuboid6>) getSubParts());
return collisionBoxes;
}
@Override
public String getType()
{
return "resonant_induction_wire";
}
@Override
public Iterable<ItemStack> getDrops()
{
return null;
}
@Override
@SideOnly(Side.CLIENT)
public void renderDynamic(codechicken.lib.vec.Vector3 pos, float frame, int pass)
{
renderer.renderWirePartAt(this, pos.x, pos.y, pos.z, frame);
}
@Override
public Iterable<Cuboid6> getOcclusionBoxes()
{
return getCollisionBoxes();
}
@Override
public boolean occlusionTest(TMultiPart other)
{
return NormalOcclusionTest.apply(this, other);
}
@Override
public int getSlotMask()
{
return PartMap.CENTER.mask;
}
@Override
public int getHollowSize()
{
return this.isInsulated ? 8 : 6;
}
@Override
public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item)
{
if (item != null)
{
if (item.itemID == Item.dyePowder.itemID)
{
setDye(item.getItemDamage());
return true;
}
else if (item.itemID == Block.cloth.blockID && !isInsulated)
{
setInsulated();
setDye(BlockColored.getDyeFromBlock(item.getItemDamage()));
player.inventory.decrStackSize(player.inventory.currentItem, 1);
return true;
}
}
return false;
}
}