Skip to content

Instantly share code, notes, and snippets.

@Unh0lyTigg
Created August 16, 2014 10:54
Show Gist options
  • Save Unh0lyTigg/30927842891c4872a64d to your computer and use it in GitHub Desktop.
Save Unh0lyTigg/30927842891c4872a64d to your computer and use it in GitHub Desktop.
package org.unh0lytigg.mobeds;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDirectional;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.Direction;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import com.google.common.collect.Lists;
public class BlockCustomBed extends BlockDirectional implements ITileEntityProvider {
protected BlockCustomBed() {
super(Material.cloth);
setBlockName("bed");
setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5625F, 1.0F);
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
return new TileCustomBed();
}
@Override
public void registerBlockIcons(IIconRegister map) {} // NOOP - custom renderer
@SuppressWarnings("rawtypes")
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int sideHit, float hitX, float hitY, float hitZ) {
if (world.isRemote)
return true;
int meta = world.getBlockMetadata(x, y, z);
if (!isBlockHeadOfBed(meta)) {
int direction = getDirection(meta);
x += Direction.offsetX[direction];
z += Direction.offsetZ[direction];
if (world.getBlock(x, y, z) != this)
return true;
meta = world.getBlockMetadata(x, y, z);
}
if (world.provider.canRespawnHere()) {
if (isBedOccupied(meta)) {
EntityPlayer player2 = null;
Iterator iter = world.playerEntities.iterator();
while (iter.hasNext()) {
EntityPlayer player3 = (EntityPlayer)iter.next();
if (player3.isPlayerSleeping()) {
ChunkCoordinates coords = player3.playerLocation;
if (coords.posX == x && coords.posY == y && coords.posZ == z)
player2 = player3;
}
}
if (player2 != null) {
player.addChatComponentMessage(new ChatComponentTranslation("tile.bed.occupied", new Object[0]));
return true;
}
updateMetadata(world, x, y, z, false);
}
EntityPlayer.EnumStatus status = player.sleepInBedAt(x, y, z);
if (status == EntityPlayer.EnumStatus.OK) {
updateMetadata(world, x, y, z, true);
return true;
} else {
if (status == EntityPlayer.EnumStatus.NOT_POSSIBLE_NOW)
player.addChatComponentMessage(new ChatComponentTranslation("tile.bed.noSleep", new Object[0]));
else
player.addChatComponentMessage(new ChatComponentTranslation("tile.bed.notSafe", new Object[0]));
return true;
}
} else {
player.addChatComponentMessage(new ChatComponentTranslation("tile.bed.noRespawnAvailable", new Object[0]));
return true;
}
}
public static boolean isBlockHeadOfBed(int meta) {
return (meta & 0x8) != 0;
}
public static boolean isBedOccupied(int meta) {
return (meta & 0x4) != 0;
}
public static void updateMetadata(World world, int x, int y, int z, boolean occupied) {
int meta = world.getBlockMetadata(x, y, z);
if (occupied)
meta |= 4;
else
meta &= -5;
world.setBlockMetadataWithNotify(x, y, z, meta, 4);
}
@Override
public boolean renderAsNormalBlock() {
return false;
}
@Override
public boolean isNormalCube() {
return false;
}
@Override
public boolean isBlockNormalCube() {
return false;
}
@Override
public boolean isOpaqueCube() {
return false;
}
public void onNeighborBlockChange(World world, int x, int y, int z, Block b) {
int meta = world.getBlockMetadata(x, y, z);
int direction = getDirection(meta);
if (isBlockHeadOfBed(meta)) {
if (world.getBlock(x - Direction.offsetX[direction], y, z - Direction.offsetZ[direction]) != this)
world.setBlockToAir(x, y, z);
} else if (world.getBlock(x + Direction.offsetX[direction], y, z + Direction.offsetZ[direction]) != this) {
world.setBlockToAir(x, y, z);
if (!world.isRemote)
this.dropBlockAsItem(world, x, y, z, meta, 0);
}
}
@Override
public Item getItemDropped(int meta, Random random, int fortune) {
return isBlockHeadOfBed(meta) ? Item.getItemById(0) : MoBeds.itembed;
}
@Override
public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int metadata, int fortune) {
ArrayList<ItemStack> items = Lists.newArrayList();
Item item = isBlockHeadOfBed(metadata) ? Item.getItemById(0) : MoBeds.itembed;
if (item == MoBeds.itembed) {
items.add(new ItemStack(item, 1, ((TileCustomBed)world.getTileEntity(x, y, z)).getColoring()));
}
return items;
}
@Override
public void breakBlock(World w, int x, int y, int z, Block b, int m) {
dropBlockAsItem(w, x, y, z, m, 0);
super.breakBlock(w, x, y, z, b, m);
}
@Override
public void onBlockDestroyedByPlayer(World p_149664_1_, int p_149664_2_, int p_149664_3_, int p_149664_4_, int p_149664_5_) {
super.onBlockDestroyedByPlayer(p_149664_1_, p_149664_2_, p_149664_3_, p_149664_4_, p_149664_5_);
}
@Override
public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z, boolean willHarvest) {
return super.removedByPlayer(world, player, x, y, z, willHarvest);
}
@Override
public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) {
setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5625F, 1.0F);
}
@Override
public AxisAlignedBB getSelectedBoundingBoxFromPool(World w, int x, int y, int z) {
int meta = w.getBlockMetadata(x, y, z);
int direction = getDirection(meta);
ForgeDirection fDir = convertToForge(direction);
if (isBlockHeadOfBed(meta))
fDir = fDir.getOpposite();
return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ).addCoord(fDir.offsetX, fDir.offsetY, fDir.offsetZ);
}
private static ForgeDirection convertToForge(int direction) {
switch(direction) {
case 0:
return ForgeDirection.SOUTH;
case 1:
return ForgeDirection.WEST;
case 2:
return ForgeDirection.NORTH;
case 3:
return ForgeDirection.EAST;
}
return ForgeDirection.UNKNOWN;
}
@Override
public Item getItem(World w, int x, int y, int z) {
return MoBeds.itembed;
}
public void onBlockHarvested(World w, int x, int y, int z, int m, EntityPlayer p) {
if (p.capabilities.isCreativeMode && isBlockHeadOfBed(m)) {
int d = getDirection(m);
x -= Direction.offsetX[d];
z -= Direction.offsetZ[d];
if (w.getBlock(x, y, z) == this)
w.setBlockToAir(x, y, z);
}
}
@Override
public int getRenderType() {
return ProxyClient.BED_RENDER_ID;
}
@Override
public boolean hasTileEntity(int metadata) {
return true;
}
@Override
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) {
System.out.println("Pick block... remote:" + world.isRemote);
TileCustomBed bed = (TileCustomBed)world.getTileEntity(x, y, z);
System.out.println("\t" + bed.getBlanketColoring() + " / " + bed.getPulloverColoring() + " / " + bed.getPillowColoring());
return new ItemStack(MoBeds.itembed, 1, ((TileCustomBed)world.getTileEntity(x, y, z)).getColoring());
}
@Override
public int getDamageValue(World world, int x, int y, int z) {
return ((TileCustomBed)world.getTileEntity(x, y, z)).getColoring();
}
public boolean isBed(IBlockAccess world, int x, int y, int z, EntityLivingBase player){
return true;
}
@Override
public void setBedOccupied(IBlockAccess world, int x, int y, int z, EntityPlayer player, boolean occupied) {
((TileCustomBed)world.getTileEntity(x, y, z)).setOccupied(occupied);
int meta = world.getBlockMetadata(x, y, z);
int direction = getDirection(meta);
ForgeDirection fDir = convertToForge(direction);
if (isBlockHeadOfBed(meta))
fDir = fDir.getOpposite();
((TileCustomBed)world.getTileEntity(x + fDir.offsetX, y, z + fDir.offsetZ)).setOccupied(occupied);
}
}
package org.unh0lytigg.mobeds;
import java.util.List;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class ItemCustomBed extends Item {
private IIcon[] icons = new IIcon[4096];
private static String[] iconnamecache = new String[4096];
private static String[] infonamecache = new String[4096];
public ItemCustomBed() {
super();
setUnlocalizedName("bed");
setCreativeTab(MoBeds.tab);
setMaxDamage(0);
setHasSubtypes(true);
setMaxStackSize(16);
}
@Override
public void registerIcons(IIconRegister map) {
for (int i = 0; i < 4096; i++) {
icons[i] = map.registerIcon(doIconLookup(i));
}
}
@Override
public IIcon getIcon(ItemStack stack, int pass) {
return icons[stack.getItemDamage()];
}
@Override
public IIcon getIconFromDamage(int meta) {
return icons[meta];
}
@Override
public IIcon getIconIndex(ItemStack stack) {
return icons[stack.getItemDamage()];
}
private static String doIconLookup(int meta) {
if (iconnamecache[meta] != null)
return iconnamecache[meta];
return (iconnamecache[meta] = doColorsLookup(meta, "mobeds:bed-", "-", false));
}
private static String doNameLookup(int meta) {
if (infonamecache[meta] != null)
return infonamecache[meta];
return (infonamecache[meta] = doColorsLookup(meta, "", " / ", true));
}
private static String doColorsLookup(int meta, String prefix, String sep, boolean camelcase) {
StringBuilder b = new StringBuilder(prefix);
int l2 = meta & 15;
int l1 = (meta >> 4) & 15;
int l0 = (meta >> 8) & 15;
b.append(doCamelCase(dyeColorNames[l0], camelcase)).append(sep).append(doCamelCase(dyeColorNames[l1], camelcase)).append(sep).append(doCamelCase(dyeColorNames[l2], camelcase));
return b.toString();
}
private static String doCamelCase(String raw, boolean camelcase) {
return camelcase ? (raw.substring(0, 1).toUpperCase() + raw.substring(1, raw.length())) : raw;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void addInformation(ItemStack item, EntityPlayer player, List lore, boolean advancedToolTips) {
super.addInformation(item, player, lore, advancedToolTips);
if (advancedToolTips)
lore.add(doNameLookup(item.getItemDamage()));
}
public static final String[] dyeColorNames = {"white", "orange", "magenta", "lightBlue", "yellow", "lime", "pink", "gray", "lightGray", "cyan", "purple", "blue", "brown", "green", "red", "black"};
@Override
public boolean onItemUse(ItemStack item, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) {
if (world.isRemote)
return true;
if (side != 1)
return false;
++y;
BlockCustomBed blockCustomBed = MoBeds.blockbed;
int direction = MathHelper.floor_double((double)(player.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
byte a = 0;
byte b = 0;
switch(direction) {
case 0: b=1; break;
case 1: a=-1; break;
case 2: b=-1; break;
case 3: a=1; break;
}
if (player.canPlayerEdit(x, y, z, side, item) && player.canPlayerEdit(x + a, y, z + b, side, item)) {
if (world.isAirBlock(x, y, z) && world.isAirBlock(x + a, y, z + b)) {
world.setBlock(x, y, z, blockCustomBed, direction, 3);
if (world.getBlock(x, y, z) == blockCustomBed) {
world.setBlock(x+a, y, z+b, blockCustomBed, direction + 8, 3);
if (!world.isRemote) {
((TileCustomBed)(world.getTileEntity(x, y, z))).setColoring(item.getItemDamage());
((TileCustomBed)(world.getTileEntity(x+a, y, z+b))).setColoring(item.getItemDamage());
}
}
--item.stackSize;
return true;
}
return false;
}
return false;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void getSubItems(Item item, CreativeTabs tab, List items) {
for (int i = 0; i < 4096; i++)
items.add(new ItemStack(this, 1, i));
}
}
package org.unh0lytigg.mobeds;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
public class TileCustomBed extends TileEntity {
private int colorVal;
public String getBlanketColoring() {
return ItemCustomBed.dyeColorNames[colorVal & 15];
}
public String getPulloverColoring() {
return ItemCustomBed.dyeColorNames[(colorVal >> 4) & 15];
}
public String getPillowColoring() {
return ItemCustomBed.dyeColorNames[(colorVal >> 8) & 15];
}
public void setColoring(int coloring) {
this.colorVal = coloring;
if (!worldObj.isRemote) {
markDirty();
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}
public int getColoring() {
return this.colorVal;
}
@Override
public Packet getDescriptionPacket() {
NBTTagCompound tag = new NBTTagCompound();
writeToNBT(tag);
return new S35PacketUpdateTileEntity(xCoord, xCoord, zCoord, 0, tag);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
readFromNBT(pkt.func_148857_g());
System.out.println("datapacket recieved | remote=" + worldObj.isRemote);
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setInteger("bedcolor", colorVal);
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
colorVal = tag.getInteger("bedcolor");
}
public void setOccupied(boolean occupied) {
BlockCustomBed.updateMetadata(worldObj, xCoord, yCoord, zCoord, occupied);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment