base mod created

This commit is contained in:
Mohammad-Ali Minaie
2018-10-08 09:07:47 -04:00
parent 0a7700c356
commit b86dedad2f
7848 changed files with 584664 additions and 1 deletions

View File

@@ -0,0 +1,14 @@
package net.minecraft.block.state;
public enum BlockFaceShape
{
SOLID,
BOWL,
CENTER_SMALL,
MIDDLE_POLE_THIN,
CENTER,
MIDDLE_POLE,
CENTER_BIG,
MIDDLE_POLE_THICK,
UNDEFINED;
}

View File

@@ -0,0 +1,235 @@
package net.minecraft.block.state;
import com.google.common.collect.Lists;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockPistonBase;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockPistonStructureHelper
{
private final World world;
private final BlockPos pistonPos;
private final BlockPos blockToMove;
private final EnumFacing moveDirection;
/** This is a List<BlockPos> of all blocks that will be moved by the piston. */
private final List<BlockPos> toMove = Lists.<BlockPos>newArrayList();
/** This is a List<BlockPos> of blocks that will be destroyed when a piston attempts to move them. */
private final List<BlockPos> toDestroy = Lists.<BlockPos>newArrayList();
public BlockPistonStructureHelper(World worldIn, BlockPos posIn, EnumFacing pistonFacing, boolean extending)
{
this.world = worldIn;
this.pistonPos = posIn;
if (extending)
{
this.moveDirection = pistonFacing;
this.blockToMove = posIn.offset(pistonFacing);
}
else
{
this.moveDirection = pistonFacing.getOpposite();
this.blockToMove = posIn.offset(pistonFacing, 2);
}
}
public boolean canMove()
{
this.toMove.clear();
this.toDestroy.clear();
IBlockState iblockstate = this.world.getBlockState(this.blockToMove);
if (!BlockPistonBase.canPush(iblockstate, this.world, this.blockToMove, this.moveDirection, false, this.moveDirection))
{
if (iblockstate.getMobilityFlag() == EnumPushReaction.DESTROY)
{
this.toDestroy.add(this.blockToMove);
return true;
}
else
{
return false;
}
}
else if (!this.addBlockLine(this.blockToMove, this.moveDirection))
{
return false;
}
else
{
for (int i = 0; i < this.toMove.size(); ++i)
{
BlockPos blockpos = this.toMove.get(i);
if (this.world.getBlockState(blockpos).getBlock().isStickyBlock(this.world.getBlockState(blockpos)) && !this.addBranchingBlocks(blockpos))
{
return false;
}
}
return true;
}
}
private boolean addBlockLine(BlockPos origin, EnumFacing p_177251_2_)
{
IBlockState iblockstate = this.world.getBlockState(origin);
Block block = iblockstate.getBlock();
if (iblockstate.getBlock().isAir(iblockstate, this.world, origin))
{
return true;
}
else if (!BlockPistonBase.canPush(iblockstate, this.world, origin, this.moveDirection, false, p_177251_2_))
{
return true;
}
else if (origin.equals(this.pistonPos))
{
return true;
}
else if (this.toMove.contains(origin))
{
return true;
}
else
{
int i = 1;
if (i + this.toMove.size() > 12)
{
return false;
}
else
{
while (block.isStickyBlock(iblockstate))
{
BlockPos blockpos = origin.offset(this.moveDirection.getOpposite(), i);
iblockstate = this.world.getBlockState(blockpos);
block = iblockstate.getBlock();
if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos) || !BlockPistonBase.canPush(iblockstate, this.world, blockpos, this.moveDirection, false, this.moveDirection.getOpposite()) || blockpos.equals(this.pistonPos))
{
break;
}
++i;
if (i + this.toMove.size() > 12)
{
return false;
}
}
int i1 = 0;
for (int j = i - 1; j >= 0; --j)
{
this.toMove.add(origin.offset(this.moveDirection.getOpposite(), j));
++i1;
}
int j1 = 1;
while (true)
{
BlockPos blockpos1 = origin.offset(this.moveDirection, j1);
int k = this.toMove.indexOf(blockpos1);
if (k > -1)
{
this.reorderListAtCollision(i1, k);
for (int l = 0; l <= k + i1; ++l)
{
BlockPos blockpos2 = this.toMove.get(l);
if (this.world.getBlockState(blockpos2).getBlock().isStickyBlock(this.world.getBlockState(blockpos2)) && !this.addBranchingBlocks(blockpos2))
{
return false;
}
}
return true;
}
iblockstate = this.world.getBlockState(blockpos1);
if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos1))
{
return true;
}
if (!BlockPistonBase.canPush(iblockstate, this.world, blockpos1, this.moveDirection, true, this.moveDirection) || blockpos1.equals(this.pistonPos))
{
return false;
}
if (iblockstate.getMobilityFlag() == EnumPushReaction.DESTROY)
{
this.toDestroy.add(blockpos1);
return true;
}
if (this.toMove.size() >= 12)
{
return false;
}
this.toMove.add(blockpos1);
++i1;
++j1;
}
}
}
}
private void reorderListAtCollision(int p_177255_1_, int p_177255_2_)
{
List<BlockPos> list = Lists.<BlockPos>newArrayList();
List<BlockPos> list1 = Lists.<BlockPos>newArrayList();
List<BlockPos> list2 = Lists.<BlockPos>newArrayList();
list.addAll(this.toMove.subList(0, p_177255_2_));
list1.addAll(this.toMove.subList(this.toMove.size() - p_177255_1_, this.toMove.size()));
list2.addAll(this.toMove.subList(p_177255_2_, this.toMove.size() - p_177255_1_));
this.toMove.clear();
this.toMove.addAll(list);
this.toMove.addAll(list1);
this.toMove.addAll(list2);
}
private boolean addBranchingBlocks(BlockPos fromPos)
{
for (EnumFacing enumfacing : EnumFacing.values())
{
if (enumfacing.getAxis() != this.moveDirection.getAxis() && !this.addBlockLine(fromPos.offset(enumfacing), enumfacing))
{
return false;
}
}
return true;
}
/**
* Returns a List<BlockPos> of all the blocks that are being moved by the piston.
*/
public List<BlockPos> getBlocksToMove()
{
return this.toMove;
}
/**
* Returns an List<BlockPos> of all the blocks that are being destroyed by the piston.
*/
public List<BlockPos> getBlocksToDestroy()
{
return this.toDestroy;
}
}

