Created
June 29, 2018 06:17
-
-
Save Daomephsta/0288c0cd521ba59590cee10c3316e843 to your computer and use it in GitHub Desktop.
Material network for Builder's Drawers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
java.lang.NullPointerException: Unexpected error | |
at daomephsta.buildersdrawers.common.tileentities.MaterialNetwork.merge(MaterialNetwork.java:89) | |
at daomephsta.buildersdrawers.common.tileentities.MaterialNetwork.connect(MaterialNetwork.java:79) | |
at daomephsta.buildersdrawers.common.tileentities.TileEntityBuildersDrawers.connectTo(TileEntityBuildersDrawers.java:41) | |
at daomephsta.buildersdrawers.common.tileentities.MaterialNetwork.merge(MaterialNetwork.java:92) | |
at daomephsta.buildersdrawers.common.tileentities.MaterialNetwork.connect(MaterialNetwork.java:79) | |
at daomephsta.buildersdrawers.common.tileentities.TileEntityBuildersDrawers.connectTo(TileEntityBuildersDrawers.java:41) | |
at daomephsta.buildersdrawers.common.tileentities.TileEntityBuildersDrawers.findNetwork(TileEntityBuildersDrawers.java:67) | |
at daomephsta.buildersdrawers.common.tileentities.TileEntityBuildersDrawers.onBlockPlaced(TileEntityBuildersDrawers.java:46) | |
at daomephsta.buildersdrawers.common.blocks.BlockBuildersDrawers.onBlockPlacedBy(BlockBuildersDrawers.java:46) | |
at net.minecraft.item.ItemBlock.placeBlockAt(ItemBlock.java:205) | |
at com.jaquadro.minecraft.storagedrawers.item.ItemDrawers.placeBlockAt(ItemDrawers.java:44) | |
at net.minecraft.item.ItemBlock.onItemUse(ItemBlock.java:57) | |
at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:201) | |
at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:499) | |
at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1692) | |
at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2379) | |
at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2145) | |
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1933) | |
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1186) | |
at net.minecraft.client.Minecraft.run(Minecraft.java:441) | |
at net.minecraft.client.main.Main.main(Main.java:118) | |
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | |
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) | |
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | |
at java.lang.reflect.Method.invoke(Method.java:498) | |
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) | |
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) | |
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | |
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) | |
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | |
at java.lang.reflect.Method.invoke(Method.java:498) | |
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) | |
at GradleStart.main(GradleStart.java:25) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package daomephsta.buildersdrawers.common.blocks; | |
import com.jaquadro.minecraft.storagedrawers.api.storage.BlockType; | |
import com.jaquadro.minecraft.storagedrawers.api.storage.EnumBasicDrawer; | |
import com.jaquadro.minecraft.storagedrawers.block.BlockDrawers; | |
import com.jaquadro.minecraft.storagedrawers.block.dynamic.StatusModelData; | |
import com.jaquadro.minecraft.storagedrawers.block.tile.TileEntityDrawers; | |
import daomephsta.buildersdrawers.common.BuildersDrawers; | |
import daomephsta.buildersdrawers.common.tileentities.TileEntityBuildersDrawers; | |
import net.minecraft.block.SoundType; | |
import net.minecraft.block.material.Material; | |
import net.minecraft.block.state.BlockStateContainer; | |
import net.minecraft.block.state.IBlockState; | |
import net.minecraft.entity.EntityLivingBase; | |
import net.minecraft.entity.player.EntityPlayer; | |
import net.minecraft.item.ItemStack; | |
import net.minecraft.tileentity.TileEntity; | |
import net.minecraft.util.*; | |
import net.minecraft.util.math.BlockPos; | |
import net.minecraft.util.text.TextComponentString; | |
import net.minecraft.world.IBlockAccess; | |
import net.minecraft.world.World; | |
public class BlockBuildersDrawers extends BlockDrawers | |
{ | |
private final StatusModelData statusModel; | |
private final EnumBasicDrawer drawerType; | |
public BlockBuildersDrawers(EnumBasicDrawer drawerType) | |
{ | |
super(Material.ROCK, "builders_drawers_" + drawerType.getName(), | |
BuildersDrawers.MODID + ".buildersDrawers." + drawerType.getName()); | |
this.drawerType = drawerType; | |
this.statusModel = new StatusModelData(3, | |
new ResourceLocation(BuildersDrawers.MODID, | |
"models/block/dynamic/builders_drawers_" + drawerType.getName() + ".json")); | |
setSoundType(SoundType.STONE); | |
} | |
@Override | |
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase entity, ItemStack itemStack) | |
{ | |
super.onBlockPlacedBy(world, pos, state, entity, itemStack); | |
TileEntityBuildersDrawers drawersTE = (TileEntityBuildersDrawers) world.getTileEntity(pos); | |
drawersTE.onBlockPlaced(world, pos, state, entity, itemStack); | |
} | |
@Override | |
public void breakBlock(World world, BlockPos pos, IBlockState state) | |
{ | |
TileEntityBuildersDrawers drawersTE = (TileEntityBuildersDrawers) world.getTileEntity(pos); | |
drawersTE.onBlockBroken(world, pos, state); | |
super.breakBlock(world, pos, state); | |
} | |
@Override | |
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) | |
{ | |
boolean superResult = super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ); | |
if (!world.isRemote) | |
{ | |
TileEntityBuildersDrawers drawersTE = (TileEntityBuildersDrawers) world.getTileEntity(pos); | |
player.sendStatusMessage(new TextComponentString("Connected to " + drawersTE.getMaterialNetwork().getNetworkID()), true); | |
return false; | |
} | |
return superResult; | |
} | |
@Override | |
public TileEntity createNewTileEntity(World world, int meta) | |
{ | |
return new TileEntityBuildersDrawers(drawerType.getDrawerCount()); | |
} | |
@Override | |
public IBlockState getStateFromMeta(int meta) | |
{ | |
return getDefaultState(); | |
} | |
@Override | |
public int getMetaFromState(IBlockState state) | |
{ | |
return 0; | |
} | |
@Override | |
protected BlockStateContainer createBlockState() | |
{ | |
return new BlockStateContainer(this, FACING); | |
} | |
@Override | |
protected int getDrawerSlot(int drawerCount, int side, float hitX, float hitY, float hitZ) | |
{ | |
if(hitTop(hitY)) return 0; | |
return hitLeft(side, hitX, hitZ) ? 1 : 2; | |
} | |
@Override | |
public boolean isHalfDepth(IBlockState state) | |
{ | |
// Mojang code is wonderful... | |
if(drawerType == null) return false; | |
return drawerType.isHalfDepth(); | |
} | |
@Override | |
public boolean isFullCube (IBlockState state) { | |
return isOpaqueCube(state); | |
} | |
@Override | |
public boolean isOpaqueCube (IBlockState state) | |
{ | |
return !isHalfDepth(state); | |
} | |
@Override | |
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) | |
{ | |
if (isHalfDepth(state)) | |
{ | |
TileEntityDrawers tile = getTileEntity(world, pos); | |
return (tile != null && tile.getDirection() == face.getOpposite().getIndex()); | |
} else | |
return true; | |
} | |
@Override | |
@SuppressWarnings("deprecation") | |
public boolean shouldSideBeRendered (IBlockState state, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { | |
if(isHalfDepth(state)) | |
{ | |
TileEntityDrawers tile = getTileEntity(blockAccess, pos); | |
if (tile != null && tile.getDirection() == side.getIndex()) | |
return true; | |
} | |
return super.shouldSideBeRendered(state, blockAccess, pos, side); | |
} | |
@Override | |
public boolean causesSuffocation (IBlockState state) | |
{ | |
return false; | |
} | |
@Override | |
public BlockType retrimType() | |
{ | |
// Builder's drawers cannot be retrimmed | |
return super.retrimType(); | |
} | |
public EnumBasicDrawer getDrawerType() | |
{ | |
return drawerType; | |
} | |
@Override | |
public StatusModelData getStatusInfo(IBlockState state) | |
{ | |
return statusModel; | |
} | |
@Override | |
public int getDrawerCount(IBlockState state) | |
{ | |
return drawerType.getDrawerCount(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package daomephsta.buildersdrawers.common.tileentities; | |
import java.util.*; | |
import net.minecraft.block.material.Material; | |
import net.minecraft.tileentity.TileEntity; | |
import net.minecraft.util.EnumFacing; | |
import net.minecraft.util.math.BlockPos; | |
import net.minecraft.world.World; | |
public class MaterialNetwork | |
{ | |
private static int nextID = 0; | |
// An ID for debug purposes. Not synced between sides. | |
private final int networkID; | |
private final World world; | |
private BlockPos master; | |
private Material storedMaterial; | |
private int storedQuantity; | |
private Set<BlockPos> nodes = new HashSet<>(); | |
private MaterialNetwork(World world, BlockPos master) | |
{ | |
this.networkID = nextID++; | |
this.world = world; | |
this.master = master; | |
nodes.add(master); | |
} | |
public static MaterialNetwork createSingletonNetwork(World world, BlockPos master) | |
{ | |
return new MaterialNetwork(world, master); | |
} | |
public static MaterialNetwork constructNewNetwork(World world, BlockPos master) | |
{ | |
MaterialNetwork network = new MaterialNetwork(world, master); | |
// Breadth first search | |
Queue<BlockPos> toVisit = new ArrayDeque<>(); | |
Set<BlockPos> visited = new HashSet<>(); | |
toVisit.add(master); | |
while(!toVisit.isEmpty()) | |
{ | |
BlockPos nodePos = toVisit.remove(); | |
for (EnumFacing facing : EnumFacing.values()) | |
{ | |
BlockPos neighbourPos = nodePos.offset(facing); | |
if (visited.contains(neighbourPos)) | |
continue; | |
TileEntity te = world.getTileEntity(neighbourPos); | |
if (te instanceof TileEntityBuildersDrawers) | |
{ | |
((TileEntityBuildersDrawers) te).connectTo(network); | |
toVisit.add(neighbourPos); | |
} | |
} | |
visited.add(nodePos); | |
} | |
return network; | |
} | |
MaterialNetwork connect(BlockPos pos) | |
{ | |
/* Find networks other than this neighbouring the connecting position. | |
* Use a set to avoid duplicates.*/ | |
Collection<MaterialNetwork> otherNetworks = new HashSet<>(); | |
for (EnumFacing facing : EnumFacing.values()) | |
{ | |
BlockPos neighbourPos = pos.offset(facing); | |
TileEntity te = world.getTileEntity(neighbourPos); | |
if (te instanceof TileEntityBuildersDrawers) | |
{ | |
MaterialNetwork network = ((TileEntityBuildersDrawers) te).getMaterialNetwork(); | |
if(network != this) otherNetworks.add(network); | |
} | |
} | |
// If other networks were found, merge them with this network. | |
if(!otherNetworks.isEmpty()) merge(otherNetworks); | |
/* Finally add the new node to the network. This must be done | |
* after merging.*/ | |
nodes.add(pos); | |
//System.out.println(String.format("Connected %s to network %d", pos, networkID)); | |
return this; | |
} | |
private void merge(Collection<MaterialNetwork> otherNetworks) | |
{ | |
for(MaterialNetwork mergingNetwork : otherNetworks) | |
{ | |
for (BlockPos slavePos : mergingNetwork.nodes) | |
{ | |
TileEntityBuildersDrawers te = (TileEntityBuildersDrawers) world.getTileEntity(slavePos); | |
te.connectTo(this); | |
} | |
} | |
} | |
void disconnect(BlockPos pos) | |
{ | |
nodes.remove(pos); | |
// Find neighbouring nodes | |
Collection<BlockPos> neighbouringNodes = new HashSet<>(); | |
for (EnumFacing facing : EnumFacing.values()) | |
{ | |
BlockPos neighbourPos = pos.offset(facing); | |
if (nodes.contains(neighbourPos)) | |
neighbouringNodes.add(neighbourPos); | |
} | |
// If there are multiple neighbours, the network has split. | |
if(neighbouringNodes.size() > 1) | |
{ | |
for(BlockPos nodePos : neighbouringNodes) | |
{ | |
TileEntityBuildersDrawers te = (TileEntityBuildersDrawers) world.getTileEntity(nodePos); | |
te.resetNetwork(); | |
} | |
} | |
} | |
public Material getStoredMaterial() | |
{ | |
return storedMaterial; | |
} | |
public void setStoredMaterial(Material storedMaterial) | |
{ | |
this.storedMaterial = storedMaterial; | |
} | |
public int getStoredQuantity() | |
{ | |
return storedQuantity; | |
} | |
public void setStoredQuantity(int storedQuantity) | |
{ | |
this.storedQuantity = storedQuantity; | |
} | |
public int getNetworkID() | |
{ | |
return networkID; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package daomephsta.buildersdrawers.common.tileentities; | |
import com.jaquadro.minecraft.chameleon.block.tiledata.TileDataShim; | |
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository; | |
import com.jaquadro.minecraft.storagedrawers.api.storage.*; | |
import com.jaquadro.minecraft.storagedrawers.block.tile.TileEntityDrawers; | |
import com.jaquadro.minecraft.storagedrawers.capabilities.CapabilityItemRepository; | |
import net.minecraft.block.state.IBlockState; | |
import net.minecraft.entity.EntityLivingBase; | |
import net.minecraft.item.ItemStack; | |
import net.minecraft.nbt.NBTTagCompound; | |
import net.minecraft.tileentity.TileEntity; | |
import net.minecraft.util.EnumFacing; | |
import net.minecraft.util.math.BlockPos; | |
import net.minecraft.world.World; | |
import net.minecraftforge.common.capabilities.Capability; | |
import net.minecraftforge.items.CapabilityItemHandler; | |
import net.minecraftforge.items.IItemHandler; | |
public class TileEntityBuildersDrawers extends TileEntityDrawers | |
{ | |
private IDrawerGroup group; | |
private MaterialNetwork materialNetwork; | |
public TileEntityBuildersDrawers() {} | |
public TileEntityBuildersDrawers(int drawerCount) | |
{ | |
this.group = new DrawerGroup(drawerCount); | |
} | |
@Override | |
public IDrawerGroup getGroup() | |
{ | |
return group; | |
} | |
void connectTo(MaterialNetwork network) | |
{ | |
materialNetwork = network.connect(pos); | |
} | |
public void onBlockPlaced(World world, BlockPos pos, IBlockState state, EntityLivingBase entity, ItemStack itemStack) | |
{ | |
if (!findNetwork()) | |
connectTo(MaterialNetwork.createSingletonNetwork(world, pos)); | |
} | |
public void onBlockBroken(World world, BlockPos pos, IBlockState state) | |
{ | |
materialNetwork.disconnect(pos); | |
} | |
public MaterialNetwork getMaterialNetwork() | |
{ | |
return materialNetwork; | |
} | |
private boolean findNetwork() | |
{ | |
for(EnumFacing facing : EnumFacing.values()) | |
{ | |
TileEntity te = world.getTileEntity(pos.offset(facing)); | |
if(te instanceof TileEntityBuildersDrawers) | |
{ | |
connectTo(((TileEntityBuildersDrawers) te).getMaterialNetwork()); | |
return true; | |
} | |
} | |
return false; | |
} | |
/** Creates a new network with this TE as the master node | |
* and then makes the network construct itself from the master node. | |
*/ | |
public void resetNetwork() | |
{ | |
connectTo(MaterialNetwork.constructNewNetwork(world, pos)); | |
} | |
@Override | |
protected void readFromFixedNBT(NBTTagCompound tag) | |
{ | |
super.readFromFixedNBT(tag); | |
group = new DrawerGroup(tag.getInteger("drawerCount")); | |
} | |
@Override | |
protected NBTTagCompound writeToFixedNBT(NBTTagCompound tag) | |
{ | |
tag = super.writeToFixedNBT(tag); | |
tag.setInteger("drawerCount", getGroup().getDrawerCount()); | |
return tag; | |
} | |
private static final class DrawerGroup extends TileDataShim implements IDrawerGroup | |
{ | |
private final int drawerCount; | |
private /*final*/ IItemHandler inventory; | |
private /*final*/ IItemRepository itemRepo; | |
private DrawerGroup(int drawerCount) | |
{ | |
this.drawerCount = drawerCount; | |
} | |
@Override | |
public int getDrawerCount() | |
{ | |
return drawerCount; | |
} | |
@Override | |
public IDrawer getDrawer(int slot) | |
{ | |
return Drawers.DISABLED; | |
} | |
@Override | |
public int[] getAccessibleDrawerSlots() | |
{ | |
return new int[0]; | |
} | |
@Override | |
public boolean hasCapability(Capability<?> capability, EnumFacing facing) | |
{ | |
return false; //capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY | |
//|| capability == CapabilityItemRepository.ITEM_REPOSITORY_CAPABILITY; | |
} | |
@Override | |
public <T> T getCapability(Capability<T> capability, EnumFacing facing) | |
{ | |
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) | |
return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(inventory); | |
if (capability == CapabilityItemRepository.ITEM_REPOSITORY_CAPABILITY) | |
return CapabilityItemRepository.ITEM_REPOSITORY_CAPABILITY.cast(itemRepo); | |
return IDrawerGroup.super.getCapability(capability, facing); | |
} | |
@Override | |
public void readFromNBT(NBTTagCompound tag) | |
{ | |
} | |
@Override | |
public NBTTagCompound writeToNBT(NBTTagCompound tag) | |
{ | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment