if(!(createNewTileEntity(null, 0) instanceof MultiColisionProvider))thrownew IllegalStateException("BlockContainerMultiColision has to be provided with a TileEntity that implements MultiColisionProvider class!");
@Override
public Packet getDescriptionPacket(){
return null;
}
public interface MultiColisionProvider {
}
public void onDataPacket(){
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
markDirty();
}
public boolean num1 = false;
public boolean num2 = false;
public boolean num3 = false;
public boolean num4 = false;
public boolean num5 = false;
public boolean num6 = false;
public void checkForNeighbors(World world, int x, int y, int z) {
if (world.getBlock(x - 1, y, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num1 = true;
System.out.println("tested block left true");
}else{
num1 = false;
}
if (world.getBlock(x + 1, y, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num2 = true;
System.out.println("tested block right true");
}else{
num2 = false;
}
if (world.getBlock(x, y, z - 1) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num3 = true;
System.out.println("tested block front true");
}else{
num3 = false;
}
if (world.getBlock(x, y, z + 1) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num4 = true;
System.out.println("tested block back true");
}else{
num4 = false;
}
if (world.getBlock(x, y + 1, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num5 = true;
System.out.println("tested block top true");
}else{
num5 = false;
}
if (world.getBlock(x, y - 1, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num6 = true;
System.out.println("tested block bottom true");
}else{
num6 = false;
}
sync();
}
public void onBlockAdded(World world, int x, int y, int z) {
if (world.getBlock(x - 1, y, z) == GunnCraftBlocks.Pipe){
num1 = true;
System.out.println("tested block left true");
}else{
num1 = false;
}
if (world.getBlock(x + 1, y, z) == GunnCraftBlocks.Pipe){
num2 = true;
System.out.println("tested block right true");
}else{
num2 = false;
}
if (world.getBlock(x, y, z - 1) == GunnCraftBlocks.Pipe){
num3 = true;
System.out.println("tested block front true");
}else{
num3 = false;
}
if (world.getBlock(x, y, z + 1) == GunnCraftBlocks.Pipe){
num4 = true;
System.out.println("tested block back true");
}else{
num4 = false;
}
if (world.getBlock(x, y + 1, z) == GunnCraftBlocks.Pipe){
num5 = true;
System.out.println("tested block top true");
}else{
num5 = false;
}
if (world.getBlock(x, y - 1, z) == GunnCraftBlocks.Pipe){
num6 = true;
System.out.println("tested block bottom true");
}else{
num6 = false;
}
sync();
}
public void sync() {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(bos);
I could use some help making multiple hit boxes like the ones used in Thermal Expansion on the pipes... because this is exactly what I'm trying to do. Ive just completed rendering the pipe properly with a huge help from andry08. Would I be using IHighlightHandler if so how do you use this?
these images show where I want to add these hit boxes because its dependent on wether there is a pipe that extends in that direction.
The variables aren't returning true, I think the problem may be that in the Pipe Class(just the plain block class) where we call the checkForNeighbors it looks like this
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block par5) {
if (!world.isRemote) {
TileEntityPipe tileEntity = (TileEntityPipe) world.getTileEntity(x, y, z);
if (tileEntity != null) {
tileEntity.checkForNeighbors(world, z, z, z);
}
}
}
where it says tileEntity.checkForNeighbors(world, z , z, z); is it suppose to be tileEntity.checkForNeighbors(world, x, y, z);?
--edit-- OMG THAT WAS IT!!!! the block connects to each other!!!
THANKS SO MUCH!!!! I couldn't get nearly this far with out your help!
how would I run the neighbor check when the world is loaded up(when the world is loaded up no pipes are connecting i have to place a block next to each of them)? I fixed it rendering when the block is placed.
the problem with this new code it that it never actually tests to see if the neighbors are pipes, we changed the function to run a checkForNeighbors that doesn't check the neighbors
this.model.checkForNeighbors(entity);
the TileEntityPipe class is the one that contains the actual checkForNeighbors
0
Went through what you had so far.
Classes I've added or changed:
errors are highlighted in red
BlockContainerMultiColision:
package com.gunnthorian.colision;
import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World
public abstract class BlockContainerMultiColision extends BlockContainer{
protected BlockContainerMultiColision(Material material){
super(material);
if(!(createNewTileEntity(null, 0) instanceof MultiColisionProvider))thrownew IllegalStateException("BlockContainerMultiColision has to be provided with a TileEntity that implements MultiColisionProvider class!");
}
@Override
publicint getRenderType(){return 80;}
@Override
publicboolean isOpaqueCube(){returnfalse;}
publicboolean isFullCube(){
returnfalse;
}
@Override
public MovingObjectPosition collisionRayTrace(World w, intx, inty, intz, Vec3 startVec, Vec3 endVec){
if(!MultiColisionProviderRayTracer.isRayTracing){
intid=MultiColisionProviderRayTracer.getRayTracedBoxId(w, x, y, z, Vec3M.conv(startVec), Vec3M.conv(endVec), getResetBoundsOptionalFix(w, x, y, z));
return MultiColisionProviderRayTracer.results[id];
}else returnsuper.collisionRayTrace(w, x, y, z, startVec, endVec);
}
publicabstract AxisAlignedBB getResetBoundsOptional(World world, intx, inty, intz);
private AxisAlignedBB getResetBoundsOptionalFix(World world, intx, inty, intz){
AxisAlignedBB result=getResetBoundsOptional(world, x, y, z);
if(result == null)returnnull;
result = result.union(new AxisAlignedBB(0, 0, 0, 1, 1, 1));
returnresult;
}
@Override
publicvoid addCollisionBoxesToList(World world, intx, inty, intz, IBlockState state, AxisAlignedBB mask, List list, Entity collidingEntity){
AxisAlignedBB[] a=((MultiColisionProvider)world.getTileEntity(x, y, z)).getActiveBoxes();
for(inti=0;i<a.length;i++){
this.setBlockBounds((float)a.minX,(float)a.minY,(float)a.minZ,(float)a.maxX,(float)a.maxY,(float)a.maxZ);
super.addCollisionBoxesToList(world, x, y, z, state, mask, list, collidingEntity);
}
}
}
MultiColisionProvider:
package com.gunnthorian.colision;
import java.util.*;
import net.minecraft.block.*;
import net.minecraft.tileentity.*;
import net.minecraft.util.*;
import net.minecraft.world.*;
import org.apache.commons.lang3.*;
public interface MultiColisionProvider{
public void getBoxesOnSide(List<AxisAlignedBB> result,int side);
public void getExpectedBoxesOnSide(List<AxisAlignedBB> result,int side);
public AxisAlignedBB getMainBox();
public void setColisionBoxes();
public AxisAlignedBB[] getExpectedColisionBoxes();
public void setPointedBox(AxisAlignedBB box);
public AxisAlignedBB getPointedBox();
public void setPrevPointedBox(AxisAlignedBB box);
public AxisAlignedBB getPrevPointedBox();
public void detectAndSendChanges();
public AxisAlignedBB[] getActiveBoxes();
public AxisAlignedBB[] getBoxes();
public class MultiColisionProviderRayTracer{
private MultiColisionProviderRayTracer(){}
public static boolean isRayTracing=false;
public static MovingObjectPosition[] results={};
public static AxisAlignedBB[] selectedBoxes={};
public static int getRayTracedBoxId(World world, int x, int y, int z, Vec3M startVec, Vec3M endVec,AxisAlignedBB resetBoundsOptional){
TileEntity tester=world.getTileEntity(x, y, z);
if(!(tester instanceof MultiColisionProvider)){
UtilM.println("There is no instance of ISidedColisionProvider at"+"("+ x + "," + y + "," + z + ")!",UtilM.getStackTrace());
return -1;
}
results=new MovingObjectPosition[0];
selectedBoxes=new AxisAlignedBB[0];
isRayTracing=true;
//start
MultiColisionProvider tile=(MultiColisionProvider)tester;
Block block=UtilM.getBlock(world, x, y, z);
AxisAlignedBB[] aciveBoxes=tile.getActiveBoxes();
if(aciveBoxes==null||aciveBoxes.length==0){
//fail switch
UtilM.println("ISidedColisionProviderRayTracer could not resolve a valid box!",UtilM.getStackTrace());
isRayTracing=false;
return -1;
}
for(int i=0;i<aciveBoxes.length;i++){
block.setBlockBounds((float)aciveBoxes.minX,(float)aciveBoxes.minY,(float)aciveBoxes.minZ,(float)aciveBoxes.maxX,(float)aciveBoxes.maxY,(float)aciveBoxes.maxZ);
results=ArrayUtils.add(results, block.collisionRayTrace(world, x, y, z, startVec.conv(), endVec.conv()));
selectedBoxes=ArrayUtils.add(selectedBoxes,aciveBoxes);
}
if(results.length==0){
if(resetBoundsOptional!=null)block.setBlockBounds((float)resetBoundsOptional.minX,(float)resetBoundsOptional.minY,(float)resetBoundsOptional.minZ,(float)resetBoundsOptional.maxX,(float)resetBoundsOptional.maxY,(float)resetBoundsOptional.maxZ);
tile.setPointedBox(null);
isRayTracing=false;
return -1;
}
double smallest=10000;
int id=0;
if(results.length>0){
for(int id1=0;id1<results.length;id1++){
MovingObjectPosition result1=results[id1];
if(result1!=null&&result1.hitVec!=null){
double distance=startVec.conv().distanceTo(result1.hitVec);
if(distance<smallest){
smallest=distance;
id=id1;
}
}
}
}
if(resetBoundsOptional!=null)block.setBlockBounds((float)resetBoundsOptional.minX,(float)resetBoundsOptional.minY,(float)resetBoundsOptional.minZ,(float)resetBoundsOptional.maxX,(float)resetBoundsOptional.maxY,(float)resetBoundsOptional.maxZ);
else if(selectedBoxes.length>0)block.setBlockBounds((float)selectedBoxes[id].minX,(float)selectedBoxes[id].minY,(float)selectedBoxes[id].minZ,(float)selectedBoxes[id].maxX,(float)selectedBoxes[id].maxY,(float)selectedBoxes[id].maxZ);
try{
tile.setPointedBox(selectedBoxes[id]);
}catch(Exception e){
UtilM.println("Error: max value without crash",selectedBoxes.length-1," and the used value is",id);
UtilM.println("selectedBoxes size",selectedBoxes.length,"results size",results.length);
e.printStackTrace();
}
isRayTracing=false;
return id;
}
public static int getPointedId(MultiColisionProvider provider){
if(provider.getPointedBox()!=null){
AxisAlignedBB box1=provider.getPointedBox();
AxisAlignedBB[] boxes=provider.getBoxes();
for(int i=0;i<boxes.length;i++){
AxisAlignedBB box2=provider.getBoxes();
if(UtilM.AxisAlignedBBEqual(box1, box2)){
return i;
}
}
}
return -1;
}
}
}
Im not sure why the VecM have the M, would they work with out it, all of the UtilM have an error would getting rid of the M fix them?
MultiColisionProviderRayTracer: (not sure if this was suppose to be another class)
package com.gunnthorian.colision;
public class MultiColisionProviderRayTracer {
}
TileEntityPipe: (one of my classes, placed > public interface MultiColisionProvider {} < in it)
package com.gunnthorian.block;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import com.gunnthorian.handler.MessageSyncTile;
import com.gunnthorian.handler.MessagesHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import net.minecraft.init.Blocks;
import net.minecraft.network.Packet;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
public class TileEntityPipe extends TileEntity {
@Override
public Packet getDescriptionPacket(){
return null;
}
public interface MultiColisionProvider {
}
public void onDataPacket(){
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
markDirty();
}
public boolean num1 = false;
public boolean num2 = false;
public boolean num3 = false;
public boolean num4 = false;
public boolean num5 = false;
public boolean num6 = false;
public void checkForNeighbors(World world, int x, int y, int z) {
if (world.getBlock(x - 1, y, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num1 = true;
System.out.println("tested block left true");
}else{
num1 = false;
}
if (world.getBlock(x + 1, y, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num2 = true;
System.out.println("tested block right true");
}else{
num2 = false;
}
if (world.getBlock(x, y, z - 1) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num3 = true;
System.out.println("tested block front true");
}else{
num3 = false;
}
if (world.getBlock(x, y, z + 1) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num4 = true;
System.out.println("tested block back true");
}else{
num4 = false;
}
if (world.getBlock(x, y + 1, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num5 = true;
System.out.println("tested block top true");
}else{
num5 = false;
}
if (world.getBlock(x, y - 1, z) == GunnCraftBlocks.Pipe || world.getBlock(x - 1, y, z) == Blocks.chest){
num6 = true;
System.out.println("tested block bottom true");
}else{
num6 = false;
}
sync();
}
public void onBlockAdded(World world, int x, int y, int z) {
if (world.getBlock(x - 1, y, z) == GunnCraftBlocks.Pipe){
num1 = true;
System.out.println("tested block left true");
}else{
num1 = false;
}
if (world.getBlock(x + 1, y, z) == GunnCraftBlocks.Pipe){
num2 = true;
System.out.println("tested block right true");
}else{
num2 = false;
}
if (world.getBlock(x, y, z - 1) == GunnCraftBlocks.Pipe){
num3 = true;
System.out.println("tested block front true");
}else{
num3 = false;
}
if (world.getBlock(x, y, z + 1) == GunnCraftBlocks.Pipe){
num4 = true;
System.out.println("tested block back true");
}else{
num4 = false;
}
if (world.getBlock(x, y + 1, z) == GunnCraftBlocks.Pipe){
num5 = true;
System.out.println("tested block top true");
}else{
num5 = false;
}
if (world.getBlock(x, y - 1, z) == GunnCraftBlocks.Pipe){
num6 = true;
System.out.println("tested block bottom true");
}else{
num6 = false;
}
sync();
}
public void sync() {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(bos);
try {
outputStream.writeInt(this.xCoord);
outputStream.writeInt(this.yCoord);
outputStream.writeInt(this.zCoord);
outputStream.writeBoolean(this.num1);
outputStream.writeBoolean(this.num2);
outputStream.writeBoolean(this.num3);
outputStream.writeBoolean(this.num4);
outputStream.writeBoolean(this.num5);
outputStream.writeBoolean(this.num6);
} catch (Exception ex) {
ex.printStackTrace();
}
if (this.worldObj != null && this.worldObj.provider != null) {
MessagesHandler.dispatcher.sendToAllAround(new MessageSyncTile(bos), new TargetPoint(this.worldObj.provider.dimensionId, this.xCoord, this.yCoord, this.zCoord, 8));
}
}
}
public void recieveSync(boolean par1, boolean par2, boolean par3, boolean par4, boolean par5, boolean par6) {
this.num1 = par1;
this.num2 = par2;
this.num3 = par3;
this.num4 = par4;
this.num5 = par5;
this.num6 = par6;
}
}
Thank you for helping with this, I hope to get it to work
0
yes thats exactly what i need in fact i was just looking at some old posts of your about this very topic of ray tracing, thanks.
0
wait... i know how to set block bounds, but i was trying to have it so that my pipe has multiple block bounds, just making sure were on the same page
0
never mind i fixed the setBlockBounds however there are no extra block bounds when he pipes are connected
package com.gunnthorian.handler;
import com.gunnthorian.block.GunnCraftBlocks;
import com.gunnthorian.block.Pipe;
import com.gunnthorian.block.TileEntityPipe;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.world.World;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
public class EventHandler2{
booleannum1 = false;
booleannum2 = false;
booleannum3 = false;
booleannum4 = false;
booleannum5 = false;
booleannum6 = false;
public void checkForNeighbors(TileEntity rte) {
TileEntityPipe te = (TileEntityPipe)rte;
num1 = te.num1;
num2 = te.num2;
num3 = te.num3;
num4 = te.num4;
num5 = te.num5;
num6 = te.num6;
}
@SubscribeEvent
publicvoid drawSelectionBox(DrawBlockHighlightEvent e) {
System.out.println(num1 + "," + num2 + "," + num3 + "," + num4 + "," + num5 + "," + num6);
if(e.target.typeOfHit == MovingObjectType.BLOCK) {
World world = e.player.worldObj;
Block block = world.getBlock(e.target.blockX, e.target.blockY, e.target.blockZ);
if(world.getBlock(e.target.blockX, e.target.blockY, e.target.blockZ).equals(GunnCraftBlocks.Pipe)) {
TileEntityPipe pipe = (TileEntityPipe) world.getTileEntity(e.target.blockX, e.target.blockY, e.target.blockZ);
if(num1 == true){
System.out.println("front tested true");
floatvar3 = 0.3125F;
block.setBlockBounds(0F, var3, var3, 1.0F - var3, 1.0F - var3, 1.0F - var3);
e.context.drawSelectionBox(e.player, e.target, 0, e.partialTicks);
e.setCanceled(true);
}
if(num2 == true){
System.out.println("back tested true");
floatvar3 = 0.3125F;
block.setBlockBounds(var3, 0F, var3, 1.0F - var3, 1.0F - var3, 1.0F - var3);
e.context.drawSelectionBox(e.player, e.target, 0, e.partialTicks);
e.setCanceled(true);
}
if(num3 == true){
System.out.println("left tested true");
floatvar3 = 0.3125F;
block.setBlockBounds(var3, var3, 0F, 1.0F - var3, 1.0F - var3, 1.0F - var3);
e.context.drawSelectionBox(e.player, e.target, 0, e.partialTicks);
e.setCanceled(true);
}
if(num4 == true){
System.out.println("right tested true");
floatvar3 = 0.3125F;
block.setBlockBounds(var3, var3, var3, 1.0F - var3, 1.0F - var3, 1.0F - var3);
e.context.drawSelectionBox(e.player, e.target, 0, e.partialTicks);
e.setCanceled(true);
}
if(num5 == true){
System.out.println("top tested true");
floatvar3 = 0.3125F;
block.setBlockBounds(var3, var3, var3, 1.0F - var3, 1.0F - var3, 1.0F - var3);
e.context.drawSelectionBox(e.player, e.target, 0, e.partialTicks);
e.setCanceled(true);
}
if(num6 == true){
System.out.println("bottom tested true");
floatvar3 = 0.3125F;
block.setBlockBounds(var3, var3, var3, 1.0F - var3, 1.0F - var3, 1.0F - var3);
e.context.drawSelectionBox(e.player, e.target, 0, e.partialTicks);
e.setCanceled(true);
}
}
}
}
}
0
oh i couldn't import it because there was something already called EventHandler so i had to rename it
in the EventHandler that i made why does it want to create a method for setBlockBounds under the drawSelectionBox?
0
@EventHandler
publicstaticvoid init(FMLInitializationEvent Event){
MessagesHandler.registerPackets();
MinecraftForge.EVENT_BUS.register(new EventHandler());
LanguageRegistry.instance().addStringLocalization("itemGroup.tabGunnCraft", "en_US", "tabgunncraft");
}
error: Cannot instantiate the type Mod.EventHandler
And what do I place in the EventHandler, like how to call the function
drawSelectionBox
0
such as? sorry this is probably something I should know
-- the stuff in the MainRegistry, how do i put it in there?
under init like this? what is the parameter for it?
Pipe.drawSelectionBox();
0
so I added some stuff to the Pipe class:
Pipe class
but none of the iff statements run true
-- I changed all of the if(num1-6 = true) to if(num1-6 == true)
-- the drawSectionBox is never being ran, I placed a System.out.println("ran") but it showed up in console.
0
this goes anywhere in the Pipe class?
0
yeah here Pipe.java
any other code needed?
0
I could use some help making multiple hit boxes like the ones used in Thermal Expansion on the pipes... because this is exactly what I'm trying to do. Ive just completed rendering the pipe properly with a huge help from andry08. Would I be using IHighlightHandler if so how do you use this?
these images show where I want to add these hit boxes because its dependent on wether there is a pipe that extends in that direction.
0
Good timing I fell asleep too
The variables aren't returning true, I think the problem may be that in the Pipe Class(just the plain block class) where we call the checkForNeighbors it looks like this
where it says tileEntity.checkForNeighbors(world, z , z, z); is it suppose to be tileEntity.checkForNeighbors(world, x, y, z);?
--edit-- OMG THAT WAS IT!!!! the block connects to each other!!!
THANKS SO MUCH!!!! I couldn't get nearly this far with out your help!
how would I run the neighbor check when the world is loaded up(when the world is loaded up no pipes are connecting i have to place a block next to each of them)? I fixed it rendering when the block is placed.
0
sounds good to me, but why isn't it rendering properly?
0
the problem with this new code it that it never actually tests to see if the neighbors are pipes, we changed the function to run a checkForNeighbors that doesn't check the neighbors
the TileEntityPipe class is the one that contains the actual checkForNeighbors
0
boolean num1;
boolean num2;
boolean num3;
boolean num4;
boolean num5;
boolean num6;
public void checkForNeighbors(TileEntity te) {
num1 = te.num1;
num2 = te.num2;
num3 = te.num3;
num4 = te.num4;
num5 = te.num5;
num6 = te.num6;
}
error: num1 cannot be resolved or is not a field