View File

@@ -0,0 +1,89 @@
package net.minecraft.block.state;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
public abstract class BlockStateBase implements IBlockState
{
private static final Joiner COMMA_JOINER = Joiner.on(',');
private static final Function < Entry < IProperty<?>, Comparable<? >> , String > MAP_ENTRY_TO_STRING = new Function < Entry < IProperty<?>, Comparable<? >> , String > ()
{
@Nullable
public String apply(@Nullable Entry < IProperty<?>, Comparable<? >> p_apply_1_)
{
if (p_apply_1_ == null)
{
return "<NULL>";
}
else
{
IProperty<?> iproperty = (IProperty)p_apply_1_.getKey();
return iproperty.getName() + "=" + this.getPropertyName(iproperty, p_apply_1_.getValue());
}
}
private <T extends Comparable<T>> String getPropertyName(IProperty<T> property, Comparable<?> entry)
{
return property.getName((T)entry);
}
};
/**
* Create a version of this BlockState with the given property cycled to the next value in order. If the property
* was at the highest possible value, it is set to the lowest one instead.
*/
public <T extends Comparable<T>> IBlockState cycleProperty(IProperty<T> property)
{
return this.withProperty(property, cyclePropertyValue(property.getAllowedValues(), this.getValue(property)));
}
/**
* Helper method for cycleProperty.
*/
protected static <T> T cyclePropertyValue(Collection<T> values, T currentValue)
{
Iterator<T> iterator = values.iterator();
while (iterator.hasNext())
{
if (iterator.next().equals(currentValue))
{
if (iterator.hasNext())
{
return iterator.next();
}
return values.iterator().next();
}
}
return iterator.next();
}
public String toString()
{
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append(Block.REGISTRY.getNameForObject(this.getBlock()));
if (!this.getProperties().isEmpty())
{
stringbuilder.append("[");
COMMA_JOINER.appendTo(stringbuilder, Iterables.transform(this.getProperties().entrySet(), MAP_ENTRY_TO_STRING));
stringbuilder.append("]");
}
return stringbuilder.toString();
}
@Nullable
public com.google.common.collect.ImmutableTable<IProperty<?>, Comparable<?>, IBlockState> getPropertyValueTable()
{
return null;
}
}

View File

