Initial cover code. Still some stuff to do.
This commit is contained in:
@@ -21,4 +21,5 @@ public final class RSItems {
|
||||
public static final ItemFluidStoragePart FLUID_STORAGE_PART = new ItemFluidStoragePart();
|
||||
public static final ItemSecurityCard SECURITY_CARD = new ItemSecurityCard();
|
||||
public static final ItemCuttingTool CUTTING_TOOL = new ItemCuttingTool();
|
||||
public static final ItemCover COVER = new ItemCover();
|
||||
}
|
||||
|
@@ -0,0 +1,7 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager;
|
||||
|
||||
public interface ICoverable {
|
||||
CoverManager getCoverManager();
|
||||
}
|
@@ -1,12 +1,22 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class NetworkNodeCable extends NetworkNode {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class NetworkNodeCable extends NetworkNode implements ICoverable {
|
||||
public static final String ID = "cable";
|
||||
|
||||
private static final String NBT_COVERS = "Covers";
|
||||
|
||||
private CoverManager coverManager = new CoverManager(this);
|
||||
|
||||
public NetworkNodeCable(World world, BlockPos pos) {
|
||||
super(world, pos);
|
||||
}
|
||||
@@ -20,4 +30,33 @@ public class NetworkNodeCable extends NetworkNode {
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoverManager getCoverManager() {
|
||||
return coverManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound write(NBTTagCompound tag) {
|
||||
super.write(tag);
|
||||
|
||||
tag.setTag(NBT_COVERS, coverManager.writeToNbt());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(NBTTagCompound tag) {
|
||||
super.read(tag);
|
||||
|
||||
if (tag.hasKey(NBT_COVERS)) {
|
||||
coverManager.readFromNbt(tag.getTagList(NBT_COVERS, Constants.NBT.TAG_COMPOUND));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IItemHandler getDrops() {
|
||||
return coverManager.getAsInventory();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,141 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node.cover;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RSItems;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemCover;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.EnumBlockRenderType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CoverManager {
|
||||
private static final String NBT_DIRECTION = "Direction";
|
||||
private static final String NBT_ITEM = "Item";
|
||||
|
||||
private Map<EnumFacing, ItemStack> covers = new HashMap<>();
|
||||
private INetworkNode node;
|
||||
|
||||
public CoverManager(INetworkNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getCover(EnumFacing facing) {
|
||||
return covers.get(facing);
|
||||
}
|
||||
|
||||
public boolean setCover(EnumFacing cover, ItemStack stack) {
|
||||
if (isValidCover(stack) && !covers.containsKey(cover)) {
|
||||
covers.put(cover, stack);
|
||||
|
||||
node.markDirty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void readFromNbt(NBTTagList list) {
|
||||
for (int i = 0; i < list.tagCount(); ++i) {
|
||||
NBTTagCompound tag = list.getCompoundTagAt(i);
|
||||
|
||||
if (tag.hasKey(NBT_DIRECTION) && tag.hasKey(NBT_ITEM)) {
|
||||
EnumFacing direction = EnumFacing.getFront(tag.getInteger(NBT_DIRECTION));
|
||||
ItemStack item = new ItemStack(tag.getCompoundTag(NBT_ITEM));
|
||||
|
||||
if (isValidCover(item)) {
|
||||
covers.put(direction, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NBTTagList writeToNbt() {
|
||||
NBTTagList list = new NBTTagList();
|
||||
|
||||
for (Map.Entry<EnumFacing, ItemStack> entry : covers.entrySet()) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
|
||||
tag.setInteger(NBT_DIRECTION, entry.getKey().ordinal());
|
||||
tag.setTag(NBT_ITEM, entry.getValue().serializeNBT());
|
||||
|
||||
list.appendTag(tag);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public IItemHandler getAsInventory() {
|
||||
ItemStackHandler handler = new ItemStackHandler(covers.size());
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (Map.Entry<EnumFacing, ItemStack> entry : covers.entrySet()) {
|
||||
ItemStack cover = new ItemStack(RSItems.COVER);
|
||||
|
||||
ItemCover.setItem(cover, entry.getValue());
|
||||
|
||||
handler.setStackInSlot(i++, cover);
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
public static boolean isValidCover(ItemStack item) {
|
||||
if (item.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block block = getBlock(item);
|
||||
|
||||
IBlockState state = getBlockState(item);
|
||||
|
||||
return block != null && state != null && isModelSupported(state) && block.isTopSolid(state) && !block.getTickRandomly() && !block.hasTileEntity(state);
|
||||
}
|
||||
|
||||
private static boolean isModelSupported(IBlockState state) {
|
||||
if (state.getRenderType() != EnumBlockRenderType.MODEL || state instanceof IExtendedBlockState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return state.isFullCube();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Block getBlock(@Nullable ItemStack item) {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Block block = Block.getBlockFromItem(item.getItem());
|
||||
|
||||
if (block == Blocks.AIR) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IBlockState getBlockState(@Nullable ItemStack item) {
|
||||
Block block = getBlock(item);
|
||||
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return block.getStateFromMeta(item.getItem().getMetadata(item));
|
||||
}
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package com.raoulvdberge.refinedstorage.block;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager;
|
||||
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileBase;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileCable;
|
||||
@@ -11,6 +13,7 @@ import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
@@ -20,13 +23,27 @@ import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BlockCable extends BlockNode {
|
||||
public static final PropertyObject<ItemStack> COVER_NORTH = new PropertyObject<>("cover_north", ItemStack.class);
|
||||
public static final PropertyObject<ItemStack> COVER_EAST = new PropertyObject<>("cover_east", ItemStack.class);
|
||||
public static final PropertyObject<ItemStack> COVER_SOUTH = new PropertyObject<>("cover_south", ItemStack.class);
|
||||
public static final PropertyObject<ItemStack> COVER_WEST = new PropertyObject<>("cover_west", ItemStack.class);
|
||||
public static final PropertyObject<ItemStack> COVER_UP = new PropertyObject<>("cover_up", ItemStack.class);
|
||||
public static final PropertyObject<ItemStack> COVER_DOWN = new PropertyObject<>("cover_down", ItemStack.class);
|
||||
|
||||
public static final AxisAlignedBB HOLDER_NORTH_AABB = RenderUtils.getBounds(7, 7, 2, 9, 9, 6);
|
||||
public static final AxisAlignedBB HOLDER_EAST_AABB = RenderUtils.getBounds(10, 7, 7, 14, 9, 9);
|
||||
public static final AxisAlignedBB HOLDER_SOUTH_AABB = RenderUtils.getBounds(7, 7, 10, 9, 9, 14);
|
||||
public static final AxisAlignedBB HOLDER_WEST_AABB = RenderUtils.getBounds(2, 7, 7, 6, 9, 9);
|
||||
public static final AxisAlignedBB HOLDER_UP_AABB = RenderUtils.getBounds(7, 10, 7, 9, 14, 9);
|
||||
public static final AxisAlignedBB HOLDER_DOWN_AABB = RenderUtils.getBounds(7, 2, 7, 9, 6, 9);
|
||||
|
||||
public static final AxisAlignedBB CORE_AABB = RenderUtils.getBounds(6, 6, 6, 10, 10, 10);
|
||||
private static final AxisAlignedBB NORTH_AABB = RenderUtils.getBounds(6, 6, 0, 10, 10, 6);
|
||||
private static final AxisAlignedBB EAST_AABB = RenderUtils.getBounds(10, 6, 6, 16, 10, 10);
|
||||
@@ -68,6 +85,12 @@ public class BlockCable extends BlockNode {
|
||||
.add(WEST)
|
||||
.add(UP)
|
||||
.add(DOWN)
|
||||
.add(COVER_NORTH)
|
||||
.add(COVER_EAST)
|
||||
.add(COVER_SOUTH)
|
||||
.add(COVER_WEST)
|
||||
.add(COVER_UP)
|
||||
.add(COVER_DOWN)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -87,6 +110,24 @@ public class BlockCable extends BlockNode {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
IBlockState s = super.getExtendedState(state, world, pos);
|
||||
|
||||
TileEntity tile = world.getTileEntity(pos);
|
||||
|
||||
if (tile instanceof TileNode && ((TileNode) tile).getNode() instanceof ICoverable) {
|
||||
s = ((IExtendedBlockState) s).withProperty(COVER_NORTH, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.NORTH));
|
||||
s = ((IExtendedBlockState) s).withProperty(COVER_EAST, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.EAST));
|
||||
s = ((IExtendedBlockState) s).withProperty(COVER_SOUTH, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.SOUTH));
|
||||
s = ((IExtendedBlockState) s).withProperty(COVER_WEST, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.WEST));
|
||||
s = ((IExtendedBlockState) s).withProperty(COVER_UP, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.UP));
|
||||
s = ((IExtendedBlockState) s).withProperty(COVER_DOWN, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.DOWN));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static boolean hasConnectionWith(IBlockAccess world, BlockPos pos, BlockBase block, TileEntity tile, EnumFacing direction) {
|
||||
if (!(tile instanceof TileNode)) {
|
||||
return false;
|
||||
@@ -119,7 +160,7 @@ public class BlockCable extends BlockNode {
|
||||
(state.getValue(DOWN) && RenderUtils.isInBounds(DOWN_AABB, hitX, hitY, hitZ));
|
||||
}
|
||||
|
||||
public List<AxisAlignedBB> getUnionizedCollisionBoxes(IBlockState state) {
|
||||
public List<AxisAlignedBB> getCombinedCollisionBoxes(IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
boxes.add(CORE_AABB);
|
||||
@@ -151,15 +192,81 @@ public class BlockCable extends BlockNode {
|
||||
return boxes;
|
||||
}
|
||||
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<AxisAlignedBB> getCollisionBoxes(IBlockState state) {
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
boxes.addAll(getUnionizedCollisionBoxes(state));
|
||||
boxes.addAll(getNonUnionizedCollisionBoxes(state));
|
||||
if (tile instanceof TileNode && ((TileNode) tile).getNode() instanceof ICoverable) {
|
||||
CoverManager coverManager = ((ICoverable) ((TileNode) tile).getNode()).getCoverManager();
|
||||
|
||||
boolean hasUp = coverManager.getCover(EnumFacing.UP) != null;
|
||||
boolean hasDown = coverManager.getCover(EnumFacing.DOWN) != null;
|
||||
|
||||
boolean hasEast = coverManager.getCover(EnumFacing.EAST) != null;
|
||||
boolean hasWest = coverManager.getCover(EnumFacing.WEST) != null;
|
||||
|
||||
if (coverManager.getCover(EnumFacing.NORTH) != null) {
|
||||
boxes.add(RenderUtils.getBounds(
|
||||
hasWest ? 2 : 0, hasDown ? 2 : 0, 0,
|
||||
hasEast ? 14 : 16, hasUp ? 14 : 16, 2
|
||||
));
|
||||
|
||||
boxes.add(HOLDER_NORTH_AABB);
|
||||
}
|
||||
|
||||
if (hasEast) {
|
||||
boxes.add(RenderUtils.getBounds(
|
||||
14, hasDown ? 2 : 0, 0,
|
||||
16, hasUp ? 14 : 16, 16
|
||||
));
|
||||
|
||||
boxes.add(HOLDER_EAST_AABB);
|
||||
}
|
||||
|
||||
if (coverManager.getCover(EnumFacing.SOUTH) != null) {
|
||||
boxes.add(RenderUtils.getBounds(
|
||||
hasEast ? 14 : 16, hasDown ? 2 : 0, 16,
|
||||
hasWest ? 2 : 0, hasUp ? 14 : 16, 14
|
||||
));
|
||||
|
||||
boxes.add(HOLDER_SOUTH_AABB);
|
||||
}
|
||||
|
||||
if (hasWest) {
|
||||
boxes.add(RenderUtils.getBounds(
|
||||
0, hasDown ? 2 : 0, 0,
|
||||
2, hasUp ? 14 : 16, 16
|
||||
));
|
||||
|
||||
boxes.add(HOLDER_WEST_AABB);
|
||||
}
|
||||
|
||||
if (hasUp) {
|
||||
boxes.add(RenderUtils.getBounds(
|
||||
0, 14, 0,
|
||||
16, 16, 16
|
||||
));
|
||||
|
||||
boxes.add(HOLDER_UP_AABB);
|
||||
}
|
||||
|
||||
if (hasDown) {
|
||||
boxes.add(RenderUtils.getBounds(
|
||||
0, 0, 0,
|
||||
16, 2, 16
|
||||
));
|
||||
|
||||
boxes.add(HOLDER_DOWN_AABB);
|
||||
}
|
||||
}
|
||||
|
||||
return boxes;
|
||||
}
|
||||
|
||||
private List<AxisAlignedBB> getAllCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
boxes.addAll(getCombinedCollisionBoxes(state));
|
||||
boxes.addAll(getCollisionBoxes(tile, state));
|
||||
|
||||
return boxes;
|
||||
}
|
||||
@@ -167,7 +274,7 @@ public class BlockCable extends BlockNode {
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, Entity entityIn, boolean p_185477_7_) {
|
||||
for (AxisAlignedBB aabb : getCollisionBoxes(this.getActualState(state, world, pos))) {
|
||||
for (AxisAlignedBB aabb : getAllCollisionBoxes(world.getTileEntity(pos), this.getActualState(state, world, pos))) {
|
||||
addCollisionBoxToList(pos, entityBox, collidingBoxes, aabb);
|
||||
}
|
||||
}
|
||||
@@ -175,7 +282,7 @@ public class BlockCable extends BlockNode {
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public RayTraceResult collisionRayTrace(IBlockState state, World world, BlockPos pos, Vec3d start, Vec3d end) {
|
||||
RenderUtils.AdvancedRayTraceResult result = RenderUtils.collisionRayTrace(pos, start, end, getCollisionBoxes(this.getActualState(state, world, pos)));
|
||||
RenderUtils.AdvancedRayTraceResult result = RenderUtils.collisionRayTrace(pos, start, end, getAllCollisionBoxes(world.getTileEntity(pos), this.getActualState(state, world, pos)));
|
||||
|
||||
return result != null ? result.hit : null;
|
||||
}
|
||||
|
@@ -17,13 +17,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BlockConstructor extends BlockCable {
|
||||
public static final AxisAlignedBB HOLDER_NORTH_AABB = RenderUtils.getBounds(7, 7, 2, 9, 9, 6);
|
||||
public static final AxisAlignedBB HOLDER_EAST_AABB = RenderUtils.getBounds(10, 7, 7, 14, 9, 9);
|
||||
public static final AxisAlignedBB HOLDER_SOUTH_AABB = RenderUtils.getBounds(7, 7, 10, 9, 9, 14);
|
||||
public static final AxisAlignedBB HOLDER_WEST_AABB = RenderUtils.getBounds(2, 7, 7, 6, 9, 9);
|
||||
public static final AxisAlignedBB HOLDER_UP_AABB = RenderUtils.getBounds(7, 10, 7, 9, 14, 9);
|
||||
public static final AxisAlignedBB HOLDER_DOWN_AABB = RenderUtils.getBounds(7, 2, 7, 9, 6, 9);
|
||||
|
||||
public static final AxisAlignedBB HEAD_NORTH_AABB = RenderUtils.getBounds(0, 0, 0, 16, 16, 2);
|
||||
public static final AxisAlignedBB HEAD_EAST_AABB = RenderUtils.getBounds(14, 0, 0, 16, 16, 16);
|
||||
public static final AxisAlignedBB HEAD_SOUTH_AABB = RenderUtils.getBounds(0, 0, 14, 16, 16, 16);
|
||||
@@ -36,7 +29,7 @@ public class BlockConstructor extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
switch (state.getValue(getDirection().getProperty())) {
|
||||
|
@@ -26,8 +26,8 @@ public class BlockDestructor extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state);
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
return RSBlocks.CONSTRUCTOR.getCollisionBoxes(tile, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -41,7 +41,7 @@ public class BlockExporter extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
switch (state.getValue(getDirection().getProperty())) {
|
||||
|
@@ -31,32 +31,32 @@ public class BlockExternalStorage extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
switch (state.getValue(getDirection().getProperty())) {
|
||||
case NORTH:
|
||||
boxes.add(BlockConstructor.HOLDER_NORTH_AABB);
|
||||
boxes.add(HOLDER_NORTH_AABB);
|
||||
boxes.add(HEAD_NORTH_AABB);
|
||||
break;
|
||||
case EAST:
|
||||
boxes.add(BlockConstructor.HOLDER_EAST_AABB);
|
||||
boxes.add(HOLDER_EAST_AABB);
|
||||
boxes.add(HEAD_EAST_AABB);
|
||||
break;
|
||||
case SOUTH:
|
||||
boxes.add(BlockConstructor.HOLDER_SOUTH_AABB);
|
||||
boxes.add(HOLDER_SOUTH_AABB);
|
||||
boxes.add(HEAD_SOUTH_AABB);
|
||||
break;
|
||||
case WEST:
|
||||
boxes.add(BlockConstructor.HOLDER_WEST_AABB);
|
||||
boxes.add(HOLDER_WEST_AABB);
|
||||
boxes.add(HEAD_WEST_AABB);
|
||||
break;
|
||||
case UP:
|
||||
boxes.add(BlockConstructor.HOLDER_UP_AABB);
|
||||
boxes.add(HOLDER_UP_AABB);
|
||||
boxes.add(HEAD_UP_AABB);
|
||||
break;
|
||||
case DOWN:
|
||||
boxes.add(BlockConstructor.HOLDER_DOWN_AABB);
|
||||
boxes.add(HOLDER_DOWN_AABB);
|
||||
boxes.add(HEAD_DOWN_AABB);
|
||||
break;
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ public class BlockImporter extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
List<AxisAlignedBB> boxes = new ArrayList<>();
|
||||
|
||||
switch (state.getValue(getDirection().getProperty())) {
|
||||
|
@@ -24,8 +24,8 @@ public class BlockReader extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state);
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
return RSBlocks.CONSTRUCTOR.getCollisionBoxes(tile, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -25,8 +25,8 @@ public class BlockWriter extends BlockCable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
|
||||
return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state);
|
||||
public List<AxisAlignedBB> getCollisionBoxes(TileEntity tile, IBlockState state) {
|
||||
return RSBlocks.CONSTRUCTOR.getCollisionBoxes(tile, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,101 @@
|
||||
package com.raoulvdberge.refinedstorage.item;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileNode;
|
||||
import com.raoulvdberge.refinedstorage.util.WorldUtils;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemCover extends ItemBase {
|
||||
private static final String NBT_ITEM = "Item";
|
||||
|
||||
public ItemCover() {
|
||||
super("cover");
|
||||
}
|
||||
|
||||
public static void setItem(ItemStack cover, ItemStack item) {
|
||||
if (!cover.hasTagCompound()) {
|
||||
cover.setTagCompound(new NBTTagCompound());
|
||||
}
|
||||
|
||||
cover.getTagCompound().setTag(NBT_ITEM, item.serializeNBT());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static ItemStack getItem(ItemStack cover) {
|
||||
if (!cover.hasTagCompound() || !cover.getTagCompound().hasKey(NBT_ITEM)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
return new ItemStack(cover.getTagCompound().getCompoundTag(NBT_ITEM));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
|
||||
super.addInformation(stack, world, tooltip, flag);
|
||||
|
||||
ItemStack item = getItem(stack);
|
||||
|
||||
if (!item.isEmpty()) {
|
||||
tooltip.add(item.getItem().getItemStackDisplayName(item));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
|
||||
TileEntity tile = world.getTileEntity(pos);
|
||||
|
||||
// Support placing on the bottom side without too much hassle.
|
||||
if (!canPlaceOn(tile)) {
|
||||
pos = pos.up();
|
||||
|
||||
facing = EnumFacing.DOWN;
|
||||
|
||||
tile = world.getTileEntity(pos);
|
||||
}
|
||||
|
||||
if (canPlaceOn(tile)) {
|
||||
if (world.isRemote) {
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
INetworkNode node = ((TileNode) tile).getNode();
|
||||
|
||||
if (node.getNetwork() != null && !node.getNetwork().getSecurityManager().hasPermission(Permission.BUILD, player)) {
|
||||
return EnumActionResult.FAIL;
|
||||
}
|
||||
|
||||
if (((ICoverable) node).getCoverManager().setCover(facing, getItem(stack))) {
|
||||
player.getHeldItem(hand).shrink(1);
|
||||
|
||||
WorldUtils.updateBlock(world, pos);
|
||||
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
return EnumActionResult.FAIL;
|
||||
}
|
||||
|
||||
return EnumActionResult.PASS;
|
||||
}
|
||||
|
||||
private boolean canPlaceOn(TileEntity tile) {
|
||||
return tile instanceof TileNode && ((TileNode) tile).getNode() instanceof ICoverable;
|
||||
}
|
||||
}
|
@@ -15,7 +15,14 @@ import com.raoulvdberge.refinedstorage.gui.grid.GuiCraftingStart;
|
||||
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
|
||||
import com.raoulvdberge.refinedstorage.item.*;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse;
|
||||
import com.raoulvdberge.refinedstorage.render.*;
|
||||
import com.raoulvdberge.refinedstorage.render.model.ModelDiskDrive;
|
||||
import com.raoulvdberge.refinedstorage.render.model.ModelDiskManipulator;
|
||||
import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelCableCover;
|
||||
import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelCover;
|
||||
import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelPattern;
|
||||
import com.raoulvdberge.refinedstorage.render.model.loader.CustomModelLoaderDefault;
|
||||
import com.raoulvdberge.refinedstorage.render.statemapper.StateMapperCTM;
|
||||
import com.raoulvdberge.refinedstorage.render.tesr.TileEntitySpecialRendererStorageMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileController;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileStorageMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.grid.portable.IPortableGrid;
|
||||
@@ -76,7 +83,7 @@ public class ProxyClient extends ProxyCommon {
|
||||
itemColors.registerItemColorHandler((stack, tintIndex) -> {
|
||||
CraftingPattern pattern = ItemPattern.getPatternFromCache(Minecraft.getMinecraft().world, stack);
|
||||
|
||||
if (BakedModelPattern.canDisplayPatternOutput(stack, pattern)) {
|
||||
if (BakedModelPattern.canDisplayOutput(stack, pattern)) {
|
||||
int color = itemColors.colorMultiplier(pattern.getOutputs().get(0), tintIndex);
|
||||
|
||||
if (color != -1) {
|
||||
@@ -121,13 +128,13 @@ public class ProxyClient extends ProxyCommon {
|
||||
);
|
||||
|
||||
ModelBakery.registerItemVariants(RSItems.PROCESSOR,
|
||||
new ResourceLocation("refinedstorage:basic_printed_processor"),
|
||||
new ResourceLocation("refinedstorage:improved_printed_processor"),
|
||||
new ResourceLocation("refinedstorage:advanced_printed_processor"),
|
||||
new ResourceLocation("refinedstorage:cut_basic_processor"),
|
||||
new ResourceLocation("refinedstorage:cut_improved_processor"),
|
||||
new ResourceLocation("refinedstorage:cut_advanced_processor"),
|
||||
new ResourceLocation("refinedstorage:basic_processor"),
|
||||
new ResourceLocation("refinedstorage:improved_processor"),
|
||||
new ResourceLocation("refinedstorage:advanced_processor"),
|
||||
new ResourceLocation("refinedstorage:printed_silicon")
|
||||
new ResourceLocation("refinedstorage:cut_silicon")
|
||||
);
|
||||
|
||||
ModelBakery.registerItemVariants(RSItems.CORE,
|
||||
@@ -223,6 +230,7 @@ public class ProxyClient extends ProxyCommon {
|
||||
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RSBlocks.DISK_MANIPULATOR), 0, new ModelResourceLocation("refinedstorage:disk_manipulator", "inventory"));
|
||||
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RSBlocks.QUARTZ_ENRICHED_IRON), 0, new ModelResourceLocation("refinedstorage:quartz_enriched_iron_block", "inventory"));
|
||||
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RSBlocks.STORAGE_MONITOR), 0, new ModelResourceLocation("refinedstorage:storage_monitor", "connected=false,direction=north"));
|
||||
ModelLoader.setCustomModelResourceLocation(RSItems.COVER, 0, new ModelResourceLocation("refinedstorage:cover", "inventory"));
|
||||
|
||||
ModelLoaderRegistry.registerLoader(new CustomModelLoaderDefault(new ResourceLocation(RS.ID, "disk_drive"), ModelDiskDrive::new));
|
||||
ModelLoaderRegistry.registerLoader(new CustomModelLoaderDefault(new ResourceLocation(RS.ID, "disk_manipulator"), ModelDiskManipulator::new));
|
||||
@@ -364,6 +372,10 @@ public class ProxyClient extends ProxyCommon {
|
||||
if (model.getResourceDomain().equals(RS.ID)) {
|
||||
if (model.getResourcePath().equals("pattern")) {
|
||||
e.getModelRegistry().putObject(model, new BakedModelPattern(e.getModelRegistry().getObject(model)));
|
||||
} else if (model.getResourcePath().equals("cable")) {
|
||||
e.getModelRegistry().putObject(model, new BakedModelCableCover(e.getModelRegistry().getObject(model)));
|
||||
} else if (model.getResourcePath().equals("cover")) {
|
||||
e.getModelRegistry().putObject(model, new BakedModelCover(e.getModelRegistry().getObject(model), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,8 +405,8 @@ public class ProxyClient extends ProxyCommon {
|
||||
return;
|
||||
}
|
||||
|
||||
List<AxisAlignedBB> unionized = cable.getUnionizedCollisionBoxes(state);
|
||||
List<AxisAlignedBB> nonUnionized = cable.getNonUnionizedCollisionBoxes(state);
|
||||
List<AxisAlignedBB> combinedBoxes = cable.getCombinedCollisionBoxes(state);
|
||||
List<AxisAlignedBB> boxes = cable.getCollisionBoxes(player.world.getTileEntity(pos), state);
|
||||
|
||||
e.setCanceled(true);
|
||||
|
||||
@@ -409,15 +421,15 @@ public class ProxyClient extends ProxyCommon {
|
||||
double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) e.getPartialTicks();
|
||||
double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) e.getPartialTicks();
|
||||
|
||||
AxisAlignedBB unionizedAabb = unionized.get(0);
|
||||
AxisAlignedBB combinedAabb = combinedBoxes.get(0);
|
||||
|
||||
for (int i = 1; i < unionized.size(); ++i) {
|
||||
unionizedAabb = unionizedAabb.union(unionized.get(i));
|
||||
for (int i = 1; i < combinedBoxes.size(); ++i) {
|
||||
combinedAabb = combinedAabb.union(combinedBoxes.get(i));
|
||||
}
|
||||
|
||||
drawSelectionBoundingBox(unionizedAabb.expand(0.0020000000949949026D, 0.0020000000949949026D, 0.0020000000949949026D).offset(-d0, -d1, -d2).offset(pos.getX(), pos.getY(), pos.getZ()));
|
||||
drawSelectionBoundingBox(combinedAabb.expand(0.0020000000949949026D, 0.0020000000949949026D, 0.0020000000949949026D).offset(-d0, -d1, -d2).offset(pos.getX(), pos.getY(), pos.getZ()));
|
||||
|
||||
for (AxisAlignedBB aabb : nonUnionized) {
|
||||
for (AxisAlignedBB aabb : boxes) {
|
||||
drawSelectionBoundingBox(aabb.expand(0.0020000000949949026D, 0.0020000000949949026D, 0.0020000000949949026D).offset(-d0, -d1, -d2).offset(pos.getX(), pos.getY(), pos.getZ()));
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,7 @@ import com.raoulvdberge.refinedstorage.integration.oc.DriverNetwork;
|
||||
import com.raoulvdberge.refinedstorage.integration.oc.IntegrationOC;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemProcessor;
|
||||
import com.raoulvdberge.refinedstorage.network.*;
|
||||
import com.raoulvdberge.refinedstorage.recipe.RecipeCover;
|
||||
import com.raoulvdberge.refinedstorage.tile.*;
|
||||
import com.raoulvdberge.refinedstorage.tile.craftingmonitor.TileCraftingMonitor;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataManager;
|
||||
@@ -59,6 +60,7 @@ import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
@@ -260,6 +262,7 @@ public class ProxyCommon {
|
||||
registerItem(RSItems.FILTER);
|
||||
registerItem(RSItems.NETWORK_CARD);
|
||||
registerItem(RSItems.SECURITY_CARD);
|
||||
registerItem(RSItems.COVER);
|
||||
|
||||
IntegrationInventorySorter.register();
|
||||
}
|
||||
@@ -304,6 +307,11 @@ public class ProxyCommon {
|
||||
itemsToRegister.forEach(e.getRegistry()::register);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void registerRecipes(RegistryEvent.Register<IRecipe> e) {
|
||||
e.getRegistry().register(new RecipeCover().setRegistryName(new ResourceLocation(RS.ID, "cover")));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onHarvestCheck(PlayerEvent.HarvestCheck e) {
|
||||
if (e.getTargetBlock().getBlock() instanceof BlockBase) {
|
||||
|
@@ -0,0 +1,72 @@
|
||||
package com.raoulvdberge.refinedstorage.recipe;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RSItems;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemCover;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
public class RecipeCover extends IForgeRegistryEntry.Impl<IRecipe> implements IRecipe {
|
||||
@Override
|
||||
public boolean matches(InventoryCrafting inv, World world) {
|
||||
boolean hadCuttingTool = false;
|
||||
boolean hadItem = false;
|
||||
|
||||
for (int i = 0; i < inv.getSizeInventory(); ++i) {
|
||||
ItemStack slot = inv.getStackInSlot(i);
|
||||
|
||||
if (!slot.isEmpty() && hadCuttingTool && hadItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slot.getItem() == RSItems.CUTTING_TOOL) {
|
||||
if (hadCuttingTool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hadCuttingTool = true;
|
||||
}
|
||||
|
||||
if (CoverManager.isValidCover(slot)) {
|
||||
if (hadItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hadItem = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hadCuttingTool && hadItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCraftingResult(InventoryCrafting inv) {
|
||||
for (int i = 0; i < inv.getSizeInventory(); ++i) {
|
||||
ItemStack slot = inv.getStackInSlot(i);
|
||||
|
||||
if (CoverManager.isValidCover(slot)) {
|
||||
ItemStack cover = new ItemStack(RSItems.COVER, 6);
|
||||
|
||||
ItemCover.setItem(cover, ItemHandlerHelper.copyStackWithSize(slot, 1));
|
||||
|
||||
return cover;
|
||||
}
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFit(int width, int height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRecipeOutput() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
@@ -0,0 +1,518 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
|
||||
import javax.vecmath.Vector4f;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @link https://github.com/ArekkuusuJerii/Solar
|
||||
*/
|
||||
public class QuadBuilder {
|
||||
private final Map<EnumFacing, QuadHolder> facingMap = Maps.newEnumMap(EnumFacing.class);
|
||||
private final VertexFormat format;
|
||||
private boolean hasBrightness;
|
||||
private Vector3 from;
|
||||
private Vector3 to;
|
||||
private EnumFacing last;
|
||||
|
||||
private QuadBuilder(VertexFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public static QuadBuilder withFormat(VertexFormat format) {
|
||||
return new QuadBuilder(format);
|
||||
}
|
||||
|
||||
public QuadBuilder setFrom(double x, double y, double z) {
|
||||
this.from = Vector3.create(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder setTo(double x, double y, double z) {
|
||||
this.to = Vector3.create(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder setHasBrightness(boolean hasBrightness) {
|
||||
this.hasBrightness = hasBrightness;
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder addAll(TextureAtlasSprite sprite) {
|
||||
for (EnumFacing facing : EnumFacing.values()) {
|
||||
addFace(facing, 0F, 16F, 0F, 16F, sprite);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder addAll(float uMin, float uMax, float vMin, float vMax, TextureAtlasSprite sprite) {
|
||||
for (EnumFacing facing : EnumFacing.values()) {
|
||||
addFace(facing, uMin, uMax, vMin, vMax, sprite);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder addFace(EnumFacing facing, float uMin, float uMax, float vMin, float vMax, TextureAtlasSprite sprite) {
|
||||
QuadHolder holder = new QuadHolder();
|
||||
|
||||
holder.uv = new Vector4f(uMin, uMax, vMin, vMax);
|
||||
|
||||
Vector3 a = Vector3.create(0, 0, 0);
|
||||
Vector3 b = Vector3.create(0, 0, 0);
|
||||
Vector3 c = Vector3.create(0, 0, 0);
|
||||
Vector3 d = Vector3.create(0, 0, 0);
|
||||
|
||||
holder.sprite = sprite;
|
||||
|
||||
switch (facing) {
|
||||
case DOWN:
|
||||
a.x = to.x;
|
||||
a.y = from.y;
|
||||
a.z = from.z;
|
||||
|
||||
b.x = to.x;
|
||||
b.y = from.y;
|
||||
b.z = to.z;
|
||||
|
||||
c.x = from.x;
|
||||
c.y = from.y;
|
||||
c.z = to.z;
|
||||
|
||||
d.x = from.x;
|
||||
d.y = from.y;
|
||||
d.z = from.z;
|
||||
break;
|
||||
case UP:
|
||||
a.x = from.x;
|
||||
a.y = to.y;
|
||||
a.z = from.z;
|
||||
|
||||
b.x = from.x;
|
||||
b.y = to.y;
|
||||
b.z = to.z;
|
||||
|
||||
c.x = to.x;
|
||||
c.y = to.y;
|
||||
c.z = to.z;
|
||||
|
||||
d.x = to.x;
|
||||
d.y = to.y;
|
||||
d.z = from.z;
|
||||
break;
|
||||
case NORTH:
|
||||
a.x = to.x;
|
||||
a.y = from.y;
|
||||
a.z = to.z;
|
||||
|
||||
b.x = to.x;
|
||||
b.y = to.y;
|
||||
b.z = to.z;
|
||||
|
||||
c.x = from.x;
|
||||
c.y = to.y;
|
||||
c.z = to.z;
|
||||
|
||||
d.x = from.x;
|
||||
d.y = from.y;
|
||||
d.z = to.z;
|
||||
break;
|
||||
case SOUTH:
|
||||
a.x = from.x;
|
||||
a.y = from.y;
|
||||
a.z = from.z;
|
||||
|
||||
b.x = from.x;
|
||||
b.y = to.y;
|
||||
b.z = from.z;
|
||||
|
||||
c.x = to.x;
|
||||
c.y = to.y;
|
||||
c.z = from.z;
|
||||
|
||||
d.x = to.x;
|
||||
d.y = from.y;
|
||||
d.z = from.z;
|
||||
break;
|
||||
case WEST:
|
||||
a.x = from.x;
|
||||
a.y = from.y;
|
||||
a.z = to.z;
|
||||
|
||||
b.x = from.x;
|
||||
b.y = to.y;
|
||||
b.z = to.z;
|
||||
|
||||
c.x = from.x;
|
||||
c.y = to.y;
|
||||
c.z = from.z;
|
||||
|
||||
d.x = from.x;
|
||||
d.y = from.y;
|
||||
d.z = from.z;
|
||||
break;
|
||||
case EAST:
|
||||
a.x = to.x;
|
||||
a.y = from.y;
|
||||
a.z = from.z;
|
||||
|
||||
b.x = to.x;
|
||||
b.y = to.y;
|
||||
b.z = from.z;
|
||||
|
||||
c.x = to.x;
|
||||
c.y = to.y;
|
||||
c.z = to.z;
|
||||
|
||||
d.x = to.x;
|
||||
d.y = from.y;
|
||||
d.z = to.z;
|
||||
break;
|
||||
}
|
||||
|
||||
holder.a = a.divide(16D);
|
||||
holder.b = b.divide(16D);
|
||||
holder.c = c.divide(16D);
|
||||
holder.d = d.divide(16D);
|
||||
|
||||
facingMap.put(facing, holder);
|
||||
last = facing;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder mirror() {
|
||||
if (facingMap.containsKey(last)) {
|
||||
Stream<Vector3> stream = Arrays.stream(facingMap.get(last).getVectors());
|
||||
switch (last) {
|
||||
case DOWN:
|
||||
case UP:
|
||||
stream.forEach(vec -> vec.subtract(0.5D).rotate(EnumFacing.Axis.Y, 180).add(0.5D));
|
||||
break;
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
stream.forEach(vec -> vec.subtract(0.5D).rotate(EnumFacing.Axis.X, 180).add(0.5D));
|
||||
break;
|
||||
case EAST:
|
||||
case WEST:
|
||||
stream.forEach(vec -> vec.subtract(0.5D).rotate(EnumFacing.Axis.Z, 180).add(0.5D));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder clear() {
|
||||
facingMap.clear();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder rotate(EnumFacing facing, EnumFacing... exclude) {
|
||||
if (exclude == null || !Arrays.asList(exclude).contains(facing)) {
|
||||
switch (facing) {
|
||||
case DOWN:
|
||||
rotate(EnumFacing.Axis.X, 180F);
|
||||
break;
|
||||
case UP:
|
||||
rotate(EnumFacing.Axis.X, 180F);
|
||||
break;
|
||||
default:
|
||||
rotate(EnumFacing.Axis.X, 90F);
|
||||
rotate(EnumFacing.Axis.Y, -facing.getHorizontalAngle());
|
||||
rotate(EnumFacing.Axis.Y, -90F);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public QuadBuilder rotate(EnumFacing.Axis axis, float angle) {
|
||||
facingMap.values().forEach(holder -> {
|
||||
Arrays.stream(holder.getVectors()).forEach(vec -> {
|
||||
vec.subtract(0.5D).rotate(axis, angle).add(0.5D);
|
||||
});
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<BakedQuad> bake() {
|
||||
return facingMap.entrySet().stream().map(e -> createQuad(e.getValue(), e.getKey())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private BakedQuad createQuad(QuadHolder holder, EnumFacing facing) {
|
||||
Vector4f uv = holder.uv;
|
||||
|
||||
Vector3 a = holder.a;
|
||||
Vector3 b = holder.b;
|
||||
Vector3 c = holder.c;
|
||||
Vector3 d = holder.d;
|
||||
|
||||
Vector3 normal = c.copy().subtract(b).cross(a.copy().subtract(b)).normalize();
|
||||
|
||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
|
||||
|
||||
putVertex(builder, normal, a.x, a.y, a.z, holder.sprite, uv.y, uv.w, hasBrightness);
|
||||
putVertex(builder, normal, b.x, b.y, b.z, holder.sprite, uv.y, uv.z, hasBrightness);
|
||||
putVertex(builder, normal, c.x, c.y, c.z, holder.sprite, uv.x, uv.z, hasBrightness);
|
||||
putVertex(builder, normal, d.x, d.y, d.z, holder.sprite, uv.x, uv.w, hasBrightness);
|
||||
|
||||
builder.setQuadOrientation(facing);
|
||||
builder.setTexture(holder.sprite);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void putVertex(UnpackedBakedQuad.Builder builder, Vector3 normal, double x, double y, double z, TextureAtlasSprite sprite, float u, float v, boolean hasBrightness) {
|
||||
for (int e = 0; e < format.getElementCount(); e++) {
|
||||
switch (format.getElement(e).getUsage()) {
|
||||
case POSITION:
|
||||
builder.put(e, (float) x, (float) y, (float) z, 1F);
|
||||
break;
|
||||
case COLOR:
|
||||
builder.put(e, 1F, 1F, 1F, 1F);
|
||||
break;
|
||||
case UV:
|
||||
if (format.getElement(e).getIndex() == 1) {
|
||||
if (hasBrightness) {
|
||||
builder.put(e, 1F, 1F);
|
||||
} else {
|
||||
builder.put(e, 0F, 0F);
|
||||
}
|
||||
break;
|
||||
} else if (format.getElement(e).getIndex() == 0) {
|
||||
u = sprite.getInterpolatedU(u);
|
||||
v = sprite.getInterpolatedV(v);
|
||||
builder.put(e, u, v, 0F, 1F);
|
||||
break;
|
||||
}
|
||||
case NORMAL:
|
||||
if (hasBrightness) {
|
||||
builder.put(e, 0F, 1F, 0F);
|
||||
} else {
|
||||
builder.put(e, (float) normal.x, (float) normal.y, (float) normal.z);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
builder.put(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class QuadHolder {
|
||||
private TextureAtlasSprite sprite;
|
||||
|
||||
private Vector3 a;
|
||||
private Vector3 b;
|
||||
private Vector3 c;
|
||||
private Vector3 d;
|
||||
|
||||
private Vector4f uv;
|
||||
|
||||
public Vector3[] getVectors() {
|
||||
return new Vector3[]{a, b, c, d};
|
||||
}
|
||||
}
|
||||
|
||||
private static class Vector3 {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
|
||||
public static Vector3 create(double x, double y, double z) {
|
||||
return new Vector3(x, y, z);
|
||||
}
|
||||
|
||||
public static Vector3 create(Vec3d vec) {
|
||||
return new Vector3(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
private Vector3(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public Vector3 setVec(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3 subtract(Vector3 vec) {
|
||||
return subtract(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public Vector3 subtract(Vec3d vec) {
|
||||
return subtract(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public Vector3 subtract(Vec3i vec) {
|
||||
return subtract(vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
public Vector3 subtract(double amount) {
|
||||
return subtract(amount, amount, amount);
|
||||
}
|
||||
|
||||
public Vector3 subtract(double x, double y, double z) {
|
||||
return add(-x, -y, -z);
|
||||
}
|
||||
|
||||
public Vector3 add(Vector3 vec) {
|
||||
return add(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public Vector3 add(Vec3d vec) {
|
||||
return add(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public Vector3 add(Vec3i vec) {
|
||||
return add(vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
public Vector3 add(double amount) {
|
||||
return add(amount, amount, amount);
|
||||
}
|
||||
|
||||
public Vector3 add(double x, double y, double z) {
|
||||
return setVec(this.x + x, this.y + y, this.z + z);
|
||||
}
|
||||
|
||||
public Vector3 multiply(Vector3 vec) {
|
||||
return multiply(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public Vector3 multiply(double m) {
|
||||
return multiply(m, m, m);
|
||||
}
|
||||
|
||||
public Vector3 multiply(double x, double y, double z) {
|
||||
return setVec(this.x * x, this.y * y, this.z * z);
|
||||
}
|
||||
|
||||
public Vector3 divide(Vector3 vec) {
|
||||
return divide(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public Vector3 divide(double m) {
|
||||
return divide(m, m, m);
|
||||
}
|
||||
|
||||
public Vector3 divide(double x, double y, double z) {
|
||||
return setVec(this.x / x, this.y / y, this.z / z);
|
||||
}
|
||||
|
||||
public Vector3 rotate(EnumFacing.Axis axis, float degrees) {
|
||||
float radians = degrees * (float) (Math.PI / 180D);
|
||||
switch (axis) {
|
||||
case X:
|
||||
rotatePitchX(radians);
|
||||
break;
|
||||
case Y:
|
||||
rotateYaw(radians);
|
||||
break;
|
||||
case Z:
|
||||
rotatePitchZ(radians);
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3 rotateYaw(float radians) {
|
||||
float cos = MathHelper.cos(radians);
|
||||
float sin = MathHelper.sin(radians);
|
||||
double x = this.x * cos + this.z * sin;
|
||||
double z = this.z * cos - this.x * sin;
|
||||
return setVec(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3 rotatePitchZ(float radians) {
|
||||
float cos = MathHelper.cos(radians);
|
||||
float sin = MathHelper.sin(radians);
|
||||
double y = this.y * cos + this.z * sin;
|
||||
double z = this.z * cos - this.y * sin;
|
||||
return setVec(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3 rotatePitchX(float radians) {
|
||||
float cos = MathHelper.cos(radians);
|
||||
float sin = MathHelper.sin(radians);
|
||||
double y = this.y * cos + this.x * sin;
|
||||
double x = this.x * cos - this.y * sin;
|
||||
return setVec(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3 rotate(Rotation rotation) {
|
||||
switch (rotation) {
|
||||
case NONE:
|
||||
default:
|
||||
return this;
|
||||
case CLOCKWISE_90:
|
||||
return setVec(-z, y, x);
|
||||
case CLOCKWISE_180:
|
||||
return setVec(-x, y, -z);
|
||||
case COUNTERCLOCKWISE_90:
|
||||
return setVec(z, y, -x);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 offset(EnumFacing facing, float amount) {
|
||||
return setVec(x + facing.getFrontOffsetX() * amount, y + facing.getFrontOffsetY() * amount, z + facing.getFrontOffsetZ() * amount);
|
||||
}
|
||||
|
||||
public Vector3 normalize() {
|
||||
double root = MathHelper.sqrt(x * x + y * y + z * z);
|
||||
|
||||
return root < 1.0E-4D ? setVec(0, 0, 0) : setVec(x / root, y / root, z / root);
|
||||
}
|
||||
|
||||
public Vector3 cross(Vector3 vec) {
|
||||
double x = this.y * vec.z - this.z * vec.y;
|
||||
double y = this.z * vec.x - this.x * vec.z;
|
||||
double z = this.x * vec.y - this.y * vec.x;
|
||||
|
||||
return setVec(x, y, z);
|
||||
}
|
||||
|
||||
public double distanceTo(Vector3 vec) {
|
||||
double xDiff = x - vec.x;
|
||||
double yDiff = y - vec.y;
|
||||
double zDiff = z - vec.z;
|
||||
|
||||
return MathHelper.sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff);
|
||||
}
|
||||
|
||||
public Vector3 limit(double max) {
|
||||
double x = this.x > max ? max : this.x < -max ? -max : this.x;
|
||||
double y = this.y > max ? max : this.y < -max ? -max : this.y;
|
||||
double z = this.z > max ? max : this.z < -max ? -max : this.z;
|
||||
|
||||
return setVec(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3 copy() {
|
||||
return new Vector3(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelDiskDrive;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
@@ -1,5 +1,6 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelDiskManipulator;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
@@ -0,0 +1,284 @@
|
||||
package com.raoulvdberge.refinedstorage.render.model.baked;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager;
|
||||
import com.raoulvdberge.refinedstorage.block.BlockCable;
|
||||
import com.raoulvdberge.refinedstorage.render.QuadBuilder;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BakedModelCableCover implements IBakedModel {
|
||||
private IBakedModel base;
|
||||
private TextureAtlasSprite genericGreyTexture;
|
||||
|
||||
public BakedModelCableCover(IBakedModel base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
|
||||
List<BakedQuad> quads = new ArrayList<>(base.getQuads(state, side, rand));
|
||||
|
||||
if (state != null) {
|
||||
IExtendedBlockState s = (IExtendedBlockState) state;
|
||||
|
||||
addCover(quads, s.getValue(BlockCable.COVER_NORTH), EnumFacing.NORTH, side, rand, s);
|
||||
addCover(quads, s.getValue(BlockCable.COVER_SOUTH), EnumFacing.SOUTH, side, rand, s);
|
||||
addCover(quads, s.getValue(BlockCable.COVER_EAST), EnumFacing.EAST, side, rand, s);
|
||||
addCover(quads, s.getValue(BlockCable.COVER_WEST), EnumFacing.WEST, side, rand, s);
|
||||
addCover(quads, s.getValue(BlockCable.COVER_DOWN), EnumFacing.DOWN, side, rand, s);
|
||||
addCover(quads, s.getValue(BlockCable.COVER_UP), EnumFacing.UP, side, rand, s);
|
||||
}
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
private void addCover(List<BakedQuad> quads, @Nullable ItemStack coverStack, EnumFacing coverSide, EnumFacing side, long rand, IExtendedBlockState state) {
|
||||
if (coverStack == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IBlockState coverState = CoverManager.getBlockState(coverStack);
|
||||
|
||||
if (coverState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IBakedModel coverModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(coverState);
|
||||
|
||||
TextureAtlasSprite sprite = getSprite(coverModel, coverState, side, rand);
|
||||
|
||||
boolean hasUp = CoverManager.getBlockState(state.getValue(BlockCable.COVER_UP)) != null;
|
||||
boolean hasDown = CoverManager.getBlockState(state.getValue(BlockCable.COVER_DOWN)) != null;
|
||||
|
||||
boolean hasEast = CoverManager.getBlockState(state.getValue(BlockCable.COVER_EAST)) != null;
|
||||
boolean hasWest = CoverManager.getBlockState(state.getValue(BlockCable.COVER_WEST)) != null;
|
||||
|
||||
float handleAngle = 0;
|
||||
EnumFacing.Axis handleAxis = EnumFacing.Axis.Y;
|
||||
|
||||
if (coverSide == EnumFacing.NORTH) {
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(hasWest ? 2 : 0, hasDown ? 2 : 0, 0)
|
||||
.setTo(hasEast ? 14 : 16, hasUp ? 14 : 16, 2)
|
||||
|
||||
.addFace(EnumFacing.UP, 16, 0, 2, 0, sprite)
|
||||
.addFace(EnumFacing.DOWN, 0, 16, 14, 16, sprite)
|
||||
.addFace(EnumFacing.EAST, 14, 16, 0, 16, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 2, 0, 16, sprite)
|
||||
|
||||
.addFace(EnumFacing.NORTH, hasEast ? 2 : 0, hasWest ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
.addFace(EnumFacing.SOUTH, hasEast ? 2 : 0, hasWest ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
} else if (coverSide == EnumFacing.SOUTH) {
|
||||
handleAngle = 180;
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(hasEast ? 14 : 16, hasDown ? 2 : 0, 16)
|
||||
.setTo(hasWest ? 2 : 0, hasUp ? 14 : 16, 14)
|
||||
|
||||
.addFace(EnumFacing.UP, 0, 16, 14, 16, sprite)
|
||||
.addFace(EnumFacing.DOWN, 16, 0, 2, 0, sprite)
|
||||
.addFace(EnumFacing.EAST, 14, 16, 0, 16, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 2, 0, 16, sprite)
|
||||
|
||||
.addFace(EnumFacing.NORTH, hasWest ? 2 : 0, hasEast ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
.addFace(EnumFacing.SOUTH, hasWest ? 2 : 0, hasEast ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
} else if (coverSide == EnumFacing.EAST) {
|
||||
handleAngle = 270;
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(14, hasDown ? 2 : 0, 0)
|
||||
.setTo(16, hasUp ? 14 : 16, 16)
|
||||
|
||||
.addFace(EnumFacing.UP, 16, 14, 16, 0, sprite)
|
||||
.addFace(EnumFacing.DOWN, 14, 16, 0, 16, sprite)
|
||||
.addFace(EnumFacing.NORTH, 14, 16, 0, 16, sprite)
|
||||
.addFace(EnumFacing.SOUTH, 0, 2, 0, 16, sprite)
|
||||
|
||||
.addFace(EnumFacing.EAST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
} else if (coverSide == EnumFacing.WEST) {
|
||||
handleAngle = 90;
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(0, hasDown ? 2 : 0, 0)
|
||||
.setTo(2, hasUp ? 14 : 16, 16)
|
||||
|
||||
.addFace(EnumFacing.UP, 2, 0, 16, 0, sprite)
|
||||
.addFace(EnumFacing.DOWN, 0, 2, 0, 16, sprite)
|
||||
.addFace(EnumFacing.NORTH, 0, 2, 0, 16, sprite)
|
||||
.addFace(EnumFacing.SOUTH, 14, 16, 0, 16, sprite)
|
||||
|
||||
.addFace(EnumFacing.EAST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
} else if (coverSide == EnumFacing.DOWN) {
|
||||
handleAxis = EnumFacing.Axis.Z;
|
||||
handleAngle = 90;
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(0, 0, 0)
|
||||
.setTo(16, 2, 16)
|
||||
|
||||
.addFace(EnumFacing.NORTH, 0, 16, 14, 16, sprite)
|
||||
.addFace(EnumFacing.SOUTH, 0, 16, 14, 16, sprite)
|
||||
.addFace(EnumFacing.EAST, 0, 16, 14, 16, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 16, 14, 16, sprite)
|
||||
|
||||
.addFace(EnumFacing.UP, 16, 0, 16, 0, sprite)
|
||||
.addFace(EnumFacing.DOWN, 0, 16, 0, 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
} else if (coverSide == EnumFacing.UP) {
|
||||
handleAxis = EnumFacing.Axis.Z;
|
||||
handleAngle = 270;
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(0, 14, 0)
|
||||
.setTo(16, 16, 16)
|
||||
|
||||
.addFace(EnumFacing.NORTH, 0, 16, 0, 2, sprite)
|
||||
.addFace(EnumFacing.SOUTH, 0, 16, 0, 2, sprite)
|
||||
.addFace(EnumFacing.EAST, 0, 16, 0, 2, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 16, 0, 2, sprite)
|
||||
|
||||
.addFace(EnumFacing.UP, 16, 0, 16, 0, sprite)
|
||||
.addFace(EnumFacing.DOWN, 0, 16, 0, 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
}
|
||||
|
||||
if (this.genericGreyTexture == null) {
|
||||
this.genericGreyTexture = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(RS.ID + ":blocks/generic_grey");
|
||||
}
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(7, 7, 2)
|
||||
.setTo(9, 9, 6)
|
||||
.addFace(EnumFacing.NORTH, 0, 0, 4, 4, genericGreyTexture)
|
||||
.addFace(EnumFacing.EAST, 0, 0, 2, 4, genericGreyTexture)
|
||||
.addFace(EnumFacing.SOUTH, 0, 0, 4, 4, genericGreyTexture)
|
||||
.addFace(EnumFacing.WEST, 0, 0, 2, 4, genericGreyTexture)
|
||||
.addFace(EnumFacing.UP, 0, 0, 4, 2, genericGreyTexture)
|
||||
.addFace(EnumFacing.DOWN, 0, 0, 4, 2, genericGreyTexture)
|
||||
.rotate(handleAxis, handleAngle)
|
||||
.bake()
|
||||
);
|
||||
}
|
||||
|
||||
public static TextureAtlasSprite getSprite(IBakedModel coverModel, IBlockState coverState, EnumFacing facing, long rand) {
|
||||
TextureAtlasSprite sprite = null;
|
||||
|
||||
BlockRenderLayer originalLayer = MinecraftForgeClient.getRenderLayer();
|
||||
|
||||
try {
|
||||
for (BlockRenderLayer layer : BlockRenderLayer.values()) {
|
||||
ForgeHooksClient.setRenderLayer(layer);
|
||||
|
||||
for (BakedQuad bakedQuad : coverModel.getQuads(coverState, facing, rand)) {
|
||||
return bakedQuad.getSprite();
|
||||
}
|
||||
|
||||
for (BakedQuad bakedQuad : coverModel.getQuads(coverState, null, rand)) {
|
||||
if (sprite == null) {
|
||||
sprite = bakedQuad.getSprite();
|
||||
}
|
||||
|
||||
if (bakedQuad.getFace() == facing) {
|
||||
return bakedQuad.getSprite();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// NO OP
|
||||
} finally {
|
||||
ForgeHooksClient.setRenderLayer(originalLayer);
|
||||
}
|
||||
|
||||
if (sprite == null) {
|
||||
try {
|
||||
sprite = coverModel.getParticleTexture();
|
||||
} catch (Exception e) {
|
||||
// NO OP
|
||||
}
|
||||
}
|
||||
|
||||
if (sprite == null) {
|
||||
sprite = Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite();
|
||||
}
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public ItemCameraTransforms getItemCameraTransforms() {
|
||||
return base.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides() {
|
||||
return base.getOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion(IBlockState state) {
|
||||
return base.isAmbientOcclusion(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) {
|
||||
return base.handlePerspective(cameraTransformType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion() {
|
||||
return base.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return base.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer() {
|
||||
return base.isBuiltInRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture() {
|
||||
return base.getParticleTexture();
|
||||
}
|
||||
}
|
@@ -0,0 +1,126 @@
|
||||
package com.raoulvdberge.refinedstorage.render.model.baked;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager;
|
||||
import com.raoulvdberge.refinedstorage.item.ItemCover;
|
||||
import com.raoulvdberge.refinedstorage.render.QuadBuilder;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BakedModelCover implements IBakedModel {
|
||||
@Nullable
|
||||
private ItemStack stack;
|
||||
private IBakedModel base;
|
||||
|
||||
public BakedModelCover(IBakedModel base, @Nullable ItemStack stack) {
|
||||
this.base = base;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
|
||||
List<BakedQuad> quads = new ArrayList<>(base.getQuads(state, side, rand));
|
||||
|
||||
TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite();
|
||||
|
||||
if (stack != null) {
|
||||
ItemStack item = ItemCover.getItem(stack);
|
||||
|
||||
if (!item.isEmpty()) {
|
||||
IBlockState coverState = CoverManager.getBlockState(item);
|
||||
|
||||
if (coverState != null) {
|
||||
IBakedModel coverModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(coverState);
|
||||
|
||||
sprite = BakedModelCableCover.getSprite(coverModel, coverState, side, rand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM)
|
||||
.setFrom(0, 0, 0)
|
||||
.setTo(16, 16, 2)
|
||||
|
||||
.addFace(EnumFacing.UP, 16, 0, 2, 0, sprite)
|
||||
.addFace(EnumFacing.DOWN, 0, 16, 14, 16, sprite)
|
||||
.addFace(EnumFacing.EAST, 14, 16, 0, 16, sprite)
|
||||
.addFace(EnumFacing.WEST, 0, 2, 0, 16, sprite)
|
||||
|
||||
.addFace(EnumFacing.NORTH, 0, 16, 0, 16, sprite)
|
||||
.addFace(EnumFacing.SOUTH, 0, 16, 0, 16, sprite)
|
||||
|
||||
.bake()
|
||||
);
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms() {
|
||||
return base.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides() {
|
||||
if (stack != null) {
|
||||
return base.getOverrides();
|
||||
}
|
||||
|
||||
return new ItemOverrideList(Collections.emptyList()) {
|
||||
@Override
|
||||
public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) {
|
||||
return new BakedModelCover(base, stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion(IBlockState state) {
|
||||
return base.isAmbientOcclusion(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) {
|
||||
Pair<? extends IBakedModel, Matrix4f> matrix = base.handlePerspective(cameraTransformType);
|
||||
Pair<? extends IBakedModel, Matrix4f> bakedModel = ForgeHooksClient.handlePerspective(this, cameraTransformType);
|
||||
|
||||
return Pair.of(bakedModel.getKey(), matrix.getRight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion() {
|
||||
return base.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return base.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer() {
|
||||
return base.isBuiltInRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture() {
|
||||
return base.getParticleTexture();
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model.baked;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model.baked;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model.baked;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternRenderHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
@@ -75,7 +75,7 @@ public class BakedModelPattern implements IBakedModel {
|
||||
public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) {
|
||||
CraftingPattern pattern = ItemPattern.getPatternFromCache(world, stack);
|
||||
|
||||
if (canDisplayPatternOutput(stack, pattern)) {
|
||||
if (canDisplayOutput(stack, pattern)) {
|
||||
return Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(pattern.getOutputs().get(0), world, entity);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class BakedModelPattern implements IBakedModel {
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean canDisplayPatternOutput(ItemStack patternStack, CraftingPattern pattern) {
|
||||
public static boolean canDisplayOutput(ItemStack patternStack, CraftingPattern pattern) {
|
||||
if (pattern.isValid() && pattern.getOutputs().size() == 1) {
|
||||
for (ICraftingPatternRenderHandler renderHandler : API.instance().getPatternRenderHandlers()) {
|
||||
if (renderHandler.canRenderOutput(patternStack)) {
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model.baked;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.block.state.IBlockState;
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.model.loader;
|
||||
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.statemapper;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
@@ -1,4 +1,4 @@
|
||||
package com.raoulvdberge.refinedstorage.render;
|
||||
package com.raoulvdberge.refinedstorage.render.tesr;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.tile.TileStorageMonitor;
|
@@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper;
|
||||
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
|
||||
@@ -15,6 +16,7 @@ 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.common.util.Constants;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -24,6 +26,7 @@ public abstract class TileNode<N extends NetworkNode> extends TileBase implement
|
||||
public static final TileDataParameter<Integer, TileNode> REDSTONE_MODE = RedstoneMode.createParameter();
|
||||
|
||||
protected static final String NBT_ACTIVE = "Active";
|
||||
private static final String NBT_COVERS = "Cover";
|
||||
|
||||
private N clientNode;
|
||||
|
||||
@@ -46,6 +49,10 @@ public abstract class TileNode<N extends NetworkNode> extends TileBase implement
|
||||
public NBTTagCompound writeUpdate(NBTTagCompound tag) {
|
||||
super.writeUpdate(tag);
|
||||
|
||||
if (getNode() instanceof ICoverable) {
|
||||
tag.setTag(NBT_COVERS, ((ICoverable) getNode()).getCoverManager().writeToNbt());
|
||||
}
|
||||
|
||||
tag.setBoolean(NBT_ACTIVE, getNode().getNetwork() != null && getNode().canUpdate());
|
||||
|
||||
return tag;
|
||||
@@ -54,6 +61,10 @@ public abstract class TileNode<N extends NetworkNode> extends TileBase implement
|
||||
public void readUpdate(NBTTagCompound tag) {
|
||||
super.readUpdate(tag);
|
||||
|
||||
if (getNode() instanceof ICoverable && tag.hasKey(NBT_COVERS)) {
|
||||
((ICoverable) getNode()).getCoverManager().readFromNbt(tag.getTagList(NBT_COVERS, Constants.NBT.TAG_COMPOUND));
|
||||
}
|
||||
|
||||
getNode().setActive(tag.getBoolean(NBT_ACTIVE));
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"textures": {
|
||||
"cable": "refinedstorage:blocks/cable",
|
||||
"line": "refinedstorage:blocks/generic_grey"
|
||||
},
|
||||
"model": "refinedstorage:cable_core",
|
||||
"uvlock": true
|
||||
},
|
||||
"variants": {
|
||||
"inventory": [
|
||||
{
|
||||
"model": "refinedstorage:cover",
|
||||
"transform": "forge:default-block"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -290,6 +290,7 @@ item.refinedstorage:network_card.name=Network Card2
|
||||
item.refinedstorage:security_card.name=Security Card
|
||||
item.refinedstorage:security_card.owner=Bound to: %s
|
||||
item.refinedstorage:cutting_tool.name=Cutting Tool
|
||||
item.refinedstorage:cover.name=Cover
|
||||
|
||||
commands.refinedstorage.createdisk.usage=/createdisk <player> <item> <metadata> <id>
|
||||
commands.refinedstorage.createdisk.error.notADisk=The given disk item is not a disk.
|
||||
|
143
src/main/resources/assets/refinedstorage/models/block/cover.json
Normal file
143
src/main/resources/assets/refinedstorage/models/block/cover.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)",
|
||||
"elements": [
|
||||
{
|
||||
"name": "Line1",
|
||||
"from": [
|
||||
7.0,
|
||||
7.0,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
9.0,
|
||||
6.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"texture": "#line",
|
||||
"uv": [
|
||||
0.0,
|
||||
0.0,
|
||||
4.0,
|
||||
4.0
|
||||
]
|
||||
},
|
||||
"east": {
|
||||
"texture": "#line",
|
||||
"uv": [
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
4.0
|
||||
]
|
||||
},
|
||||
"south": {
|
||||
"texture": "#line",
|
||||
"uv": [
|
||||
0.0,
|
||||
0.0,
|
||||
4.0,
|
||||
4.0
|
||||
]
|
||||
},
|
||||
"west": {
|
||||
"texture": "#line",
|
||||
"uv": [
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
4.0
|
||||
]
|
||||
},
|
||||
"up": {
|
||||
"texture": "#line",
|
||||
"uv": [
|
||||
0.0,
|
||||
0.0,
|
||||
4.0,
|
||||
2.0
|
||||
]
|
||||
},
|
||||
"down": {
|
||||
"texture": "#line",
|
||||
"uv": [
|
||||
0.0,
|
||||
0.0,
|
||||
4.0,
|
||||
2.0
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Core",
|
||||
"from": [
|
||||
6.0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"to": [
|
||||
10.0,
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"texture": "#cable",
|
||||
"uv": [
|
||||
6.0,
|
||||
6.0,
|
||||
10.0,
|
||||
10.0
|
||||
]
|
||||
},
|
||||
"east": {
|
||||
"texture": "#cable",
|
||||
"uv": [
|
||||
6.0,
|
||||
6.0,
|
||||
10.0,
|
||||
10.0
|
||||
]
|
||||
},
|
||||
"south": {
|
||||
"texture": "#cable",
|
||||
"uv": [
|
||||
6.0,
|
||||
6.0,
|
||||
10.0,
|
||||
10.0
|
||||
]
|
||||
},
|
||||
"west": {
|
||||
"texture": "#cable",
|
||||
"uv": [
|
||||
6.0,
|
||||
6.0,
|
||||
10.0,
|
||||
10.0
|
||||
]
|
||||
},
|
||||
"up": {
|
||||
"texture": "#cable",
|
||||
"uv": [
|
||||
6.0,
|
||||
6.0,
|
||||
10.0,
|
||||
10.0
|
||||
]
|
||||
},
|
||||
"down": {
|
||||
"texture": "#cable",
|
||||
"uv": [
|
||||
6.0,
|
||||
6.0,
|
||||
10.0,
|
||||
10.0
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user