@@ -0,0 +1,610 @@
package net.minecraft.block.state;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.google.common.collect.UnmodifiableIterator;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.MapPopulator;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Cartesian;
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.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockStateContainer
{
private static final Pattern NAME_PATTERN = Pattern.compile("^[a-z0-9_]+$");
private static final Function < IProperty<?>, String > GET_NAME_FUNC = new Function < IProperty<?>, String > ()
{
@Nullable
public String apply(@Nullable IProperty<?> p_apply_1_)
{
return p_apply_1_ == null ? "<NULL>" : p_apply_1_.getName();
}
};
private final Block block;
private final ImmutableSortedMap < String, IProperty<? >> properties;
private final ImmutableList<IBlockState> validStates;
public BlockStateContainer(Block blockIn, IProperty<?>... properties)
{
this(blockIn, properties, null);
}
protected StateImplementation createState(Block block, ImmutableMap<IProperty<?>, Comparable<?>> properties, @Nullable ImmutableMap<net.minecraftforge.common.property.IUnlistedProperty<?>, java.util.Optional<?>> unlistedProperties)
{
return new StateImplementation(block, properties);
}
protected BlockStateContainer(Block blockIn, IProperty<?>[] properties, ImmutableMap<net.minecraftforge.common.property.IUnlistedProperty<?>, java.util.Optional<?>> unlistedProperties)
{
this.block = blockIn;
Map < String, IProperty<? >> map = Maps. < String, IProperty<? >> newHashMap();
for (IProperty<?> iproperty : properties)
{
validateProperty(blockIn, iproperty);
map.put(iproperty.getName(), iproperty);
}
this.properties = ImmutableSortedMap.copyOf(map);
Map < Map < IProperty<?>, Comparable<? >> , BlockStateContainer.StateImplementation > map2 = Maps. < Map < IProperty<?>, Comparable<? >> , BlockStateContainer.StateImplementation > newLinkedHashMap();
List<BlockStateContainer.StateImplementation> list1 = Lists.<BlockStateContainer.StateImplementation>newArrayList();
for (List < Comparable<? >> list : Cartesian.cartesianProduct(this.getAllowedValues()))
{
Map < IProperty<?>, Comparable<? >> map1 = MapPopulator. < IProperty<?>, Comparable<? >> createMap(this.properties.values(), list);
BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation = createState(blockIn, ImmutableMap.copyOf(map1), unlistedProperties);
map2.put(map1, blockstatecontainer$stateimplementation);
list1.add(blockstatecontainer$stateimplementation);
}
for (BlockStateContainer.StateImplementation blockstatecontainer$stateimplementation1 : list1)
{
blockstatecontainer$stateimplementation1.buildPropertyValueTable(map2);
}
this.validStates = ImmutableList.<IBlockState>copyOf(list1);
}
public static <T extends Comparable<T>> String validateProperty(Block block, IProperty<T> property)
{
String s = property.getName();
if (!NAME_PATTERN.matcher(s).matches())
{
throw new IllegalArgumentException("Block: " + block.getClass() + " has invalidly named property: " + s);
}
else
{
for (T t : property.getAllowedValues())
{
String s1 = property.getName(t);
if (!NAME_PATTERN.matcher(s1).matches())
{
throw new IllegalArgumentException("Block: " + block.getClass() + " has property: " + s + " with invalidly named value: " + s1);
}
}
return s;
}
}
public ImmutableList<IBlockState> getValidStates()
{
return this.validStates;
}
private List < Iterable < Comparable<? >>> getAllowedValues()
{
List < Iterable < Comparable<? >>> list = Lists. < Iterable < Comparable<? >>> newArrayList();
ImmutableCollection < IProperty<? >> immutablecollection = this.properties.values();
UnmodifiableIterator unmodifiableiterator = immutablecollection.iterator();
while (unmodifiableiterator.hasNext())
{
IProperty<?> iproperty = (IProperty)unmodifiableiterator.next();
list.add(((IProperty)iproperty).getAllowedValues());
}
return list;
}
public IBlockState getBaseState()
{
return (IBlockState)this.validStates.get(0);
}
public Block getBlock()
{
return this.block;
}
public Collection < IProperty<? >> getProperties()
{
return this.properties.values();
}
public String toString()
{
return MoreObjects.toStringHelper(this).add("block", Block.REGISTRY.getNameForObject(this.block)).add("properties", Iterables.transform(this.properties.values(), GET_NAME_FUNC)).toString();
}
@Nullable
public IProperty<?> getProperty(String propertyName)
{
return (IProperty)this.properties.get(propertyName);
}
public static class StateImplementation extends BlockStateBase
{
private final Block block;
private final ImmutableMap < IProperty<?>, Comparable<? >> properties;
protected ImmutableTable < IProperty<?>, Comparable<?>, IBlockState > propertyValueTable;
protected StateImplementation(Block blockIn, ImmutableMap < IProperty<?>, Comparable<? >> propertiesIn)
{
this.block = blockIn;
this.properties = propertiesIn;
}
protected StateImplementation(Block blockIn, ImmutableMap<IProperty<?>, Comparable<?>> propertiesIn, ImmutableTable<IProperty<?>, Comparable<?>, IBlockState> propertyValueTable)
{
this.block = blockIn;
this.properties = propertiesIn;
this.propertyValueTable = propertyValueTable;
}
public Collection < IProperty<? >> getPropertyKeys()
{
return Collections. < IProperty<? >> unmodifiableCollection(this.properties.keySet());
}
/**
* Get the value of the given Property for this BlockState
*/
public <T extends Comparable<T>> T getValue(IProperty<T> property)
{
Comparable<?> comparable = (Comparable)this.properties.get(property);
if (comparable == null)
{
throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.block.getBlockState());
}
else
{
return (T)(property.getValueClass().cast(comparable));
}
}
/**
* Get a version of this BlockState with the given Property now set to the given value
*/
public <T extends Comparable<T>, V extends T> IBlockState withProperty(IProperty<T> property, V value)
{
Comparable<?> comparable = (Comparable)this.properties.get(property);
if (comparable == null)
{
throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.block.getBlockState());
}
else if (comparable == value)
{
return this;
}
else
{
IBlockState iblockstate = (IBlockState)this.propertyValueTable.get(property, value);
if (iblockstate == null)
{
throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on block " + Block.REGISTRY.getNameForObject(this.block) + ", it is not an allowed value");
}
else
{
return iblockstate;
}
}
}
public ImmutableMap < IProperty<?>, Comparable<? >> getProperties()
{
return this.properties;
}
public Block getBlock()
{
return this.block;
}
public boolean equals(Object p_equals_1_)
{
return this == p_equals_1_;
}
public int hashCode()
{
return this.properties.hashCode();
}
public void buildPropertyValueTable(Map < Map < IProperty<?>, Comparable<? >> , BlockStateContainer.StateImplementation > map)
{
if (this.propertyValueTable != null)
{
throw new IllegalStateException();
}
else
{
Table < IProperty<?>, Comparable<?>, IBlockState > table = HashBasedTable. < IProperty<?>, Comparable<?>, IBlockState > create();
UnmodifiableIterator unmodifiableiterator = this.properties.entrySet().iterator();
while (unmodifiableiterator.hasNext())
{
Entry < IProperty<?>, Comparable<? >> entry = (Entry)unmodifiableiterator.next();
IProperty<?> iproperty = (IProperty)entry.getKey();
for (Comparable<?> comparable : iproperty.getAllowedValues())
{
if (comparable != entry.getValue())
{
table.put(iproperty, comparable, map.get(this.getPropertiesWithValue(iproperty, comparable)));
}
}
}
this.propertyValueTable = ImmutableTable.copyOf(table);
}
}
private Map < IProperty<?>, Comparable<? >> getPropertiesWithValue(IProperty<?> property, Comparable<?> value)
{
Map < IProperty<?>, Comparable<? >> map = Maps. < IProperty<?>, Comparable<? >> newHashMap(this.properties);
map.put(property, value);
return map;
}
public Material getMaterial()
{
return this.block.getMaterial(this);
}
public boolean isFullBlock()
{
return this.block.isFullBlock(this);
}
public boolean canEntitySpawn(Entity entityIn)
{
return this.block.canEntitySpawn(this, entityIn);
}
public int getLightOpacity()
{
return this.block.getLightOpacity(this);
}
public int getLightValue()
{
return this.block.getLightValue(this);
}
@SideOnly(Side.CLIENT)
public boolean isTranslucent()
{
return this.block.isTranslucent(this);
}
public boolean useNeighborBrightness()
{
return this.block.getUseNeighborBrightness(this);
}
public MapColor getMapColor(IBlockAccess p_185909_1_, BlockPos p_185909_2_)
{
return this.block.getMapColor(this, p_185909_1_, p_185909_2_);
}
/**
* Returns the blockstate with the given rotation. If inapplicable, returns itself.
*/
public IBlockState withRotation(Rotation rot)
{
return this.block.withRotation(this, rot);
}
/**
* Returns the blockstate mirrored in the given way. If inapplicable, returns itself.
*/
public IBlockState withMirror(Mirror mirrorIn)
{
return this.block.withMirror(this, mirrorIn);
}
public boolean isFullCube()
{
return this.block.isFullCube(this);
}
@SideOnly(Side.CLIENT)
public boolean hasCustomBreakingProgress()
{
return this.block.hasCustomBreakingProgress(this);
}
public EnumBlockRenderType getRenderType()
{
return this.block.getRenderType(this);
}
@SideOnly(Side.CLIENT)
public int getPackedLightmapCoords(IBlockAccess source, BlockPos pos)
{
return this.block.getPackedLightmapCoords(this, source, pos);
}
@SideOnly(Side.CLIENT)
public float getAmbientOcclusionLightValue()
{
return this.block.getAmbientOcclusionLightValue(this);
}
public boolean isBlockNormalCube()
{
return this.block.isBlockNormalCube(this);
}
public boolean isNormalCube()
{
return this.block.isNormalCube(this);
}
public boolean canProvidePower()
{
return this.block.canProvidePower(this);
}
public int getWeakPower(IBlockAccess blockAccess, BlockPos pos, EnumFacing side)
{
return this.block.getWeakPower(this, blockAccess, pos, side);
}
public boolean hasComparatorInputOverride()
{
return this.block.hasComparatorInputOverride(this);
}
public int getComparatorInputOverride(World worldIn, BlockPos pos)
{
return this.block.getComparatorInputOverride(this, worldIn, pos);
}
public float getBlockHardness(World worldIn, BlockPos pos)
{
return this.block.getBlockHardness(this, worldIn, pos);
}
public float getPlayerRelativeBlockHardness(EntityPlayer player, World worldIn, BlockPos pos)
{
return this.block.getPlayerRelativeBlockHardness(this, player, worldIn, pos);
}
public int getStrongPower(IBlockAccess blockAccess, BlockPos pos, EnumFacing side)
{
return this.block.getStrongPower(this, blockAccess, pos, side);
}
public EnumPushReaction getMobilityFlag()
{
return this.block.getMobilityFlag(this);
}
public IBlockState getActualState(IBlockAccess blockAccess, BlockPos pos)
{
return this.block.getActualState(this, blockAccess, pos);
}
@SideOnly(Side.CLIENT)
public AxisAlignedBB getSelectedBoundingBox(World worldIn, BlockPos pos)
{
return this.block.getSelectedBoundingBox(this, worldIn, pos);
}
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess blockAccess, BlockPos pos, EnumFacing facing)
{
return this.block.shouldSideBeRendered(this, blockAccess, pos, facing);
}
public boolean isOpaqueCube()
{
return this.block.isOpaqueCube(this);
}
@Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockAccess worldIn, BlockPos pos)
{
return this.block.getCollisionBoundingBox(this, worldIn, pos);
}
public void addCollisionBoxToList(World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean p_185908_6_)
{
this.block.addCollisionBoxToList(this, worldIn, pos, entityBox, collidingBoxes, entityIn, p_185908_6_);
}
public AxisAlignedBB getBoundingBox(IBlockAccess blockAccess, BlockPos pos)
{
return this.block.getBoundingBox(this, blockAccess, pos);
}
public RayTraceResult collisionRayTrace(World worldIn, BlockPos pos, Vec3d start, Vec3d end)
{
return this.block.collisionRayTrace(this, worldIn, pos, start, end);
}
/**
* Determines if the block is solid enough on the top side to support other blocks, like redstone
* components.
*/
public boolean isTopSolid()
{
return this.block.isTopSolid(this);
}
public Vec3d getOffset(IBlockAccess access, BlockPos pos)
{
return this.block.getOffset(this, access, pos);
}
/**
* Called on both Client and Server when World#addBlockEvent is called. On the Server, this may perform
* additional changes to the world, like pistons replacing the block with an extended base. On the client,
* the update may involve replacing tile entities, playing sounds, or performing other visual actions to
* reflect the server side changes.
*/
public boolean onBlockEventReceived(World worldIn, BlockPos pos, int id, int param)
{
return this.block.eventReceived(this, worldIn, pos, id, param);
}
/**
* Called when a neighboring block was changed and marks that this state should perform any checks during a
* neighbor change. Cases may include when redstone power is updated, cactus blocks popping off due to a
* neighboring solid block, etc.
*/
public void neighborChanged(World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos)
{
this.block.neighborChanged(this, worldIn, pos, blockIn, fromPos);
}
public boolean causesSuffocation()
{
return this.block.causesSuffocation(this);
}
public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, BlockPos pos, EnumFacing facing)
{
return this.block.getBlockFaceShape(worldIn, this, pos, facing);
}
//Forge Start
@Override
public ImmutableTable<IProperty<?>, Comparable<?>, IBlockState> getPropertyValueTable()
{
return propertyValueTable;
}
@Override
public int getLightOpacity(IBlockAccess world, BlockPos pos)
{
return this.block.getLightOpacity(this, world, pos);
}
@Override
public int getLightValue(IBlockAccess world, BlockPos pos)
{
return this.block.getLightValue(this, world, pos);
}
@Override
public boolean isSideSolid(IBlockAccess world, BlockPos pos, EnumFacing side)
{
return this.block.isSideSolid(this, world, pos, side);
}
@Override
public boolean doesSideBlockChestOpening(IBlockAccess world, BlockPos pos, EnumFacing side)
{
return this.block.doesSideBlockChestOpening(this, world, pos, side);
}
@Override
public boolean doesSideBlockRendering(IBlockAccess world, BlockPos pos, EnumFacing side)
{
return this.block.doesSideBlockRendering(this, world, pos, side);
}
}
/**
* Forge added class to make building things easier.
* Will return an instance of BlockStateContainer appropriate for
* the list of properties passed in.
*
* Example usage:
*
* protected BlockStateContainer createBlockState()
* {
* return (new BlockStateContainer.Builder(this)).add(FACING).add(SOME_UNLISTED).build();
* }
*
*/
public static class Builder
{
private final Block block;
private final List<IProperty<?>> listed = Lists.newArrayList();
private final List<net.minecraftforge.common.property.IUnlistedProperty<?>> unlisted = Lists.newArrayList();
public Builder(Block block)
{
this.block = block;
}
public Builder add(IProperty<?>... props)
{
for (IProperty<?> prop : props)
this.listed.add(prop);
return this;
}
public Builder add(net.minecraftforge.common.property.IUnlistedProperty<?>... props)
{
for (net.minecraftforge.common.property.IUnlistedProperty<?> prop : props)
this.unlisted.add(prop);
return this;
}
public BlockStateContainer build()
{
IProperty<?>[] listed = new IProperty[this.listed.size()];
listed = this.listed.toArray(listed);
if (this.unlisted.size() == 0)
return new BlockStateContainer(this.block, listed);
net.minecraftforge.common.property.IUnlistedProperty<?>[] unlisted = new net.minecraftforge.common.property.IUnlistedProperty[this.unlisted.size()];
unlisted = this.unlisted.toArray(unlisted);
return new net.minecraftforge.common.property.ExtendedBlockState(this.block, listed, unlisted);
}
}
}

View File

@@ -0,0 +1,72 @@
package net.minecraft.block.state;
import com.google.common.base.Predicate;
import javax.annotation.Nullable;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockWorldState
{
private final World world;
private final BlockPos pos;
private final boolean forceLoad;
private IBlockState state;
private TileEntity tileEntity;
private boolean tileEntityInitialized;
public BlockWorldState(World worldIn, BlockPos posIn, boolean forceLoadIn)
{
this.world = worldIn;
this.pos = posIn;
this.forceLoad = forceLoadIn;
}
/**
* Gets the block state as currently held, or (if it has not gotten it from the world) loads it from the world.
* This will only look up the state from the world if {@link #forceLoad} is true or the block position is loaded.
*/
public IBlockState getBlockState()
{
if (this.state == null && (this.forceLoad || this.world.isBlockLoaded(this.pos)))
{
this.state = this.world.getBlockState(this.pos);
}
return this.state;
}
/**
* Gets the tile entity as currently held, or (if it has not gotten it from the world) loads it from the world.
*/
@Nullable
public TileEntity getTileEntity()
{
if (this.tileEntity == null && !this.tileEntityInitialized)
{
this.tileEntity = this.world.getTileEntity(this.pos);
this.tileEntityInitialized = true;
}
return this.tileEntity;
}
public BlockPos getPos()
{
return this.pos;
}
/**
* Creates a new {@link Predicate} that will match when the given {@link IBlockState} predicate matches.
*/
public static Predicate<BlockWorldState> hasState(final Predicate<IBlockState> predicatesIn)
{
return new Predicate<BlockWorldState>()
{
public boolean apply(@Nullable BlockWorldState p_apply_1_)
{
return p_apply_1_ != null && predicatesIn.apply(p_apply_1_.getBlockState());
}
};
}
}

View File

@@ -0,0 +1,23 @@
package net.minecraft.block.state;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IBlockBehaviors
{
/**
* Called on both Client and Server when World#addBlockEvent is called. On the Server, this may perform additional
* changes to the world, like pistons replacing the block with an extended base. On the client, the update may
* involve replacing tile entities, playing sounds, or performing other visual actions to reflect the server side
* changes.
*/
boolean onBlockEventReceived(World worldIn, BlockPos pos, int id, int param);
/**
* Called when a neighboring block was changed and marks that this state should perform any checks during a neighbor
* change. Cases may include when redstone power is updated, cactus blocks popping off due to a neighboring solid
* block, etc.
*/
void neighborChanged(World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos);
}

View File

@@ -0,0 +1,124 @@
package net.minecraft.block.state;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
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.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public interface IBlockProperties
{
Material getMaterial();
boolean isFullBlock();
boolean canEntitySpawn(Entity entityIn);
@Deprecated //Forge location aware version below
int getLightOpacity();
int getLightOpacity(IBlockAccess world, BlockPos pos);
@Deprecated //Forge location aware version below
int getLightValue();
int getLightValue(IBlockAccess world, BlockPos pos);
@SideOnly(Side.CLIENT)
boolean isTranslucent();
boolean useNeighborBrightness();
MapColor getMapColor(IBlockAccess p_185909_1_, BlockPos p_185909_2_);
/**
* Returns the blockstate with the given rotation. If inapplicable, returns itself.
*/
IBlockState withRotation(Rotation rot);
/**
* Returns the blockstate mirrored in the given way. If inapplicable, returns itself.
*/
IBlockState withMirror(Mirror mirrorIn);
boolean isFullCube();
@SideOnly(Side.CLIENT)
boolean hasCustomBreakingProgress();
EnumBlockRenderType getRenderType();
@SideOnly(Side.CLIENT)
int getPackedLightmapCoords(IBlockAccess source, BlockPos pos);
@SideOnly(Side.CLIENT)
float getAmbientOcclusionLightValue();
boolean isBlockNormalCube();
boolean isNormalCube();
boolean canProvidePower();
int getWeakPower(IBlockAccess blockAccess, BlockPos pos, EnumFacing side);
boolean hasComparatorInputOverride();
int getComparatorInputOverride(World worldIn, BlockPos pos);
float getBlockHardness(World worldIn, BlockPos pos);
float getPlayerRelativeBlockHardness(EntityPlayer player, World worldIn, BlockPos pos);
int getStrongPower(IBlockAccess blockAccess, BlockPos pos, EnumFacing side);
EnumPushReaction getMobilityFlag();
IBlockState getActualState(IBlockAccess blockAccess, BlockPos pos);
@SideOnly(Side.CLIENT)
AxisAlignedBB getSelectedBoundingBox(World worldIn, BlockPos pos);
@SideOnly(Side.CLIENT)
boolean shouldSideBeRendered(IBlockAccess blockAccess, BlockPos pos, EnumFacing facing);
boolean isOpaqueCube();
@Nullable
AxisAlignedBB getCollisionBoundingBox(IBlockAccess worldIn, BlockPos pos);
void addCollisionBoxToList(World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean p_185908_6_);
AxisAlignedBB getBoundingBox(IBlockAccess blockAccess, BlockPos pos);
RayTraceResult collisionRayTrace(World worldIn, BlockPos pos, Vec3d start, Vec3d end);
/**
* Determines if the block is solid enough on the top side to support other blocks, like redstone components.
*/
@Deprecated // Forge: Use isSideSolid(IBlockAccess, BlockPos, EnumFacing.UP) instead
boolean isTopSolid();
//Forge added functions
boolean doesSideBlockRendering(IBlockAccess world, BlockPos pos, EnumFacing side);
boolean isSideSolid(IBlockAccess world, BlockPos pos, EnumFacing side);
boolean doesSideBlockChestOpening(IBlockAccess world, BlockPos pos, EnumFacing side);
Vec3d getOffset(IBlockAccess access, BlockPos pos);
boolean causesSuffocation();
BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, BlockPos pos, EnumFacing facing);
}

View File

@@ -0,0 +1,31 @@
package net.minecraft.block.state;
import com.google.common.collect.ImmutableMap;
import java.util.Collection;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
public interface IBlockState extends IBlockBehaviors, IBlockProperties
{
Collection < IProperty<? >> getPropertyKeys();
/**
* Get the value of the given Property for this BlockState
*/
<T extends Comparable<T>> T getValue(IProperty<T> property);
/**
* Get a version of this BlockState with the given Property now set to the given value
*/
<T extends Comparable<T>, V extends T> IBlockState withProperty(IProperty<T> property, V value);
/**
* Create a version of this BlockState with the given property cycled to the next value in order. If the property
* was at the highest possible value, it is set to the lowest one instead.
*/
<T extends Comparable<T>> IBlockState cycleProperty(IProperty<T> property);
ImmutableMap < IProperty<?>, Comparable<? >> getProperties();
Block getBlock();
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.block.state;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -0,0 +1,26 @@
package net.minecraft.block.state.pattern;
import com.google.common.base.Predicate;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
public class BlockMatcher implements Predicate<IBlockState>
{
private final Block block;
private BlockMatcher(Block blockType)
{
this.block = blockType;
}
public static BlockMatcher forBlock(Block blockType)
{
return new BlockMatcher(blockType);
}
public boolean apply(@Nullable IBlockState p_apply_1_)
{
return p_apply_1_ != null && p_apply_1_.getBlock() == this.block;
}
}

View File

@@ -0,0 +1,26 @@
package net.minecraft.block.state.pattern;
import com.google.common.base.Predicate;
import javax.annotation.Nullable;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
public class BlockMaterialMatcher implements Predicate<IBlockState>
{
private final Material material;
private BlockMaterialMatcher(Material materialIn)
{
this.material = materialIn;
}
public static BlockMaterialMatcher forMaterial(Material materialIn)
{
return new BlockMaterialMatcher(materialIn);
}
public boolean apply(@Nullable IBlockState p_apply_1_)
{
return p_apply_1_ != null && p_apply_1_.getMaterial() == this.material;
}
}

View File

@@ -0,0 +1,216 @@
package net.minecraft.block.state.pattern;
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import javax.annotation.Nullable;
import net.minecraft.block.state.BlockWorldState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
public class BlockPattern
{
private final Predicate<BlockWorldState>[][][] blockMatches;
private final int fingerLength;
private final int thumbLength;
private final int palmLength;
public BlockPattern(Predicate<BlockWorldState>[][][] predicatesIn)
{
this.blockMatches = predicatesIn;
this.fingerLength = predicatesIn.length;
if (this.fingerLength > 0)
{
this.thumbLength = predicatesIn[0].length;
if (this.thumbLength > 0)
{
this.palmLength = predicatesIn[0][0].length;
}
else
{
this.palmLength = 0;
}
}
else
{
this.thumbLength = 0;
this.palmLength = 0;
}
}
public int getFingerLength()
{
return this.fingerLength;
}
public int getThumbLength()
{
return this.thumbLength;
}
public int getPalmLength()
{
return this.palmLength;
}
/**
* checks that the given pattern & rotation is at the block co-ordinates.
*/
@Nullable
private BlockPattern.PatternHelper checkPatternAt(BlockPos pos, EnumFacing finger, EnumFacing thumb, LoadingCache<BlockPos, BlockWorldState> lcache)
{
for (int i = 0; i < this.palmLength; ++i)
{
for (int j = 0; j < this.thumbLength; ++j)
{
for (int k = 0; k < this.fingerLength; ++k)
{
if (!this.blockMatches[k][j][i].apply(lcache.getUnchecked(translateOffset(pos, finger, thumb, i, j, k))))
{
return null;
}
}
}
}
return new BlockPattern.PatternHelper(pos, finger, thumb, lcache, this.palmLength, this.thumbLength, this.fingerLength);
}
/**
* Calculates whether the given world position matches the pattern. Warning, fairly heavy function. @return a
* BlockPattern.PatternHelper if found, null otherwise.
*/
@Nullable
public BlockPattern.PatternHelper match(World worldIn, BlockPos pos)
{
LoadingCache<BlockPos, BlockWorldState> loadingcache = createLoadingCache(worldIn, false);
int i = Math.max(Math.max(this.palmLength, this.thumbLength), this.fingerLength);
for (BlockPos blockpos : BlockPos.getAllInBox(pos, pos.add(i - 1, i - 1, i - 1)))
{
for (EnumFacing enumfacing : EnumFacing.values())
{
for (EnumFacing enumfacing1 : EnumFacing.values())
{
if (enumfacing1 != enumfacing && enumfacing1 != enumfacing.getOpposite())
{
BlockPattern.PatternHelper blockpattern$patternhelper = this.checkPatternAt(blockpos, enumfacing, enumfacing1, loadingcache);
if (blockpattern$patternhelper != null)
{
return blockpattern$patternhelper;
}
}
}
}
}
return null;
}
public static LoadingCache<BlockPos, BlockWorldState> createLoadingCache(World worldIn, boolean forceLoadIn)
{
return CacheBuilder.newBuilder().<BlockPos, BlockWorldState>build(new BlockPattern.CacheLoader(worldIn, forceLoadIn));
}
/**
* Offsets the position of pos in the direction of finger and thumb facing by offset amounts, follows the right-hand
* rule for cross products (finger, thumb, palm) @return A new BlockPos offset in the facing directions
*/
protected static BlockPos translateOffset(BlockPos pos, EnumFacing finger, EnumFacing thumb, int palmOffset, int thumbOffset, int fingerOffset)
{
if (finger != thumb && finger != thumb.getOpposite())
{
Vec3i vec3i = new Vec3i(finger.getFrontOffsetX(), finger.getFrontOffsetY(), finger.getFrontOffsetZ());
Vec3i vec3i1 = new Vec3i(thumb.getFrontOffsetX(), thumb.getFrontOffsetY(), thumb.getFrontOffsetZ());
Vec3i vec3i2 = vec3i.crossProduct(vec3i1);
return pos.add(vec3i1.getX() * -thumbOffset + vec3i2.getX() * palmOffset + vec3i.getX() * fingerOffset, vec3i1.getY() * -thumbOffset + vec3i2.getY() * palmOffset + vec3i.getY() * fingerOffset, vec3i1.getZ() * -thumbOffset + vec3i2.getZ() * palmOffset + vec3i.getZ() * fingerOffset);
}
else
{
throw new IllegalArgumentException("Invalid forwards & up combination");
}
}
static class CacheLoader extends com.google.common.cache.CacheLoader<BlockPos, BlockWorldState>
{
private final World world;
private final boolean forceLoad;
public CacheLoader(World worldIn, boolean forceLoadIn)
{
this.world = worldIn;
this.forceLoad = forceLoadIn;
}
public BlockWorldState load(BlockPos p_load_1_) throws Exception
{
return new BlockWorldState(this.world, p_load_1_, this.forceLoad);
}
}
public static class PatternHelper
{
private final BlockPos frontTopLeft;
private final EnumFacing forwards;
private final EnumFacing up;
private final LoadingCache<BlockPos, BlockWorldState> lcache;
private final int width;
private final int height;
private final int depth;
public PatternHelper(BlockPos posIn, EnumFacing fingerIn, EnumFacing thumbIn, LoadingCache<BlockPos, BlockWorldState> lcacheIn, int widthIn, int heightIn, int depthIn)
{
this.frontTopLeft = posIn;
this.forwards = fingerIn;
this.up = thumbIn;
this.lcache = lcacheIn;
this.width = widthIn;
this.height = heightIn;
this.depth = depthIn;
}
/**
* Return the BlockPos of the Pattern
*/
public BlockPos getFrontTopLeft()
{
return this.frontTopLeft;
}
public EnumFacing getForwards()
{
return this.forwards;
}
public EnumFacing getUp()
{
return this.up;
}
public int getWidth()
{
return this.width;
}
public int getHeight()
{
return this.height;
}
public BlockWorldState translateOffset(int palmOffset, int thumbOffset, int fingerOffset)
{
return this.lcache.getUnchecked(BlockPattern.translateOffset(this.frontTopLeft, this.getForwards(), this.getUp(), palmOffset, thumbOffset, fingerOffset));
}
public String toString()
{
return MoreObjects.toStringHelper(this).add("up", this.up).add("forwards", this.forwards).add("frontTopLeft", this.frontTopLeft).toString();
}
}
}

View File

@@ -0,0 +1,79 @@
package net.minecraft.block.state.pattern;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
public class BlockStateMatcher implements Predicate<IBlockState>
{
public static final Predicate<IBlockState> ANY = new Predicate<IBlockState>()
{
public boolean apply(@Nullable IBlockState p_apply_1_)
{
return true;
}
};
private final BlockStateContainer blockstate;
private final Map < IProperty<?>, Predicate<? >> propertyPredicates = Maps. < IProperty<?>, Predicate<? >> newHashMap();
private BlockStateMatcher(BlockStateContainer blockStateIn)
{
this.blockstate = blockStateIn;
}
public static BlockStateMatcher forBlock(Block blockIn)
{
return new BlockStateMatcher(blockIn.getBlockState());
}
public boolean apply(@Nullable IBlockState p_apply_1_)
{
if (p_apply_1_ != null && p_apply_1_.getBlock().equals(this.blockstate.getBlock()))
{
if (this.propertyPredicates.isEmpty())
{
return true;
}
else
{
for (Entry < IProperty<?>, Predicate<? >> entry : this.propertyPredicates.entrySet())
{
if (!this.matches(p_apply_1_, (IProperty)entry.getKey(), (Predicate)entry.getValue()))
{
return false;
}
}
return true;
}
}
else
{
return false;
}
}
protected <T extends Comparable<T>> boolean matches(IBlockState blockState, IProperty<T> property, Predicate<T> predicate)
{
return predicate.apply(blockState.getValue(property));
}
public <V extends Comparable<V>> BlockStateMatcher where(IProperty<V> property, Predicate <? extends V > is)
{
if (!this.blockstate.getProperties().contains(property))
{
throw new IllegalArgumentException(this.blockstate + " cannot support property " + property);
}
else
{
this.propertyPredicates.put(property, is);
return this;
}
}
}

View File

@@ -0,0 +1,127 @@
package net.minecraft.block.state.pattern;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.lang.reflect.Array;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.block.state.BlockWorldState;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
public class FactoryBlockPattern
{
private static final Joiner COMMA_JOIN = Joiner.on(",");
private final List<String[]> depth = Lists.<String[]>newArrayList();
private final Map<Character, Predicate<BlockWorldState>> symbolMap = Maps.<Character, Predicate<BlockWorldState>>newHashMap();
private int aisleHeight;
private int rowWidth;
private FactoryBlockPattern()
{
this.symbolMap.put(' ', Predicates.alwaysTrue());
}
/**
* Adds a single aisle to this pattern, going in the z axis. (so multiple calls to this will increase the z-size by
* 1)
*/
public FactoryBlockPattern aisle(String... aisle)
{
if (!ArrayUtils.isEmpty((Object[])aisle) && !StringUtils.isEmpty(aisle[0]))
{
if (this.depth.isEmpty())
{
this.aisleHeight = aisle.length;
this.rowWidth = aisle[0].length();
}
if (aisle.length != this.aisleHeight)
{
throw new IllegalArgumentException("Expected aisle with height of " + this.aisleHeight + ", but was given one with a height of " + aisle.length + ")");
}
else
{
for (String s : aisle)
{
if (s.length() != this.rowWidth)
{
throw new IllegalArgumentException("Not all rows in the given aisle are the correct width (expected " + this.rowWidth + ", found one with " + s.length() + ")");
}
for (char c0 : s.toCharArray())
{
if (!this.symbolMap.containsKey(Character.valueOf(c0)))
{
this.symbolMap.put(Character.valueOf(c0), null);
}
}
}
this.depth.add(aisle);
return this;
}
}
else
{
throw new IllegalArgumentException("Empty pattern for aisle");
}
}
public static FactoryBlockPattern start()
{
return new FactoryBlockPattern();
}
public FactoryBlockPattern where(char symbol, Predicate<BlockWorldState> blockMatcher)
{
this.symbolMap.put(Character.valueOf(symbol), blockMatcher);
return this;
}
public BlockPattern build()
{
return new BlockPattern(this.makePredicateArray());
}
private Predicate<BlockWorldState>[][][] makePredicateArray()
{
this.checkMissingPredicates();
Predicate<BlockWorldState>[][][] predicate = (Predicate[][][])((Predicate[][][])Array.newInstance(Predicate.class, this.depth.size(), this.aisleHeight, this.rowWidth));
for (int i = 0; i < this.depth.size(); ++i)
{
for (int j = 0; j < this.aisleHeight; ++j)
{
for (int k = 0; k < this.rowWidth; ++k)
{
predicate[i][j][k] = this.symbolMap.get(Character.valueOf(((String[])this.depth.get(i))[j].charAt(k)));
}
}
}
return predicate;
}
private void checkMissingPredicates()
{
List<Character> list = Lists.<Character>newArrayList();
for (Entry<Character, Predicate<BlockWorldState>> entry : this.symbolMap.entrySet())
{
if (entry.getValue() == null)
{
list.add(entry.getKey());
}
}
if (!list.isEmpty())
{
throw new IllegalStateException("Predicates for character(s) " + COMMA_JOIN.join(list) + " are missing");
}
}
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.block.state.pattern;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;