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,125 @@
package net.minecraft.tileentity;
import javax.annotation.Nullable;
import net.minecraft.block.BlockFlower;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public enum BannerPattern
{
BASE("base", "b"),
SQUARE_BOTTOM_LEFT("square_bottom_left", "bl", " ", " ", "# "),
SQUARE_BOTTOM_RIGHT("square_bottom_right", "br", " ", " ", " #"),
SQUARE_TOP_LEFT("square_top_left", "tl", "# ", " ", " "),
SQUARE_TOP_RIGHT("square_top_right", "tr", " #", " ", " "),
STRIPE_BOTTOM("stripe_bottom", "bs", " ", " ", "###"),
STRIPE_TOP("stripe_top", "ts", "###", " ", " "),
STRIPE_LEFT("stripe_left", "ls", "# ", "# ", "# "),
STRIPE_RIGHT("stripe_right", "rs", " #", " #", " #"),
STRIPE_CENTER("stripe_center", "cs", " # ", " # ", " # "),
STRIPE_MIDDLE("stripe_middle", "ms", " ", "###", " "),
STRIPE_DOWNRIGHT("stripe_downright", "drs", "# ", " # ", " #"),
STRIPE_DOWNLEFT("stripe_downleft", "dls", " #", " # ", "# "),
STRIPE_SMALL("small_stripes", "ss", "# #", "# #", " "),
CROSS("cross", "cr", "# #", " # ", "# #"),
STRAIGHT_CROSS("straight_cross", "sc", " # ", "###", " # "),
TRIANGLE_BOTTOM("triangle_bottom", "bt", " ", " # ", "# #"),
TRIANGLE_TOP("triangle_top", "tt", "# #", " # ", " "),
TRIANGLES_BOTTOM("triangles_bottom", "bts", " ", "# #", " # "),
TRIANGLES_TOP("triangles_top", "tts", " # ", "# #", " "),
DIAGONAL_LEFT("diagonal_left", "ld", "## ", "# ", " "),
DIAGONAL_RIGHT("diagonal_up_right", "rd", " ", " #", " ##"),
DIAGONAL_LEFT_MIRROR("diagonal_up_left", "lud", " ", "# ", "## "),
DIAGONAL_RIGHT_MIRROR("diagonal_right", "rud", " ##", " #", " "),
CIRCLE_MIDDLE("circle", "mc", " ", " # ", " "),
RHOMBUS_MIDDLE("rhombus", "mr", " # ", "# #", " # "),
HALF_VERTICAL("half_vertical", "vh", "## ", "## ", "## "),
HALF_HORIZONTAL("half_horizontal", "hh", "###", "###", " "),
HALF_VERTICAL_MIRROR("half_vertical_right", "vhr", " ##", " ##", " ##"),
HALF_HORIZONTAL_MIRROR("half_horizontal_bottom", "hhb", " ", "###", "###"),
BORDER("border", "bo", "###", "# #", "###"),
CURLY_BORDER("curly_border", "cbo", new ItemStack(Blocks.VINE)),
CREEPER("creeper", "cre", new ItemStack(Items.SKULL, 1, 4)),
GRADIENT("gradient", "gra", "# #", " # ", " # "),
GRADIENT_UP("gradient_up", "gru", " # ", " # ", "# #"),
BRICKS("bricks", "bri", new ItemStack(Blocks.BRICK_BLOCK)),
SKULL("skull", "sku", new ItemStack(Items.SKULL, 1, 1)),
FLOWER("flower", "flo", new ItemStack(Blocks.RED_FLOWER, 1, BlockFlower.EnumFlowerType.OXEYE_DAISY.getMeta())),
MOJANG("mojang", "moj", new ItemStack(Items.GOLDEN_APPLE, 1, 1));
private final String fileName;
private final String hashname;
private final String[] patterns;
private ItemStack patternItem;
private BannerPattern(String p_i47245_3_, String p_i47245_4_)
{
this.patterns = new String[3];
this.patternItem = ItemStack.EMPTY;
this.fileName = p_i47245_3_;
this.hashname = p_i47245_4_;
}
private BannerPattern(String p_i47246_3_, String p_i47246_4_, ItemStack p_i47246_5_)
{
this(p_i47246_3_, p_i47246_4_);
this.patternItem = p_i47246_5_;
}
private BannerPattern(String p_i47247_3_, String p_i47247_4_, String p_i47247_5_, String p_i47247_6_, String p_i47247_7_)
{
this(p_i47247_3_, p_i47247_4_);
this.patterns[0] = p_i47247_5_;
this.patterns[1] = p_i47247_6_;
this.patterns[2] = p_i47247_7_;
}
@SideOnly(Side.CLIENT)
public String getFileName()
{
return this.fileName;
}
public String getHashname()
{
return this.hashname;
}
public String[] getPatterns()
{
return this.patterns;
}
public boolean hasPattern()
{
return !this.patternItem.isEmpty() || this.patterns[0] != null;
}
public boolean hasPatternItem()
{
return !this.patternItem.isEmpty();
}
public ItemStack getPatternItem()
{
return this.patternItem;
}
@Nullable
@SideOnly(Side.CLIENT)
public static BannerPattern byHash(String hash)
{
for (BannerPattern bannerpattern : values())
{
if (bannerpattern.hashname.equals(hash))
{
return bannerpattern;
}
}
return null;
}
}

View File

@@ -0,0 +1,314 @@
package net.minecraft.tileentity;
import io.netty.buffer.ByteBuf;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.Nullable;
import net.minecraft.command.CommandResultStats;
import net.minecraft.command.ICommandSender;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.crash.ICrashReportDetail;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ReportedException;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class CommandBlockBaseLogic implements ICommandSender
{
/** The formatting for the timestamp on commands run. */
private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("HH:mm:ss");
private long lastExecution = -1L;
private boolean updateLastExecution = true;
/** The number of successful commands run. (used for redstone output) */
private int successCount;
private boolean trackOutput = true;
/** The previously run command. */
private ITextComponent lastOutput;
/** The command stored in the command block. */
private String commandStored = "";
/** The custom name of the command block. (defaults to "@") */
private String customName = "@";
private final CommandResultStats resultStats = new CommandResultStats();
/**
* returns the successCount int.
*/
public int getSuccessCount()
{
return this.successCount;
}
public void setSuccessCount(int successCountIn)
{
this.successCount = successCountIn;
}
/**
* Returns the lastOutput.
*/
public ITextComponent getLastOutput()
{
return (ITextComponent)(this.lastOutput == null ? new TextComponentString("") : this.lastOutput);
}
public NBTTagCompound writeToNBT(NBTTagCompound p_189510_1_)
{
p_189510_1_.setString("Command", this.commandStored);
p_189510_1_.setInteger("SuccessCount", this.successCount);
p_189510_1_.setString("CustomName", this.customName);
p_189510_1_.setBoolean("TrackOutput", this.trackOutput);
if (this.lastOutput != null && this.trackOutput)
{
p_189510_1_.setString("LastOutput", ITextComponent.Serializer.componentToJson(this.lastOutput));
}
p_189510_1_.setBoolean("UpdateLastExecution", this.updateLastExecution);
if (this.updateLastExecution && this.lastExecution > 0L)
{
p_189510_1_.setLong("LastExecution", this.lastExecution);
}
this.resultStats.writeStatsToNBT(p_189510_1_);
return p_189510_1_;
}
/**
* Reads NBT formatting and stored data into variables.
*/
public void readDataFromNBT(NBTTagCompound nbt)
{
this.commandStored = nbt.getString("Command");
this.successCount = nbt.getInteger("SuccessCount");
if (nbt.hasKey("CustomName", 8))
{
this.customName = nbt.getString("CustomName");
}
if (nbt.hasKey("TrackOutput", 1))
{
this.trackOutput = nbt.getBoolean("TrackOutput");
}
if (nbt.hasKey("LastOutput", 8) && this.trackOutput)
{
try
{
this.lastOutput = ITextComponent.Serializer.jsonToComponent(nbt.getString("LastOutput"));
}
catch (Throwable throwable)
{
this.lastOutput = new TextComponentString(throwable.getMessage());
}
}
else
{
this.lastOutput = null;
}
if (nbt.hasKey("UpdateLastExecution"))
{
this.updateLastExecution = nbt.getBoolean("UpdateLastExecution");
}
if (this.updateLastExecution && nbt.hasKey("LastExecution"))
{
this.lastExecution = nbt.getLong("LastExecution");
}
else
{
this.lastExecution = -1L;
}
this.resultStats.readStatsFromNBT(nbt);
}
/**
* Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not
*/
public boolean canUseCommand(int permLevel, String commandName)
{
return permLevel <= 2;
}
/**
* Sets the command.
*/
public void setCommand(String command)
{
this.commandStored = command;
this.successCount = 0;
}
/**
* Returns the command of the command block.
*/
public String getCommand()
{
return this.commandStored;
}
public boolean trigger(World worldIn)
{
if (!worldIn.isRemote && worldIn.getTotalWorldTime() != this.lastExecution)
{
if ("Searge".equalsIgnoreCase(this.commandStored))
{
this.lastOutput = new TextComponentString("#itzlipofutzli");
this.successCount = 1;
return true;
}
else
{
MinecraftServer minecraftserver = this.getServer();
if (minecraftserver != null && minecraftserver.isAnvilFileSet() && minecraftserver.isCommandBlockEnabled())
{
try
{
this.lastOutput = null;
this.successCount = minecraftserver.getCommandManager().executeCommand(this, this.commandStored);
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Executing command block");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Command to be executed");
crashreportcategory.addDetail("Command", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return CommandBlockBaseLogic.this.getCommand();
}
});
crashreportcategory.addDetail("Name", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return CommandBlockBaseLogic.this.getName();
}
});
throw new ReportedException(crashreport);
}
}
else
{
this.successCount = 0;
}
if (this.updateLastExecution)
{
this.lastExecution = worldIn.getTotalWorldTime();
}
else
{
this.lastExecution = -1L;
}
return true;
}
}
else
{
return false;
}
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.customName;
}
public void setName(String name)
{
this.customName = name;
}
/**
* Send a chat message to the CommandSender
*/
public void sendMessage(ITextComponent component)
{
if (this.trackOutput && this.getEntityWorld() != null && !this.getEntityWorld().isRemote)
{
this.lastOutput = (new TextComponentString("[" + TIMESTAMP_FORMAT.format(new Date()) + "] ")).appendSibling(component);
this.updateCommand();
}
}
/**
* Returns true if the command sender should be sent feedback about executed commands
*/
public boolean sendCommandFeedback()
{
MinecraftServer minecraftserver = this.getServer();
return minecraftserver == null || !minecraftserver.isAnvilFileSet() || minecraftserver.worlds[0].getGameRules().getBoolean("commandBlockOutput");
}
public void setCommandStat(CommandResultStats.Type type, int amount)
{
this.resultStats.setCommandStatForSender(this.getServer(), this, type, amount);
}
public abstract void updateCommand();
/**
* Currently this returns 0 for the traditional command block, and 1 for the minecart command block
*/
@SideOnly(Side.CLIENT)
public abstract int getCommandBlockType();
/**
* Fills in information about the command block for the packet. entityId for the minecart version, and X/Y/Z for the
* traditional version
*/
@SideOnly(Side.CLIENT)
public abstract void fillInInfo(ByteBuf buf);
public void setLastOutput(@Nullable ITextComponent lastOutputMessage)
{
this.lastOutput = lastOutputMessage;
}
public void setTrackOutput(boolean shouldTrackOutput)
{
this.trackOutput = shouldTrackOutput;
}
public boolean shouldTrackOutput()
{
return this.trackOutput;
}
public boolean tryOpenEditCommandBlock(EntityPlayer playerIn)
{
if (!playerIn.canUseCommandBlock())
{
return false;
}
else
{
if (playerIn.getEntityWorld().isRemote)
{
playerIn.displayGuiEditCommandCart(this);
}
return true;
}
}
public CommandResultStats getCommandResultStats()
{
return this.resultStats;
}
}

View File

@@ -0,0 +1,27 @@
package net.minecraft.tileentity;
import net.minecraft.inventory.IInventory;
import net.minecraft.world.World;
public interface IHopper extends IInventory
{
/**
* Returns the worldObj for this tileEntity.
*/
World getWorld();
/**
* Gets the world X position for this hopper entity.
*/
double getXPos();
/**
* Gets the world Y position for this hopper entity.
*/
double getYPos();
/**
* Gets the world Z position for this hopper entity.
*/
double getZPos();
}

View File

@@ -0,0 +1,327 @@
package net.minecraft.tileentity;
import com.google.common.collect.Lists;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StringUtils;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedSpawnerEntity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class MobSpawnerBaseLogic
{
/** The delay to spawn. */
private int spawnDelay = 20;
/** List of potential entities to spawn */
private final List<WeightedSpawnerEntity> potentialSpawns = Lists.<WeightedSpawnerEntity>newArrayList();
private WeightedSpawnerEntity spawnData = new WeightedSpawnerEntity();
/** The rotation of the mob inside the mob spawner */
private double mobRotation;
/** the previous rotation of the mob inside the mob spawner */
private double prevMobRotation;
private int minSpawnDelay = 200;
private int maxSpawnDelay = 800;
private int spawnCount = 4;
/** Cached instance of the entity to render inside the spawner. */
private Entity cachedEntity;
private int maxNearbyEntities = 6;
/** The distance from which a player activates the spawner. */
private int activatingRangeFromPlayer = 16;
/** The range coefficient for spawning entities around. */
private int spawnRange = 4;
@Nullable
private ResourceLocation getEntityId()
{
String s = this.spawnData.getNbt().getString("id");
return StringUtils.isNullOrEmpty(s) ? null : new ResourceLocation(s);
}
public void setEntityId(@Nullable ResourceLocation id)
{
if (id != null)
{
this.spawnData.getNbt().setString("id", id.toString());
}
}
/**
* Returns true if there's a player close enough to this mob spawner to activate it.
*/
private boolean isActivated()
{
BlockPos blockpos = this.getSpawnerPosition();
return this.getSpawnerWorld().isAnyPlayerWithinRangeAt((double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 0.5D, (double)blockpos.getZ() + 0.5D, (double)this.activatingRangeFromPlayer);
}
public void updateSpawner()
{
if (!this.isActivated())
{
this.prevMobRotation = this.mobRotation;
}
else
{
BlockPos blockpos = this.getSpawnerPosition();
if (this.getSpawnerWorld().isRemote)
{
double d3 = (double)((float)blockpos.getX() + this.getSpawnerWorld().rand.nextFloat());
double d4 = (double)((float)blockpos.getY() + this.getSpawnerWorld().rand.nextFloat());
double d5 = (double)((float)blockpos.getZ() + this.getSpawnerWorld().rand.nextFloat());
this.getSpawnerWorld().spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d3, d4, d5, 0.0D, 0.0D, 0.0D);
this.getSpawnerWorld().spawnParticle(EnumParticleTypes.FLAME, d3, d4, d5, 0.0D, 0.0D, 0.0D);
if (this.spawnDelay > 0)
{
--this.spawnDelay;
}
this.prevMobRotation = this.mobRotation;
this.mobRotation = (this.mobRotation + (double)(1000.0F / ((float)this.spawnDelay + 200.0F))) % 360.0D;
}
else
{
if (this.spawnDelay == -1)
{
this.resetTimer();
}
if (this.spawnDelay > 0)
{
--this.spawnDelay;
return;
}
boolean flag = false;
for (int i = 0; i < this.spawnCount; ++i)
{
NBTTagCompound nbttagcompound = this.spawnData.getNbt();
NBTTagList nbttaglist = nbttagcompound.getTagList("Pos", 6);
World world = this.getSpawnerWorld();
int j = nbttaglist.tagCount();
double d0 = j >= 1 ? nbttaglist.getDoubleAt(0) : (double)blockpos.getX() + (world.rand.nextDouble() - world.rand.nextDouble()) * (double)this.spawnRange + 0.5D;
double d1 = j >= 2 ? nbttaglist.getDoubleAt(1) : (double)(blockpos.getY() + world.rand.nextInt(3) - 1);
double d2 = j >= 3 ? nbttaglist.getDoubleAt(2) : (double)blockpos.getZ() + (world.rand.nextDouble() - world.rand.nextDouble()) * (double)this.spawnRange + 0.5D;
Entity entity = AnvilChunkLoader.readWorldEntityPos(nbttagcompound, world, d0, d1, d2, false);
if (entity == null)
{
return;
}
int k = world.getEntitiesWithinAABB(entity.getClass(), (new AxisAlignedBB((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ(), (double)(blockpos.getX() + 1), (double)(blockpos.getY() + 1), (double)(blockpos.getZ() + 1))).grow((double)this.spawnRange)).size();
if (k >= this.maxNearbyEntities)
{
this.resetTimer();
return;
}
EntityLiving entityliving = entity instanceof EntityLiving ? (EntityLiving)entity : null;
entity.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, world.rand.nextFloat() * 360.0F, 0.0F);
if (entityliving == null || net.minecraftforge.event.ForgeEventFactory.canEntitySpawnSpawner(entityliving, getSpawnerWorld(), (float)entity.posX, (float)entity.posY, (float)entity.posZ, this))
{
if (this.spawnData.getNbt().getSize() == 1 && this.spawnData.getNbt().hasKey("id", 8) && entity instanceof EntityLiving)
{
if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, this.getSpawnerWorld(), (float)entity.posX, (float)entity.posY, (float)entity.posZ, this))
((EntityLiving)entity).onInitialSpawn(world.getDifficultyForLocation(new BlockPos(entity)), (IEntityLivingData)null);
}
AnvilChunkLoader.spawnEntity(entity, world);
world.playEvent(2004, blockpos, 0);
if (entityliving != null)
{
entityliving.spawnExplosionParticle();
}
flag = true;
}
}
if (flag)
{
this.resetTimer();
}
}
}
}
private void resetTimer()
{
if (this.maxSpawnDelay <= this.minSpawnDelay)
{
this.spawnDelay = this.minSpawnDelay;
}
else
{
int i = this.maxSpawnDelay - this.minSpawnDelay;
this.spawnDelay = this.minSpawnDelay + this.getSpawnerWorld().rand.nextInt(i);
}
if (!this.potentialSpawns.isEmpty())
{
this.setNextSpawnData((WeightedSpawnerEntity)WeightedRandom.getRandomItem(this.getSpawnerWorld().rand, this.potentialSpawns));
}
this.broadcastEvent(1);
}
public void readFromNBT(NBTTagCompound nbt)
{
this.spawnDelay = nbt.getShort("Delay");
this.potentialSpawns.clear();
if (nbt.hasKey("SpawnPotentials", 9))
{
NBTTagList nbttaglist = nbt.getTagList("SpawnPotentials", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
this.potentialSpawns.add(new WeightedSpawnerEntity(nbttaglist.getCompoundTagAt(i)));
}
}
if (nbt.hasKey("SpawnData", 10))
{
this.setNextSpawnData(new WeightedSpawnerEntity(1, nbt.getCompoundTag("SpawnData")));
}
else if (!this.potentialSpawns.isEmpty())
{
this.setNextSpawnData((WeightedSpawnerEntity)WeightedRandom.getRandomItem(this.getSpawnerWorld().rand, this.potentialSpawns));
}
if (nbt.hasKey("MinSpawnDelay", 99))
{
this.minSpawnDelay = nbt.getShort("MinSpawnDelay");
this.maxSpawnDelay = nbt.getShort("MaxSpawnDelay");
this.spawnCount = nbt.getShort("SpawnCount");
}
if (nbt.hasKey("MaxNearbyEntities", 99))
{
this.maxNearbyEntities = nbt.getShort("MaxNearbyEntities");
this.activatingRangeFromPlayer = nbt.getShort("RequiredPlayerRange");
}
if (nbt.hasKey("SpawnRange", 99))
{
this.spawnRange = nbt.getShort("SpawnRange");
}
if (this.getSpawnerWorld() != null)
{
this.cachedEntity = null;
}
}
public NBTTagCompound writeToNBT(NBTTagCompound p_189530_1_)
{
ResourceLocation resourcelocation = this.getEntityId();
if (resourcelocation == null)
{
return p_189530_1_;
}
else
{
p_189530_1_.setShort("Delay", (short)this.spawnDelay);
p_189530_1_.setShort("MinSpawnDelay", (short)this.minSpawnDelay);
p_189530_1_.setShort("MaxSpawnDelay", (short)this.maxSpawnDelay);
p_189530_1_.setShort("SpawnCount", (short)this.spawnCount);
p_189530_1_.setShort("MaxNearbyEntities", (short)this.maxNearbyEntities);
p_189530_1_.setShort("RequiredPlayerRange", (short)this.activatingRangeFromPlayer);
p_189530_1_.setShort("SpawnRange", (short)this.spawnRange);
p_189530_1_.setTag("SpawnData", this.spawnData.getNbt().copy());
NBTTagList nbttaglist = new NBTTagList();
if (this.potentialSpawns.isEmpty())
{
nbttaglist.appendTag(this.spawnData.toCompoundTag());
}
else
{
for (WeightedSpawnerEntity weightedspawnerentity : this.potentialSpawns)
{
nbttaglist.appendTag(weightedspawnerentity.toCompoundTag());
}
}
p_189530_1_.setTag("SpawnPotentials", nbttaglist);
return p_189530_1_;
}
}
/**
* Sets the delay to minDelay if parameter given is 1, else return false.
*/
public boolean setDelayToMin(int delay)
{
if (delay == 1 && this.getSpawnerWorld().isRemote)
{
this.spawnDelay = this.minSpawnDelay;
return true;
}
else
{
return false;
}
}
@SideOnly(Side.CLIENT)
public Entity getCachedEntity()
{
if (this.cachedEntity == null)
{
this.cachedEntity = AnvilChunkLoader.readWorldEntity(this.spawnData.getNbt(), this.getSpawnerWorld(), false);
if (this.spawnData.getNbt().getSize() == 1 && this.spawnData.getNbt().hasKey("id", 8) && this.cachedEntity instanceof EntityLiving)
{
((EntityLiving)this.cachedEntity).onInitialSpawn(this.getSpawnerWorld().getDifficultyForLocation(new BlockPos(this.cachedEntity)), (IEntityLivingData)null);
}
}
return this.cachedEntity;
}
public void setNextSpawnData(WeightedSpawnerEntity p_184993_1_)
{
this.spawnData = p_184993_1_;
}
public abstract void broadcastEvent(int id);
public abstract World getSpawnerWorld();
public abstract BlockPos getSpawnerPosition();
@SideOnly(Side.CLIENT)
public double getMobRotation()
{
return this.mobRotation;
}
@SideOnly(Side.CLIENT)
public double getPrevMobRotation()
{
return this.prevMobRotation;
}
/* ======================================== FORGE START =====================================*/
@Nullable public Entity getSpawnerEntity() { return null; }
}

View File

@@ -0,0 +1,564 @@
package net.minecraft.tileentity;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockJukebox;
import net.minecraft.block.state.IBlockState;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.crash.ICrashReportDetail;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.Mirror;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.RegistryNamespaced;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public abstract class TileEntity implements net.minecraftforge.common.capabilities.ICapabilitySerializable<NBTTagCompound>
{
private static final Logger LOGGER = LogManager.getLogger();
private static final RegistryNamespaced < ResourceLocation, Class <? extends TileEntity >> REGISTRY = new RegistryNamespaced < ResourceLocation, Class <? extends TileEntity >> ();
/** the instance of the world the tile entity is in. */
protected World world;
protected BlockPos pos = BlockPos.ORIGIN;
protected boolean tileEntityInvalid;
private int blockMetadata = -1;
/** the Block type that this TileEntity is contained within */
protected Block blockType;
public static void register(String id, Class <? extends TileEntity > clazz)
{
REGISTRY.putObject(new ResourceLocation(id), clazz);
}
@Nullable
public static ResourceLocation getKey(Class <? extends TileEntity > clazz)
{
return REGISTRY.getNameForObject(clazz);
}
/**
* Returns the worldObj for this tileEntity.
*/
public World getWorld()
{
return this.world;
}
/**
* Sets the worldObj for this tileEntity.
*/
public void setWorld(World worldIn)
{
this.world = worldIn;
}
/**
* Returns true if the worldObj isn't null.
*/
public boolean hasWorld()
{
return this.world != null;
}
public void readFromNBT(NBTTagCompound compound)
{
this.pos = new BlockPos(compound.getInteger("x"), compound.getInteger("y"), compound.getInteger("z"));
if (compound.hasKey("ForgeData")) this.customTileData = compound.getCompoundTag("ForgeData");
if (this.capabilities != null && compound.hasKey("ForgeCaps")) this.capabilities.deserializeNBT(compound.getCompoundTag("ForgeCaps"));
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
return this.writeInternal(compound);
}
private NBTTagCompound writeInternal(NBTTagCompound compound)
{
ResourceLocation resourcelocation = REGISTRY.getNameForObject(this.getClass());
if (resourcelocation == null)
{
throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!");
}
else
{
compound.setString("id", resourcelocation.toString());
compound.setInteger("x", this.pos.getX());
compound.setInteger("y", this.pos.getY());
compound.setInteger("z", this.pos.getZ());
if (this.customTileData != null) compound.setTag("ForgeData", this.customTileData);
if (this.capabilities != null) compound.setTag("ForgeCaps", this.capabilities.serializeNBT());
return compound;
}
}
@Nullable
public static TileEntity create(World worldIn, NBTTagCompound compound)
{
TileEntity tileentity = null;
String s = compound.getString("id");
Class <? extends TileEntity > oclass = null;
try
{
oclass = (Class)REGISTRY.getObject(new ResourceLocation(s));
if (oclass != null)
{
tileentity = oclass.newInstance();
}
}
catch (Throwable throwable1)
{
LOGGER.error("Failed to create block entity {}", s, throwable1);
net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author",
s, oclass == null ? null : oclass.getName(), throwable1);
}
if (tileentity != null)
{
try
{
tileentity.setWorldCreate(worldIn);
tileentity.readFromNBT(compound);
}
catch (Throwable throwable)
{
LOGGER.error("Failed to load data for block entity {}", s, throwable);
net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity {}({}) has thrown an exception during loading, its state cannot be restored. Report this to the mod author",
s, oclass.getName(), throwable);
tileentity = null;
}
}
else
{
LOGGER.warn("Skipping BlockEntity with id {}", (Object)s);
}
return tileentity;
}
protected void setWorldCreate(World worldIn)
{
}
public int getBlockMetadata()
{
if (this.blockMetadata == -1)
{
IBlockState iblockstate = this.world.getBlockState(this.pos);
this.blockMetadata = iblockstate.getBlock().getMetaFromState(iblockstate);
}
return this.blockMetadata;
}
/**
* For tile entities, ensures the chunk containing the tile entity is saved to disk later - the game won't think it
* hasn't changed and skip it.
*/
public void markDirty()
{
if (this.world != null)
{
IBlockState iblockstate = this.world.getBlockState(this.pos);
this.blockMetadata = iblockstate.getBlock().getMetaFromState(iblockstate);
this.world.markChunkDirty(this.pos, this);
if (this.getBlockType() != Blocks.AIR)
{
this.world.updateComparatorOutputLevel(this.pos, this.getBlockType());
}
}
}
/**
* Returns the square of the distance between this entity and the passed in coordinates.
*/
public double getDistanceSq(double x, double y, double z)
{
double d0 = (double)this.pos.getX() + 0.5D - x;
double d1 = (double)this.pos.getY() + 0.5D - y;
double d2 = (double)this.pos.getZ() + 0.5D - z;
return d0 * d0 + d1 * d1 + d2 * d2;
}
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared()
{
return 4096.0D;
}
public BlockPos getPos()
{
return this.pos;
}
/**
* Gets the block type at the location of this entity (client-only).
*/
public Block getBlockType()
{
if (this.blockType == null && this.world != null)
{
this.blockType = this.world.getBlockState(this.pos).getBlock();
}
return this.blockType;
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return null;
}
public NBTTagCompound getUpdateTag()
{
return this.writeInternal(new NBTTagCompound());
}
public boolean isInvalid()
{
return this.tileEntityInvalid;
}
/**
* invalidates a tile entity
*/
public void invalidate()
{
this.tileEntityInvalid = true;
}
/**
* validates a tile entity
*/
public void validate()
{
this.tileEntityInvalid = false;
}
public boolean receiveClientEvent(int id, int type)
{
return false;
}
public void updateContainingBlockInfo()
{
this.blockType = null;
this.blockMetadata = -1;
}
public void addInfoToCrashReport(CrashReportCategory reportCategory)
{
reportCategory.addDetail("Name", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
return TileEntity.REGISTRY.getNameForObject(TileEntity.this.getClass()) + " // " + TileEntity.this.getClass().getCanonicalName();
}
});
if (this.world != null)
{
CrashReportCategory.addBlockInfo(reportCategory, this.pos, this.getBlockType(), this.getBlockMetadata());
reportCategory.addDetail("Actual block type", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
int i = Block.getIdFromBlock(TileEntity.this.world.getBlockState(TileEntity.this.pos).getBlock());
try
{
return String.format("ID #%d (%s // %s // %s)", i, Block.getBlockById(i).getUnlocalizedName(), Block.getBlockById(i).getClass().getName(), Block.getBlockById(i).getRegistryName());
}
catch (Throwable var3)
{
return "ID #" + i;
}
}
});
reportCategory.addDetail("Actual block data value", new ICrashReportDetail<String>()
{
public String call() throws Exception
{
IBlockState iblockstate = TileEntity.this.world.getBlockState(TileEntity.this.pos);
int i = iblockstate.getBlock().getMetaFromState(iblockstate);
if (i < 0)
{
return "Unknown? (Got " + i + ")";
}
else
{
String s = String.format("%4s", Integer.toBinaryString(i)).replace(" ", "0");
return String.format("%1$d / 0x%1$X / 0b%2$s", i, s);
}
}
});
}
}
public void setPos(BlockPos posIn)
{
this.pos = posIn.toImmutable();
}
public boolean onlyOpsCanSetNbt()
{
return false;
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
@Nullable
public ITextComponent getDisplayName()
{
return null;
}
public void rotate(Rotation rotationIn)
{
}
public void mirror(Mirror mirrorIn)
{
}
// -- BEGIN FORGE PATCHES --
/**
* Called when you receive a TileEntityData packet for the location this
* TileEntity is currently in. On the client, the NetworkManager will always
* be the remote server. On the server, it will be whomever is responsible for
* sending the packet.
*
* @param net The NetworkManager the packet originated from
* @param pkt The data packet
*/
public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt)
{
}
/**
* Called when the chunk's TE update tag, gotten from {@link #getUpdateTag()}, is received on the client.
* <p>
* Used to handle this tag in a special way. By default this simply calls {@link #readFromNBT(NBTTagCompound)}.
*
* @param tag The {@link NBTTagCompound} sent from {@link #getUpdateTag()}
*/
public void handleUpdateTag(NBTTagCompound tag)
{
this.readFromNBT(tag);
}
/**
* Called when the chunk this TileEntity is on is Unloaded.
*/
public void onChunkUnload()
{
}
private boolean isVanilla = getClass().getName().startsWith("net.minecraft.");
/**
* Called from Chunk.setBlockIDWithMetadata and Chunk.fillChunk, determines if this tile entity should be re-created when the ID, or Metadata changes.
* Use with caution as this will leave straggler TileEntities, or create conflicts with other TileEntities if not used properly.
*
* @param world Current world
* @param pos Tile's world position
* @param oldState The old ID of the block
* @param newState The new ID of the block (May be the same)
* @return true forcing the invalidation of the existing TE, false not to invalidate the existing TE
*/
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate)
{
return isVanilla ? (oldState.getBlock() != newSate.getBlock()) : oldState != newSate;
}
public boolean shouldRenderInPass(int pass)
{
return pass == 0;
}
/**
* Sometimes default render bounding box: infinite in scope. Used to control rendering on {@link TileEntitySpecialRenderer}.
*/
public static final net.minecraft.util.math.AxisAlignedBB INFINITE_EXTENT_AABB = new net.minecraft.util.math.AxisAlignedBB(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
/**
* Return an {@link AxisAlignedBB} that controls the visible scope of a {@link TileEntitySpecialRenderer} associated with this {@link TileEntity}
* Defaults to the collision bounding box {@link Block#getCollisionBoundingBoxFromPool(World, int, int, int)} associated with the block
* at this location.
*
* @return an appropriately size {@link AxisAlignedBB} for the {@link TileEntity}
*/
@SideOnly(Side.CLIENT)
public net.minecraft.util.math.AxisAlignedBB getRenderBoundingBox()
{
net.minecraft.util.math.AxisAlignedBB bb = INFINITE_EXTENT_AABB;
Block type = getBlockType();
BlockPos pos = getPos();
if (type == Blocks.ENCHANTING_TABLE)
{
bb = new net.minecraft.util.math.AxisAlignedBB(pos, pos.add(1, 1, 1));
}
else if (type == Blocks.CHEST || type == Blocks.TRAPPED_CHEST)
{
bb = new net.minecraft.util.math.AxisAlignedBB(pos.add(-1, 0, -1), pos.add(2, 2, 2));
}
else if (type == Blocks.STRUCTURE_BLOCK)
{
bb = INFINITE_EXTENT_AABB;
}
else if (type != null && type != Blocks.BEACON)
{
net.minecraft.util.math.AxisAlignedBB cbb = null;
try
{
cbb = world.getBlockState(getPos()).getCollisionBoundingBox(world, pos).offset(pos);
}
catch (Exception e)
{
// We have to capture any exceptions that may occur here because BUKKIT servers like to send
// the tile entity data BEFORE the chunk data, you know, the OPPOSITE of what vanilla does!
// So we can not GARENTEE that the world state is the real state for the block...
// So, once again in the long line of US having to accommodate BUKKIT breaking things,
// here it is, assume that the TE is only 1 cubic block. Problem with this is that it may
// cause the TileEntity renderer to error further down the line! But alas, nothing we can do.
cbb = new net.minecraft.util.math.AxisAlignedBB(getPos().add(-1, 0, -1), getPos().add(1, 1, 1));
}
if (cbb != null) bb = cbb;
}
return bb;
}
/**
* Checks if this tile entity knows how to render its 'breaking' overlay effect.
* If this returns true, The TileEntitySpecialRenderer will be called again with break progress set.
* @return True to re-render tile with breaking effect.
*/
public boolean canRenderBreaking()
{
Block block = this.getBlockType();
return (block instanceof net.minecraft.block.BlockChest ||
block instanceof net.minecraft.block.BlockEnderChest ||
block instanceof net.minecraft.block.BlockSign ||
block instanceof net.minecraft.block.BlockSkull);
}
private NBTTagCompound customTileData;
/**
* Gets a {@link NBTTagCompound} that can be used to store custom data for this tile entity.
* It will be written, and read from disc, so it persists over world saves.
*
* @return A compound tag for custom data
*/
public NBTTagCompound getTileData()
{
if (this.customTileData == null)
{
this.customTileData = new NBTTagCompound();
}
return this.customTileData;
}
/**
* Determines if the player can overwrite the NBT data of this tile entity while they place it using a ItemStack.
* Added as a fix for MC-75630 - Exploit with signs and command blocks
* @return True to prevent NBT copy, false to allow.
*/
public boolean restrictNBTCopy()
{
return this instanceof TileEntityCommandBlock ||
this instanceof TileEntityMobSpawner ||
this instanceof TileEntitySign;
}
/**
* Called when this is first added to the world (by {@link World#addTileEntity(TileEntity)}).
* Override instead of adding {@code if (firstTick)} stuff in update.
*/
public void onLoad()
{
// NOOP
}
/**
* If the TileEntitySpecialRenderer associated with this TileEntity can be batched in with another renderers, and won't access the GL state.
* If TileEntity returns true, then TESR should have the same functionality as (and probably extend) the FastTESR class.
*/
public boolean hasFastRenderer()
{
return false;
}
private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities;
public TileEntity()
{
capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(this);
}
@Override
public boolean hasCapability(net.minecraftforge.common.capabilities.Capability<?> capability, @Nullable net.minecraft.util.EnumFacing facing)
{
return capabilities == null ? false : capabilities.hasCapability(capability, facing);
}
@Override
@Nullable
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing)
{
return capabilities == null ? null : capabilities.getCapability(capability, facing);
}
public void deserializeNBT(NBTTagCompound nbt)
{
this.readFromNBT(nbt);
}
public NBTTagCompound serializeNBT()
{
NBTTagCompound ret = new NBTTagCompound();
this.writeToNBT(ret);
return ret;
}
static
{
register("furnace", TileEntityFurnace.class);
register("chest", TileEntityChest.class);
register("ender_chest", TileEntityEnderChest.class);
register("jukebox", BlockJukebox.TileEntityJukebox.class);
register("dispenser", TileEntityDispenser.class);
register("dropper", TileEntityDropper.class);
register("sign", TileEntitySign.class);
register("mob_spawner", TileEntityMobSpawner.class);
register("noteblock", TileEntityNote.class);
register("piston", TileEntityPiston.class);
register("brewing_stand", TileEntityBrewingStand.class);
register("enchanting_table", TileEntityEnchantmentTable.class);
register("end_portal", TileEntityEndPortal.class);
register("beacon", TileEntityBeacon.class);
register("skull", TileEntitySkull.class);
register("daylight_detector", TileEntityDaylightDetector.class);
register("hopper", TileEntityHopper.class);
register("comparator", TileEntityComparator.class);
register("flower_pot", TileEntityFlowerPot.class);
register("banner", TileEntityBanner.class);
register("structure_block", TileEntityStructure.class);
register("end_gateway", TileEntityEndGateway.class);
register("command_block", TileEntityCommandBlock.class);
register("shulker_box", TileEntityShulkerBox.class);
register("bed", TileEntityBed.class);
}
}

View File

@@ -0,0 +1,245 @@
package net.minecraft.tileentity;
import com.google.common.collect.Lists;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemBanner;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.IWorldNameable;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityBanner extends TileEntity implements IWorldNameable
{
private String name;
private EnumDyeColor baseColor = EnumDyeColor.BLACK;
/** A list of all the banner patterns. */
private NBTTagList patterns;
private boolean patternDataSet;
/** A list of all patterns stored on this banner. */
private List<BannerPattern> patternList;
/** A list of all the color values stored on this banner. */
private List<EnumDyeColor> colorList;
/** This is a String representation of this banners pattern and color lists, used for texture caching. */
private String patternResourceLocation;
public void setItemValues(ItemStack stack, boolean p_175112_2_)
{
this.patterns = null;
NBTTagCompound nbttagcompound = stack.getSubCompound("BlockEntityTag");
if (nbttagcompound != null && nbttagcompound.hasKey("Patterns", 9))
{
this.patterns = nbttagcompound.getTagList("Patterns", 10).copy();
}
this.baseColor = p_175112_2_ ? getColor(stack) : ItemBanner.getBaseColor(stack);
this.patternList = null;
this.colorList = null;
this.patternResourceLocation = "";
this.patternDataSet = true;
this.name = stack.hasDisplayName() ? stack.getDisplayName() : null;
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.name : "banner";
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return this.name != null && !this.name.isEmpty();
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
public ITextComponent getDisplayName()
{
return (ITextComponent)(this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName(), new Object[0]));
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setInteger("Base", this.baseColor.getDyeDamage());
if (this.patterns != null)
{
compound.setTag("Patterns", this.patterns);
}
if (this.hasCustomName())
{
compound.setString("CustomName", this.name);
}
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
if (compound.hasKey("CustomName", 8))
{
this.name = compound.getString("CustomName");
}
this.baseColor = EnumDyeColor.byDyeDamage(compound.getInteger("Base"));
this.patterns = compound.getTagList("Patterns", 10);
this.patternList = null;
this.colorList = null;
this.patternResourceLocation = null;
this.patternDataSet = true;
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 6, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
/**
* Retrieves the amount of patterns stored on an ItemStack. If the tag does not exist this value will be 0.
*/
public static int getPatterns(ItemStack stack)
{
NBTTagCompound nbttagcompound = stack.getSubCompound("BlockEntityTag");
return nbttagcompound != null && nbttagcompound.hasKey("Patterns") ? nbttagcompound.getTagList("Patterns", 10).tagCount() : 0;
}
/**
* Retrieves the list of patterns for this tile entity. The banner data will be initialized/refreshed before this
* happens.
*/
@SideOnly(Side.CLIENT)
public List<BannerPattern> getPatternList()
{
this.initializeBannerData();
return this.patternList;
}
/**
* Retrieves the list of colors for this tile entity. The banner data will be initialized/refreshed before this
* happens.
*/
@SideOnly(Side.CLIENT)
public List<EnumDyeColor> getColorList()
{
this.initializeBannerData();
return this.colorList;
}
@SideOnly(Side.CLIENT)
public String getPatternResourceLocation()
{
this.initializeBannerData();
return this.patternResourceLocation;
}
/**
* Establishes all of the basic properties for the banner. This will also apply the data from the tile entities nbt
* tag compounds.
*/
@SideOnly(Side.CLIENT)
private void initializeBannerData()
{
if (this.patternList == null || this.colorList == null || this.patternResourceLocation == null)
{
if (!this.patternDataSet)
{
this.patternResourceLocation = "";
}
else
{
this.patternList = Lists.<BannerPattern>newArrayList();
this.colorList = Lists.<EnumDyeColor>newArrayList();
this.patternList.add(BannerPattern.BASE);
this.colorList.add(this.baseColor);
this.patternResourceLocation = "b" + this.baseColor.getDyeDamage();
if (this.patterns != null)
{
for (int i = 0; i < this.patterns.tagCount(); ++i)
{
NBTTagCompound nbttagcompound = this.patterns.getCompoundTagAt(i);
BannerPattern bannerpattern = BannerPattern.byHash(nbttagcompound.getString("Pattern"));
if (bannerpattern != null)
{
this.patternList.add(bannerpattern);
int j = nbttagcompound.getInteger("Color");
this.colorList.add(EnumDyeColor.byDyeDamage(j));
this.patternResourceLocation = this.patternResourceLocation + bannerpattern.getHashname() + j;
}
}
}
}
}
}
/**
* Removes all the banner related data from a provided instance of ItemStack.
*/
public static void removeBannerData(ItemStack stack)
{
NBTTagCompound nbttagcompound = stack.getSubCompound("BlockEntityTag");
if (nbttagcompound != null && nbttagcompound.hasKey("Patterns", 9))
{
NBTTagList nbttaglist = nbttagcompound.getTagList("Patterns", 10);
if (!nbttaglist.hasNoTags())
{
nbttaglist.removeTag(nbttaglist.tagCount() - 1);
if (nbttaglist.hasNoTags())
{
stack.getTagCompound().removeTag("BlockEntityTag");
if (stack.getTagCompound().hasNoTags())
{
stack.setTagCompound((NBTTagCompound)null);
}
}
}
}
}
public ItemStack getItem()
{
ItemStack itemstack = ItemBanner.makeBanner(this.baseColor, this.patterns);
if (this.hasCustomName())
{
itemstack.setStackDisplayName(this.getName());
}
return itemstack;
}
public static EnumDyeColor getColor(ItemStack p_190616_0_)
{
NBTTagCompound nbttagcompound = p_190616_0_.getSubCompound("BlockEntityTag");
return nbttagcompound != null && nbttagcompound.hasKey("Base") ? EnumDyeColor.byDyeDamage(nbttagcompound.getInteger("Base")) : EnumDyeColor.BLACK;
}
}

View File

@@ -0,0 +1,568 @@
package net.minecraft.tileentity;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStainedGlass;
import net.minecraft.block.BlockStainedGlassPane;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerBeacon;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityBeacon extends TileEntityLockable implements ITickable, ISidedInventory
{
/** List of effects that Beacon can apply */
public static final Potion[][] EFFECTS_LIST = new Potion[][] {{MobEffects.SPEED, MobEffects.HASTE}, {MobEffects.RESISTANCE, MobEffects.JUMP_BOOST}, {MobEffects.STRENGTH}, {MobEffects.REGENERATION}};
private static final Set<Potion> VALID_EFFECTS = Sets.<Potion>newHashSet();
/** A list of beam segments for this beacon */
private final List<TileEntityBeacon.BeamSegment> beamSegments = Lists.<TileEntityBeacon.BeamSegment>newArrayList();
@SideOnly(Side.CLIENT)
private long beamRenderCounter;
@SideOnly(Side.CLIENT)
private float beamRenderScale;
private boolean isComplete;
/** Level of this beacon's pyramid. */
private int levels = -1;
/** Primary potion effect given by this beacon. */
@Nullable
private Potion primaryEffect;
/** Secondary potion effect given by this beacon. */
@Nullable
private Potion secondaryEffect;
/** Item given to this beacon as payment. */
private ItemStack payment = ItemStack.EMPTY;
private String customName;
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
if (this.world.getTotalWorldTime() % 80L == 0L)
{
this.updateBeacon();
}
}
public void updateBeacon()
{
if (this.world != null)
{
this.updateSegmentColors();
this.addEffectsToPlayers();
}
}
private void addEffectsToPlayers()
{
if (this.isComplete && this.levels > 0 && !this.world.isRemote && this.primaryEffect != null)
{
double d0 = (double)(this.levels * 10 + 10);
int i = 0;
if (this.levels >= 4 && this.primaryEffect == this.secondaryEffect)
{
i = 1;
}
int j = (9 + this.levels * 2) * 20;
int k = this.pos.getX();
int l = this.pos.getY();
int i1 = this.pos.getZ();
AxisAlignedBB axisalignedbb = (new AxisAlignedBB((double)k, (double)l, (double)i1, (double)(k + 1), (double)(l + 1), (double)(i1 + 1))).grow(d0).expand(0.0D, (double)this.world.getHeight(), 0.0D);
List<EntityPlayer> list = this.world.<EntityPlayer>getEntitiesWithinAABB(EntityPlayer.class, axisalignedbb);
for (EntityPlayer entityplayer : list)
{
entityplayer.addPotionEffect(new PotionEffect(this.primaryEffect, j, i, true, true));
}
if (this.levels >= 4 && this.primaryEffect != this.secondaryEffect && this.secondaryEffect != null)
{
for (EntityPlayer entityplayer1 : list)
{
entityplayer1.addPotionEffect(new PotionEffect(this.secondaryEffect, j, 0, true, true));
}
}
}
}
private void updateSegmentColors()
{
int i = this.pos.getX();
int j = this.pos.getY();
int k = this.pos.getZ();
int l = this.levels;
this.levels = 0;
this.beamSegments.clear();
this.isComplete = true;
TileEntityBeacon.BeamSegment tileentitybeacon$beamsegment = new TileEntityBeacon.BeamSegment(EnumDyeColor.WHITE.getColorComponentValues());
this.beamSegments.add(tileentitybeacon$beamsegment);
boolean flag = true;
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (int i1 = j + 1; i1 < 256; ++i1)
{
IBlockState iblockstate = this.world.getBlockState(blockpos$mutableblockpos.setPos(i, i1, k));
float[] afloat;
if (iblockstate.getBlock() == Blocks.STAINED_GLASS)
{
afloat = ((EnumDyeColor)iblockstate.getValue(BlockStainedGlass.COLOR)).getColorComponentValues();
}
else
{
if (iblockstate.getBlock() != Blocks.STAINED_GLASS_PANE)
{
if (iblockstate.getLightOpacity(world, blockpos$mutableblockpos) >= 15 && iblockstate.getBlock() != Blocks.BEDROCK)
{
this.isComplete = false;
this.beamSegments.clear();
break;
}
float[] customColor = iblockstate.getBlock().getBeaconColorMultiplier(iblockstate, this.world, blockpos$mutableblockpos, getPos());
if (customColor != null)
afloat = customColor;
else {
tileentitybeacon$beamsegment.incrementHeight();
continue;
}
}
else
afloat = ((EnumDyeColor)iblockstate.getValue(BlockStainedGlassPane.COLOR)).getColorComponentValues();
}
if (!flag)
{
afloat = new float[] {(tileentitybeacon$beamsegment.getColors()[0] + afloat[0]) / 2.0F, (tileentitybeacon$beamsegment.getColors()[1] + afloat[1]) / 2.0F, (tileentitybeacon$beamsegment.getColors()[2] + afloat[2]) / 2.0F};
}
if (Arrays.equals(afloat, tileentitybeacon$beamsegment.getColors()))
{
tileentitybeacon$beamsegment.incrementHeight();
}
else
{
tileentitybeacon$beamsegment = new TileEntityBeacon.BeamSegment(afloat);
this.beamSegments.add(tileentitybeacon$beamsegment);
}
flag = false;
}
if (this.isComplete)
{
for (int l1 = 1; l1 <= 4; this.levels = l1++)
{
int i2 = j - l1;
if (i2 < 0)
{
break;
}
boolean flag1 = true;
for (int j1 = i - l1; j1 <= i + l1 && flag1; ++j1)
{
for (int k1 = k - l1; k1 <= k + l1; ++k1)
{
Block block = this.world.getBlockState(new BlockPos(j1, i2, k1)).getBlock();
if (!block.isBeaconBase(this.world, new BlockPos(j1, i2, k1), getPos()))
{
flag1 = false;
break;
}
}
}
if (!flag1)
{
break;
}
}
if (this.levels == 0)
{
this.isComplete = false;
}
}
if (!this.world.isRemote && l < this.levels)
{
for (EntityPlayerMP entityplayermp : this.world.getEntitiesWithinAABB(EntityPlayerMP.class, (new AxisAlignedBB((double)i, (double)j, (double)k, (double)i, (double)(j - 4), (double)k)).grow(10.0D, 5.0D, 10.0D)))
{
CriteriaTriggers.CONSTRUCT_BEACON.trigger(entityplayermp, this);
}
}
}
@SideOnly(Side.CLIENT)
public List<TileEntityBeacon.BeamSegment> getBeamSegments()
{
return this.beamSegments;
}
@SideOnly(Side.CLIENT)
public float shouldBeamRender()
{
if (!this.isComplete)
{
return 0.0F;
}
else
{
int i = (int)(this.world.getTotalWorldTime() - this.beamRenderCounter);
this.beamRenderCounter = this.world.getTotalWorldTime();
if (i > 1)
{
this.beamRenderScale -= (float)i / 40.0F;
if (this.beamRenderScale < 0.0F)
{
this.beamRenderScale = 0.0F;
}
}
this.beamRenderScale += 0.025F;
if (this.beamRenderScale > 1.0F)
{
this.beamRenderScale = 1.0F;
}
return this.beamRenderScale;
}
}
public int getLevels()
{
return this.levels;
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 3, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared()
{
return 65536.0D;
}
@Nullable
private static Potion isBeaconEffect(int p_184279_0_)
{
Potion potion = Potion.getPotionById(p_184279_0_);
return VALID_EFFECTS.contains(potion) ? potion : null;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.primaryEffect = isBeaconEffect(compound.getInteger("Primary"));
this.secondaryEffect = isBeaconEffect(compound.getInteger("Secondary"));
this.levels = compound.getInteger("Levels");
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setInteger("Primary", Potion.getIdFromPotion(this.primaryEffect));
compound.setInteger("Secondary", Potion.getIdFromPotion(this.secondaryEffect));
compound.setInteger("Levels", this.levels);
return compound;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return 1;
}
public boolean isEmpty()
{
return this.payment.isEmpty();
}
/**
* Returns the stack in the given slot.
*/
public ItemStack getStackInSlot(int index)
{
return index == 0 ? this.payment : ItemStack.EMPTY;
}
/**
* Removes up to a specified number of items from an inventory slot and returns them in a new stack.
*/
public ItemStack decrStackSize(int index, int count)
{
if (index == 0 && !this.payment.isEmpty())
{
if (count >= this.payment.getCount())
{
ItemStack itemstack = this.payment;
this.payment = ItemStack.EMPTY;
return itemstack;
}
else
{
return this.payment.splitStack(count);
}
}
else
{
return ItemStack.EMPTY;
}
}
/**
* Removes a stack from the given slot and returns it.
*/
public ItemStack removeStackFromSlot(int index)
{
if (index == 0)
{
ItemStack itemstack = this.payment;
this.payment = ItemStack.EMPTY;
return itemstack;
}
else
{
return ItemStack.EMPTY;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int index, ItemStack stack)
{
if (index == 0)
{
this.payment = stack;
}
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.beacon";
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return this.customName != null && !this.customName.isEmpty();
}
public void setName(String name)
{
this.customName = name;
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 1;
}
/**
* Don't rename this method to canInteractWith due to conflicts with Container
*/
public boolean isUsableByPlayer(EntityPlayer player)
{
if (this.world.getTileEntity(this.pos) != this)
{
return false;
}
else
{
return player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
}
public void openInventory(EntityPlayer player)
{
}
public void closeInventory(EntityPlayer player)
{
}
/**
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. For
* guis use Slot.isItemValid
*/
public boolean isItemValidForSlot(int index, ItemStack stack)
{
return stack.getItem() != null && stack.getItem().isBeaconPayment(stack);
}
public String getGuiID()
{
return "minecraft:beacon";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
return new ContainerBeacon(playerInventory, this);
}
public int getField(int id)
{
switch (id)
{
case 0:
return this.levels;
case 1:
return Potion.getIdFromPotion(this.primaryEffect);
case 2:
return Potion.getIdFromPotion(this.secondaryEffect);
default:
return 0;
}
}
public void setField(int id, int value)
{
switch (id)
{
case 0:
this.levels = value;
break;
case 1:
this.primaryEffect = isBeaconEffect(value);
break;
case 2:
this.secondaryEffect = isBeaconEffect(value);
}
}
public int getFieldCount()
{
return 3;
}
public void clear()
{
this.payment = ItemStack.EMPTY;
}
public boolean receiveClientEvent(int id, int type)
{
if (id == 1)
{
this.updateBeacon();
return true;
}
else
{
return super.receiveClientEvent(id, type);
}
}
public int[] getSlotsForFace(EnumFacing side)
{
return new int[0];
}
/**
* Returns true if automation can insert the given item in the given slot from the given side.
*/
public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction)
{
return false;
}
/**
* Returns true if automation can extract the given item in the given slot from the given side.
*/
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{
return false;
}
static
{
for (Potion[] apotion : EFFECTS_LIST)
{
Collections.addAll(VALID_EFFECTS, apotion);
}
}
public static class BeamSegment
{
/** RGB (0 to 1.0) colors of this beam segment */
private final float[] colors;
private int height;
public BeamSegment(float[] colorsIn)
{
this.colors = colorsIn;
this.height = 1;
}
protected void incrementHeight()
{
++this.height;
}
/**
* Returns RGB (0 to 1.0) colors of this beam segment
*/
public float[] getColors()
{
return this.colors;
}
@SideOnly(Side.CLIENT)
public int getHeight()
{
return this.height;
}
}
}

View File

@@ -0,0 +1,69 @@
package net.minecraft.tileentity;
import net.minecraft.block.BlockBed;
import net.minecraft.init.Items;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityBed extends TileEntity
{
private EnumDyeColor color = EnumDyeColor.RED;
public void setItemValues(ItemStack p_193051_1_)
{
this.setColor(EnumDyeColor.byMetadata(p_193051_1_.getMetadata()));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
if (compound.hasKey("color"))
{
this.color = EnumDyeColor.byMetadata(compound.getInteger("color"));
}
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setInteger("color", this.color.getMetadata());
return compound;
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 11, this.getUpdateTag());
}
public EnumDyeColor getColor()
{
return this.color;
}
public void setColor(EnumDyeColor color)
{
this.color = color;
this.markDirty();
}
@SideOnly(Side.CLIENT)
public boolean isHeadPiece()
{
return BlockBed.isHeadPiece(this.getBlockMetadata());
}
public ItemStack getItemStack()
{
return new ItemStack(Items.BED, 1, this.color.getMetadata());
}
}

View File

@@ -0,0 +1,459 @@
package net.minecraft.tileentity;
import java.util.Arrays;
import net.minecraft.block.BlockBrewingStand;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerBrewingStand;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionHelper;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
import net.minecraft.util.math.BlockPos;
public class TileEntityBrewingStand extends TileEntityLockable implements ITickable, ISidedInventory
{
/** an array of the input slot indices */
private static final int[] SLOTS_FOR_UP = new int[] {3};
private static final int[] SLOTS_FOR_DOWN = new int[] {0, 1, 2, 3};
/** an array of the output slot indices */
private static final int[] OUTPUT_SLOTS = new int[] {0, 1, 2, 4};
/** The ItemStacks currently placed in the slots of the brewing stand */
private NonNullList<ItemStack> brewingItemStacks = NonNullList.<ItemStack>withSize(5, ItemStack.EMPTY);
private int brewTime;
/** an integer with each bit specifying whether that slot of the stand contains a potion */
private boolean[] filledSlots;
/** used to check if the current ingredient has been removed from the brewing stand during brewing */
private Item ingredientID;
private String customName;
private int fuel;
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.brewing";
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return this.customName != null && !this.customName.isEmpty();
}
public void setName(String name)
{
this.customName = name;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return this.brewingItemStacks.size();
}
public boolean isEmpty()
{
for (ItemStack itemstack : this.brewingItemStacks)
{
if (!itemstack.isEmpty())
{
return false;
}
}
return true;
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
ItemStack itemstack = this.brewingItemStacks.get(4);
if (this.fuel <= 0 && itemstack.getItem() == Items.BLAZE_POWDER)
{
this.fuel = 20;
itemstack.shrink(1);
this.markDirty();
}
boolean flag = this.canBrew();
boolean flag1 = this.brewTime > 0;
ItemStack itemstack1 = this.brewingItemStacks.get(3);
if (flag1)
{
--this.brewTime;
boolean flag2 = this.brewTime == 0;
if (flag2 && flag)
{
this.brewPotions();
this.markDirty();
}
else if (!flag)
{
this.brewTime = 0;
this.markDirty();
}
else if (this.ingredientID != itemstack1.getItem())
{
this.brewTime = 0;
this.markDirty();
}
}
else if (flag && this.fuel > 0)
{
--this.fuel;
this.brewTime = 400;
this.ingredientID = itemstack1.getItem();
this.markDirty();
}
if (!this.world.isRemote)
{
boolean[] aboolean = this.createFilledSlotsArray();
if (!Arrays.equals(aboolean, this.filledSlots))
{
this.filledSlots = aboolean;
IBlockState iblockstate = this.world.getBlockState(this.getPos());
if (!(iblockstate.getBlock() instanceof BlockBrewingStand))
{
return;
}
for (int i = 0; i < BlockBrewingStand.HAS_BOTTLE.length; ++i)
{
iblockstate = iblockstate.withProperty(BlockBrewingStand.HAS_BOTTLE[i], Boolean.valueOf(aboolean[i]));
}
this.world.setBlockState(this.pos, iblockstate, 2);
}
}
}
/**
* Creates an array of boolean values, each value represents a potion input slot, value is true if the slot is not
* null.
*/
public boolean[] createFilledSlotsArray()
{
boolean[] aboolean = new boolean[3];
for (int i = 0; i < 3; ++i)
{
if (!((ItemStack)this.brewingItemStacks.get(i)).isEmpty())
{
aboolean[i] = true;
}
}
return aboolean;
}
private boolean canBrew()
{
if (1 == 1) return net.minecraftforge.common.brewing.BrewingRecipeRegistry.canBrew(brewingItemStacks, brewingItemStacks.get(3), OUTPUT_SLOTS); // divert to VanillaBrewingRegistry
ItemStack itemstack = this.brewingItemStacks.get(3);
if (itemstack.isEmpty())
{
return false;
}
else if (!PotionHelper.isReagent(itemstack))
{
return false;
}
else
{
for (int i = 0; i < 3; ++i)
{
ItemStack itemstack1 = this.brewingItemStacks.get(i);
if (!itemstack1.isEmpty() && PotionHelper.hasConversions(itemstack1, itemstack))
{
return true;
}
}
return false;
}
}
private void brewPotions()
{
if (net.minecraftforge.event.ForgeEventFactory.onPotionAttemptBrew(brewingItemStacks)) return;
ItemStack itemstack = this.brewingItemStacks.get(3);
net.minecraftforge.common.brewing.BrewingRecipeRegistry.brewPotions(brewingItemStacks, brewingItemStacks.get(3), OUTPUT_SLOTS);
itemstack.shrink(1);
BlockPos blockpos = this.getPos();
if (itemstack.getItem().hasContainerItem(itemstack))
{
ItemStack itemstack1 = itemstack.getItem().getContainerItem(itemstack);
if (itemstack.isEmpty())
{
itemstack = itemstack1;
}
else
{
InventoryHelper.spawnItemStack(this.world, (double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ(), itemstack1);
}
}
this.brewingItemStacks.set(3, itemstack);
this.world.playEvent(1035, blockpos, 0);
net.minecraftforge.event.ForgeEventFactory.onPotionBrewed(brewingItemStacks);
}
public static void registerFixesBrewingStand(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityBrewingStand.class, new String[] {"Items"}));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.brewingItemStacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, this.brewingItemStacks);
this.brewTime = compound.getShort("BrewTime");
if (compound.hasKey("CustomName", 8))
{
this.customName = compound.getString("CustomName");
}
this.fuel = compound.getByte("Fuel");
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setShort("BrewTime", (short)this.brewTime);
ItemStackHelper.saveAllItems(compound, this.brewingItemStacks);
if (this.hasCustomName())
{
compound.setString("CustomName", this.customName);
}
compound.setByte("Fuel", (byte)this.fuel);
return compound;
}
/**
* Returns the stack in the given slot.
*/
public ItemStack getStackInSlot(int index)
{
return index >= 0 && index < this.brewingItemStacks.size() ? (ItemStack)this.brewingItemStacks.get(index) : ItemStack.EMPTY;
}
/**
* Removes up to a specified number of items from an inventory slot and returns them in a new stack.
*/
public ItemStack decrStackSize(int index, int count)
{
return ItemStackHelper.getAndSplit(this.brewingItemStacks, index, count);
}
/**
* Removes a stack from the given slot and returns it.
*/
public ItemStack removeStackFromSlot(int index)
{
return ItemStackHelper.getAndRemove(this.brewingItemStacks, index);
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int index, ItemStack stack)
{
if (index >= 0 && index < this.brewingItemStacks.size())
{
this.brewingItemStacks.set(index, stack);
}
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 64;
}
/**
* Don't rename this method to canInteractWith due to conflicts with Container
*/
public boolean isUsableByPlayer(EntityPlayer player)
{
if (this.world.getTileEntity(this.pos) != this)
{
return false;
}
else
{
return player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
}
public void openInventory(EntityPlayer player)
{
}
public void closeInventory(EntityPlayer player)
{
}
/**
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. For
* guis use Slot.isItemValid
*/
public boolean isItemValidForSlot(int index, ItemStack stack)
{
if (index == 3)
{
return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidIngredient(stack);
}
else
{
Item item = stack.getItem();
if (index == 4)
{
return item == Items.BLAZE_POWDER;
}
else
{
return net.minecraftforge.common.brewing.BrewingRecipeRegistry.isValidInput(stack) && this.getStackInSlot(index).isEmpty();
}
}
}
public int[] getSlotsForFace(EnumFacing side)
{
if (side == EnumFacing.UP)
{
return SLOTS_FOR_UP;
}
else
{
return side == EnumFacing.DOWN ? SLOTS_FOR_DOWN : OUTPUT_SLOTS;
}
}
/**
* Returns true if automation can insert the given item in the given slot from the given side.
*/
public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction)
{
return this.isItemValidForSlot(index, itemStackIn);
}
/**
* Returns true if automation can extract the given item in the given slot from the given side.
*/
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{
if (index == 3)
{
return stack.getItem() == Items.GLASS_BOTTLE;
}
else
{
return true;
}
}
public String getGuiID()
{
return "minecraft:brewing_stand";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
return new ContainerBrewingStand(playerInventory, this);
}
public int getField(int id)
{
switch (id)
{
case 0:
return this.brewTime;
case 1:
return this.fuel;
default:
return 0;
}
}
public void setField(int id, int value)
{
switch (id)
{
case 0:
this.brewTime = value;
break;
case 1:
this.fuel = value;
}
}
net.minecraftforge.items.IItemHandler handlerInput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP);
net.minecraftforge.items.IItemHandler handlerOutput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN);
net.minecraftforge.items.IItemHandler handlerSides = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.NORTH);
@SuppressWarnings("unchecked")
@Override
@javax.annotation.Nullable
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing)
{
if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
{
if (facing == EnumFacing.UP)
return (T) handlerInput;
else if (facing == EnumFacing.DOWN)
return (T) handlerOutput;
else
return (T) handlerSides;
}
return super.getCapability(capability, facing);
}
public int getFieldCount()
{
return 2;
}
public void clear()
{
this.brewingItemStacks.clear();
}
}

View File

@@ -0,0 +1,441 @@
package net.minecraft.tileentity;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockChest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryLargeChest;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
public class TileEntityChest extends TileEntityLockableLoot implements ITickable
{
private NonNullList<ItemStack> chestContents = NonNullList.<ItemStack>withSize(27, ItemStack.EMPTY);
/** Determines if the check for adjacent chests has taken place. */
public boolean adjacentChestChecked;
/** Contains the chest tile located adjacent to this one (if any) */
public TileEntityChest adjacentChestZNeg;
/** Contains the chest tile located adjacent to this one (if any) */
public TileEntityChest adjacentChestXPos;
/** Contains the chest tile located adjacent to this one (if any) */
public TileEntityChest adjacentChestXNeg;
/** Contains the chest tile located adjacent to this one (if any) */
public TileEntityChest adjacentChestZPos;
/** The current angle of the lid (between 0 and 1) */
public float lidAngle;
/** The angle of the lid last tick */
public float prevLidAngle;
/** The number of players currently using this chest */
public int numPlayersUsing;
/** Server sync counter (once per 20 ticks) */
private int ticksSinceSync;
private BlockChest.Type cachedChestType;
public TileEntityChest()
{
}
public TileEntityChest(BlockChest.Type typeIn)
{
this.cachedChestType = typeIn;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return 27;
}
public boolean isEmpty()
{
for (ItemStack itemstack : this.chestContents)
{
if (!itemstack.isEmpty())
{
return false;
}
}
return true;
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.chest";
}
public static void registerFixesChest(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityChest.class, new String[] {"Items"}));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.chestContents = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (!this.checkLootAndRead(compound))
{
ItemStackHelper.loadAllItems(compound, this.chestContents);
}
if (compound.hasKey("CustomName", 8))
{
this.customName = compound.getString("CustomName");
}
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
if (!this.checkLootAndWrite(compound))
{
ItemStackHelper.saveAllItems(compound, this.chestContents);
}
if (this.hasCustomName())
{
compound.setString("CustomName", this.customName);
}
return compound;
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 64;
}
public void updateContainingBlockInfo()
{
super.updateContainingBlockInfo();
this.adjacentChestChecked = false;
doubleChestHandler = null;
}
@SuppressWarnings("incomplete-switch")
private void setNeighbor(TileEntityChest chestTe, EnumFacing side)
{
if (chestTe.isInvalid())
{
this.adjacentChestChecked = false;
}
else if (this.adjacentChestChecked)
{
switch (side)
{
case NORTH:
if (this.adjacentChestZNeg != chestTe)
{
this.adjacentChestChecked = false;
}
break;
case SOUTH:
if (this.adjacentChestZPos != chestTe)
{
this.adjacentChestChecked = false;
}
break;
case EAST:
if (this.adjacentChestXPos != chestTe)
{
this.adjacentChestChecked = false;
}
break;
case WEST:
if (this.adjacentChestXNeg != chestTe)
{
this.adjacentChestChecked = false;
}
}
}
}
/**
* Performs the check for adjacent chests to determine if this chest is double or not.
*/
public void checkForAdjacentChests()
{
if (!this.adjacentChestChecked)
{
if (this.world == null || !this.world.isAreaLoaded(this.pos, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbors
this.adjacentChestChecked = true;
this.adjacentChestXNeg = this.getAdjacentChest(EnumFacing.WEST);
this.adjacentChestXPos = this.getAdjacentChest(EnumFacing.EAST);
this.adjacentChestZNeg = this.getAdjacentChest(EnumFacing.NORTH);
this.adjacentChestZPos = this.getAdjacentChest(EnumFacing.SOUTH);
}
}
@Nullable
protected TileEntityChest getAdjacentChest(EnumFacing side)
{
BlockPos blockpos = this.pos.offset(side);
if (this.isChestAt(blockpos))
{
TileEntity tileentity = this.world.getTileEntity(blockpos);
if (tileentity instanceof TileEntityChest)
{
TileEntityChest tileentitychest = (TileEntityChest)tileentity;
tileentitychest.setNeighbor(this, side.getOpposite());
return tileentitychest;
}
}
return null;
}
private boolean isChestAt(BlockPos posIn)
{
if (this.world == null)
{
return false;
}
else
{
Block block = this.world.getBlockState(posIn).getBlock();
return block instanceof BlockChest && ((BlockChest)block).chestType == this.getChestType();
}
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
this.checkForAdjacentChests();
int i = this.pos.getX();
int j = this.pos.getY();
int k = this.pos.getZ();
++this.ticksSinceSync;
if (!this.world.isRemote && this.numPlayersUsing != 0 && (this.ticksSinceSync + i + j + k) % 200 == 0)
{
this.numPlayersUsing = 0;
float f = 5.0F;
for (EntityPlayer entityplayer : this.world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB((double)((float)i - 5.0F), (double)((float)j - 5.0F), (double)((float)k - 5.0F), (double)((float)(i + 1) + 5.0F), (double)((float)(j + 1) + 5.0F), (double)((float)(k + 1) + 5.0F))))
{
if (entityplayer.openContainer instanceof ContainerChest)
{
IInventory iinventory = ((ContainerChest)entityplayer.openContainer).getLowerChestInventory();
if (iinventory == this || iinventory instanceof InventoryLargeChest && ((InventoryLargeChest)iinventory).isPartOfLargeChest(this))
{
++this.numPlayersUsing;
}
}
}
}
this.prevLidAngle = this.lidAngle;
float f1 = 0.1F;
if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null)
{
double d1 = (double)i + 0.5D;
double d2 = (double)k + 0.5D;
if (this.adjacentChestZPos != null)
{
d2 += 0.5D;
}
if (this.adjacentChestXPos != null)
{
d1 += 0.5D;
}
this.world.playSound((EntityPlayer)null, d1, (double)j + 0.5D, d2, SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
}
if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
{
float f2 = this.lidAngle;
if (this.numPlayersUsing > 0)
{
this.lidAngle += 0.1F;
}
else
{
this.lidAngle -= 0.1F;
}
if (this.lidAngle > 1.0F)
{
this.lidAngle = 1.0F;
}
float f3 = 0.5F;
if (this.lidAngle < 0.5F && f2 >= 0.5F && this.adjacentChestZNeg == null && this.adjacentChestXNeg == null)
{
double d3 = (double)i + 0.5D;
double d0 = (double)k + 0.5D;
if (this.adjacentChestZPos != null)
{
d0 += 0.5D;
}
if (this.adjacentChestXPos != null)
{
d3 += 0.5D;
}
this.world.playSound((EntityPlayer)null, d3, (double)j + 0.5D, d0, SoundEvents.BLOCK_CHEST_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
}
if (this.lidAngle < 0.0F)
{
this.lidAngle = 0.0F;
}
}
}
public boolean receiveClientEvent(int id, int type)
{
if (id == 1)
{
this.numPlayersUsing = type;
return true;
}
else
{
return super.receiveClientEvent(id, type);
}
}
public void openInventory(EntityPlayer player)
{
if (!player.isSpectator())
{
if (this.numPlayersUsing < 0)
{
this.numPlayersUsing = 0;
}
++this.numPlayersUsing;
this.world.addBlockEvent(this.pos, this.getBlockType(), 1, this.numPlayersUsing);
this.world.notifyNeighborsOfStateChange(this.pos, this.getBlockType(), false);
if (this.getChestType() == BlockChest.Type.TRAP)
{
this.world.notifyNeighborsOfStateChange(this.pos.down(), this.getBlockType(), false);
}
}
}
public void closeInventory(EntityPlayer player)
{
if (!player.isSpectator() && this.getBlockType() instanceof BlockChest)
{
--this.numPlayersUsing;
this.world.addBlockEvent(this.pos, this.getBlockType(), 1, this.numPlayersUsing);
this.world.notifyNeighborsOfStateChange(this.pos, this.getBlockType(), false);
if (this.getChestType() == BlockChest.Type.TRAP)
{
this.world.notifyNeighborsOfStateChange(this.pos.down(), this.getBlockType(), false);
}
}
}
public net.minecraftforge.items.VanillaDoubleChestItemHandler doubleChestHandler;
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable net.minecraft.util.EnumFacing facing)
{
if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
{
if(doubleChestHandler == null || doubleChestHandler.needsRefresh())
doubleChestHandler = net.minecraftforge.items.VanillaDoubleChestItemHandler.get(this);
if (doubleChestHandler != null && doubleChestHandler != net.minecraftforge.items.VanillaDoubleChestItemHandler.NO_ADJACENT_CHESTS_INSTANCE)
return (T) doubleChestHandler;
}
return super.getCapability(capability, facing);
}
public net.minecraftforge.items.IItemHandler getSingleChestHandler()
{
return super.getCapability(net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
}
/**
* invalidates a tile entity
*/
public void invalidate()
{
super.invalidate();
this.updateContainingBlockInfo();
this.checkForAdjacentChests();
}
public BlockChest.Type getChestType()
{
if (this.cachedChestType == null)
{
if (this.world == null || !(this.getBlockType() instanceof BlockChest))
{
return BlockChest.Type.BASIC;
}
this.cachedChestType = ((BlockChest)this.getBlockType()).chestType;
}
return this.cachedChestType;
}
public String getGuiID()
{
return "minecraft:chest";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
this.fillWithLoot(playerIn);
return new ContainerChest(playerInventory, this, playerIn);
}
protected NonNullList<ItemStack> getItems()
{
return this.chestContents;
}
}

View File

@@ -0,0 +1,250 @@
package net.minecraft.tileentity;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCommandBlock;
import net.minecraft.block.state.IBlockState;
import net.minecraft.command.CommandResultStats;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityCommandBlock extends TileEntity
{
private boolean powered;
private boolean auto;
private boolean conditionMet;
private boolean sendToClient;
private final CommandBlockBaseLogic commandBlockLogic = new CommandBlockBaseLogic()
{
/**
* Get the position in the world. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return the coordinates 0, 0, 0
*/
public BlockPos getPosition()
{
return TileEntityCommandBlock.this.pos;
}
/**
* Get the position vector. <b>{@code null} is not allowed!</b> If you are not an entity in the world, return
* 0.0D, 0.0D, 0.0D
*/
public Vec3d getPositionVector()
{
return new Vec3d((double)TileEntityCommandBlock.this.pos.getX() + 0.5D, (double)TileEntityCommandBlock.this.pos.getY() + 0.5D, (double)TileEntityCommandBlock.this.pos.getZ() + 0.5D);
}
/**
* Get the world, if available. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return the overworld
*/
public World getEntityWorld()
{
return TileEntityCommandBlock.this.getWorld();
}
/**
* Sets the command.
*/
public void setCommand(String command)
{
super.setCommand(command);
TileEntityCommandBlock.this.markDirty();
}
public void updateCommand()
{
IBlockState iblockstate = TileEntityCommandBlock.this.world.getBlockState(TileEntityCommandBlock.this.pos);
TileEntityCommandBlock.this.getWorld().notifyBlockUpdate(TileEntityCommandBlock.this.pos, iblockstate, iblockstate, 3);
}
/**
* Currently this returns 0 for the traditional command block, and 1 for the minecart command block
*/
@SideOnly(Side.CLIENT)
public int getCommandBlockType()
{
return 0;
}
/**
* Fills in information about the command block for the packet. entityId for the minecart version, and X/Y/Z for
* the traditional version
*/
@SideOnly(Side.CLIENT)
public void fillInInfo(ByteBuf buf)
{
buf.writeInt(TileEntityCommandBlock.this.pos.getX());
buf.writeInt(TileEntityCommandBlock.this.pos.getY());
buf.writeInt(TileEntityCommandBlock.this.pos.getZ());
}
/**
* Get the Minecraft server instance
*/
public MinecraftServer getServer()
{
return TileEntityCommandBlock.this.world.getMinecraftServer();
}
};
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
this.commandBlockLogic.writeToNBT(compound);
compound.setBoolean("powered", this.isPowered());
compound.setBoolean("conditionMet", this.isConditionMet());
compound.setBoolean("auto", this.isAuto());
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.commandBlockLogic.readDataFromNBT(compound);
this.powered = compound.getBoolean("powered");
this.conditionMet = compound.getBoolean("conditionMet");
this.setAuto(compound.getBoolean("auto"));
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
if (this.isSendToClient())
{
this.setSendToClient(false);
NBTTagCompound nbttagcompound = this.writeToNBT(new NBTTagCompound());
return new SPacketUpdateTileEntity(this.pos, 2, nbttagcompound);
}
else
{
return null;
}
}
public boolean onlyOpsCanSetNbt()
{
return true;
}
public CommandBlockBaseLogic getCommandBlockLogic()
{
return this.commandBlockLogic;
}
public CommandResultStats getCommandResultStats()
{
return this.commandBlockLogic.getCommandResultStats();
}
public void setPowered(boolean poweredIn)
{
this.powered = poweredIn;
}
public boolean isPowered()
{
return this.powered;
}
public boolean isAuto()
{
return this.auto;
}
public void setAuto(boolean autoIn)
{
boolean flag = this.auto;
this.auto = autoIn;
if (!flag && autoIn && !this.powered && this.world != null && this.getMode() != TileEntityCommandBlock.Mode.SEQUENCE)
{
Block block = this.getBlockType();
if (block instanceof BlockCommandBlock)
{
this.setConditionMet();
this.world.scheduleUpdate(this.pos, block, block.tickRate(this.world));
}
}
}
public boolean isConditionMet()
{
return this.conditionMet;
}
public boolean setConditionMet()
{
this.conditionMet = true;
if (this.isConditional())
{
BlockPos blockpos = this.pos.offset(((EnumFacing)this.world.getBlockState(this.pos).getValue(BlockCommandBlock.FACING)).getOpposite());
if (this.world.getBlockState(blockpos).getBlock() instanceof BlockCommandBlock)
{
TileEntity tileentity = this.world.getTileEntity(blockpos);
this.conditionMet = tileentity instanceof TileEntityCommandBlock && ((TileEntityCommandBlock)tileentity).getCommandBlockLogic().getSuccessCount() > 0;
}
else
{
this.conditionMet = false;
}
}
return this.conditionMet;
}
public boolean isSendToClient()
{
return this.sendToClient;
}
public void setSendToClient(boolean p_184252_1_)
{
this.sendToClient = p_184252_1_;
}
public TileEntityCommandBlock.Mode getMode()
{
Block block = this.getBlockType();
if (block == Blocks.COMMAND_BLOCK)
{
return TileEntityCommandBlock.Mode.REDSTONE;
}
else if (block == Blocks.REPEATING_COMMAND_BLOCK)
{
return TileEntityCommandBlock.Mode.AUTO;
}
else
{
return block == Blocks.CHAIN_COMMAND_BLOCK ? TileEntityCommandBlock.Mode.SEQUENCE : TileEntityCommandBlock.Mode.REDSTONE;
}
}
public boolean isConditional()
{
IBlockState iblockstate = this.world.getBlockState(this.getPos());
return iblockstate.getBlock() instanceof BlockCommandBlock ? ((Boolean)iblockstate.getValue(BlockCommandBlock.CONDITIONAL)).booleanValue() : false;
}
/**
* validates a tile entity
*/
public void validate()
{
this.blockType = null;
super.validate();
}
public static enum Mode
{
SEQUENCE,
AUTO,
REDSTONE;
}
}

View File

@@ -0,0 +1,31 @@
package net.minecraft.tileentity;
import net.minecraft.nbt.NBTTagCompound;
public class TileEntityComparator extends TileEntity
{
private int outputSignal;
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setInteger("OutputSignal", this.outputSignal);
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.outputSignal = compound.getInteger("OutputSignal");
}
public int getOutputSignal()
{
return this.outputSignal;
}
public void setOutputSignal(int outputSignalIn)
{
this.outputSignal = outputSignalIn;
}
}

View File

@@ -0,0 +1,23 @@
package net.minecraft.tileentity;
import net.minecraft.block.BlockDaylightDetector;
import net.minecraft.util.ITickable;
public class TileEntityDaylightDetector extends TileEntity implements ITickable
{
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
if (this.world != null && !this.world.isRemote && this.world.getTotalWorldTime() % 20L == 0L)
{
this.blockType = this.getBlockType();
if (this.blockType instanceof BlockDaylightDetector)
{
((BlockDaylightDetector)this.blockType).updatePower(this.world, this.pos);
}
}
}
}

View File

@@ -0,0 +1,146 @@
package net.minecraft.tileentity;
import java.util.Random;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerDispenser;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
public class TileEntityDispenser extends TileEntityLockableLoot
{
private static final Random RNG = new Random();
private NonNullList<ItemStack> stacks = NonNullList.<ItemStack>withSize(9, ItemStack.EMPTY);
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return 9;
}
public boolean isEmpty()
{
for (ItemStack itemstack : this.stacks)
{
if (!itemstack.isEmpty())
{
return false;
}
}
return true;
}
public int getDispenseSlot()
{
this.fillWithLoot((EntityPlayer)null);
int i = -1;
int j = 1;
for (int k = 0; k < this.stacks.size(); ++k)
{
if (!((ItemStack)this.stacks.get(k)).isEmpty() && RNG.nextInt(j++) == 0)
{
i = k;
}
}
return i;
}
/**
* Add the given ItemStack to this Dispenser. Return the Slot the Item was placed in or -1 if no free slot is
* available.
*/
public int addItemStack(ItemStack stack)
{
for (int i = 0; i < this.stacks.size(); ++i)
{
if (((ItemStack)this.stacks.get(i)).isEmpty())
{
this.setInventorySlotContents(i, stack);
return i;
}
}
return -1;
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.dispenser";
}
public static void registerFixes(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityDispenser.class, new String[] {"Items"}));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.stacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (!this.checkLootAndRead(compound))
{
ItemStackHelper.loadAllItems(compound, this.stacks);
}
if (compound.hasKey("CustomName", 8))
{
this.customName = compound.getString("CustomName");
}
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
if (!this.checkLootAndWrite(compound))
{
ItemStackHelper.saveAllItems(compound, this.stacks);
}
if (this.hasCustomName())
{
compound.setString("CustomName", this.customName);
}
return compound;
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 64;
}
public String getGuiID()
{
return "minecraft:dispenser";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
this.fillWithLoot(playerIn);
return new ContainerDispenser(playerInventory, this);
}
protected NonNullList<ItemStack> getItems()
{
return this.stacks;
}
}

View File

@@ -0,0 +1,26 @@
package net.minecraft.tileentity;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
public class TileEntityDropper extends TileEntityDispenser
{
public static void registerFixesDropper(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityDropper.class, new String[] {"Items"}));
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.dropper";
}
public String getGuiID()
{
return "minecraft:dropper";
}
}

View File

@@ -0,0 +1,171 @@
package net.minecraft.tileentity;
import java.util.Random;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerEnchantment;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.IInteractionObject;
public class TileEntityEnchantmentTable extends TileEntity implements ITickable, IInteractionObject
{
public int tickCount;
public float pageFlip;
public float pageFlipPrev;
public float flipT;
public float flipA;
public float bookSpread;
public float bookSpreadPrev;
public float bookRotation;
public float bookRotationPrev;
public float tRot;
private static final Random rand = new Random();
private String customName;
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
if (this.hasCustomName())
{
compound.setString("CustomName", this.customName);
}
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
if (compound.hasKey("CustomName", 8))
{
this.customName = compound.getString("CustomName");
}
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
this.bookSpreadPrev = this.bookSpread;
this.bookRotationPrev = this.bookRotation;
EntityPlayer entityplayer = this.world.getClosestPlayer((double)((float)this.pos.getX() + 0.5F), (double)((float)this.pos.getY() + 0.5F), (double)((float)this.pos.getZ() + 0.5F), 3.0D, false);
if (entityplayer != null)
{
double d0 = entityplayer.posX - (double)((float)this.pos.getX() + 0.5F);
double d1 = entityplayer.posZ - (double)((float)this.pos.getZ() + 0.5F);
this.tRot = (float)MathHelper.atan2(d1, d0);
this.bookSpread += 0.1F;
if (this.bookSpread < 0.5F || rand.nextInt(40) == 0)
{
float f1 = this.flipT;
while (true)
{
this.flipT += (float)(rand.nextInt(4) - rand.nextInt(4));
if (f1 != this.flipT)
{
break;
}
}
}
}
else
{
this.tRot += 0.02F;
this.bookSpread -= 0.1F;
}
while (this.bookRotation >= (float)Math.PI)
{
this.bookRotation -= ((float)Math.PI * 2F);
}
while (this.bookRotation < -(float)Math.PI)
{
this.bookRotation += ((float)Math.PI * 2F);
}
while (this.tRot >= (float)Math.PI)
{
this.tRot -= ((float)Math.PI * 2F);
}
while (this.tRot < -(float)Math.PI)
{
this.tRot += ((float)Math.PI * 2F);
}
float f2;
for (f2 = this.tRot - this.bookRotation; f2 >= (float)Math.PI; f2 -= ((float)Math.PI * 2F))
{
;
}
while (f2 < -(float)Math.PI)
{
f2 += ((float)Math.PI * 2F);
}
this.bookRotation += f2 * 0.4F;
this.bookSpread = MathHelper.clamp(this.bookSpread, 0.0F, 1.0F);
++this.tickCount;
this.pageFlipPrev = this.pageFlip;
float f = (this.flipT - this.pageFlip) * 0.4F;
float f3 = 0.2F;
f = MathHelper.clamp(f, -0.2F, 0.2F);
this.flipA += (f - this.flipA) * 0.9F;
this.pageFlip += this.flipA;
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.enchant";
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return this.customName != null && !this.customName.isEmpty();
}
public void setCustomName(String customNameIn)
{
this.customName = customNameIn;
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
public ITextComponent getDisplayName()
{
return (ITextComponent)(this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName(), new Object[0]));
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
return new ContainerEnchantment(playerInventory, this.world, this.pos);
}
public String getGuiID()
{
return "minecraft:enchanting_table";
}
}

View File

@@ -0,0 +1,330 @@
package net.minecraft.tileentity;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderEnd;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.feature.WorldGenEndGateway;
import net.minecraft.world.gen.feature.WorldGenEndIsland;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TileEntityEndGateway extends TileEntityEndPortal implements ITickable
{
private static final Logger LOGGER = LogManager.getLogger();
private long age;
private int teleportCooldown;
private BlockPos exitPortal;
private boolean exactTeleport;
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setLong("Age", this.age);
if (this.exitPortal != null)
{
compound.setTag("ExitPortal", NBTUtil.createPosTag(this.exitPortal));
}
if (this.exactTeleport)
{
compound.setBoolean("ExactTeleport", this.exactTeleport);
}
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.age = compound.getLong("Age");
if (compound.hasKey("ExitPortal", 10))
{
this.exitPortal = NBTUtil.getPosFromTag(compound.getCompoundTag("ExitPortal"));
}
this.exactTeleport = compound.getBoolean("ExactTeleport");
}
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared()
{
return 65536.0D;
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
boolean flag = this.isSpawning();
boolean flag1 = this.isCoolingDown();
++this.age;
if (flag1)
{
--this.teleportCooldown;
}
else if (!this.world.isRemote)
{
List<Entity> list = this.world.<Entity>getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(this.getPos()));
if (!list.isEmpty())
{
this.teleportEntity(list.get(0));
}
if (this.age % 2400L == 0L)
{
this.triggerCooldown();
}
}
if (flag != this.isSpawning() || flag1 != this.isCoolingDown())
{
this.markDirty();
}
}
public boolean isSpawning()
{
return this.age < 200L;
}
public boolean isCoolingDown()
{
return this.teleportCooldown > 0;
}
@SideOnly(Side.CLIENT)
public float getSpawnPercent(float p_184302_1_)
{
return MathHelper.clamp(((float)this.age + p_184302_1_) / 200.0F, 0.0F, 1.0F);
}
@SideOnly(Side.CLIENT)
public float getCooldownPercent(float p_184305_1_)
{
return 1.0F - MathHelper.clamp(((float)this.teleportCooldown - p_184305_1_) / 40.0F, 0.0F, 1.0F);
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 8, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public void triggerCooldown()
{
if (!this.world.isRemote)
{
this.teleportCooldown = 40;
this.world.addBlockEvent(this.getPos(), this.getBlockType(), 1, 0);
this.markDirty();
}
}
public boolean receiveClientEvent(int id, int type)
{
if (id == 1)
{
this.teleportCooldown = 40;
return true;
}
else
{
return super.receiveClientEvent(id, type);
}
}
public void teleportEntity(Entity entityIn)
{
if (!this.world.isRemote && !this.isCoolingDown())
{
this.teleportCooldown = 100;
if (this.exitPortal == null && this.world.provider instanceof WorldProviderEnd)
{
this.findExitPortal();
}
if (this.exitPortal != null)
{
BlockPos blockpos = this.exactTeleport ? this.exitPortal : this.findExitPosition();
entityIn.setPositionAndUpdate((double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 0.5D, (double)blockpos.getZ() + 0.5D);
}
this.triggerCooldown();
}
}
private BlockPos findExitPosition()
{
BlockPos blockpos = findHighestBlock(this.world, this.exitPortal, 5, false);
LOGGER.debug("Best exit position for portal at {} is {}", this.exitPortal, blockpos);
return blockpos.up();
}
private void findExitPortal()
{
Vec3d vec3d = (new Vec3d((double)this.getPos().getX(), 0.0D, (double)this.getPos().getZ())).normalize();
Vec3d vec3d1 = vec3d.scale(1024.0D);
for (int i = 16; getChunk(this.world, vec3d1).getTopFilledSegment() > 0 && i-- > 0; vec3d1 = vec3d1.add(vec3d.scale(-16.0D)))
{
LOGGER.debug("Skipping backwards past nonempty chunk at {}", (Object)vec3d1);
}
for (int j = 16; getChunk(this.world, vec3d1).getTopFilledSegment() == 0 && j-- > 0; vec3d1 = vec3d1.add(vec3d.scale(16.0D)))
{
LOGGER.debug("Skipping forward past empty chunk at {}", (Object)vec3d1);
}
LOGGER.debug("Found chunk at {}", (Object)vec3d1);
Chunk chunk = getChunk(this.world, vec3d1);
this.exitPortal = findSpawnpointInChunk(chunk);
if (this.exitPortal == null)
{
this.exitPortal = new BlockPos(vec3d1.x + 0.5D, 75.0D, vec3d1.z + 0.5D);
LOGGER.debug("Failed to find suitable block, settling on {}", (Object)this.exitPortal);
(new WorldGenEndIsland()).generate(this.world, new Random(this.exitPortal.toLong()), this.exitPortal);
}
else
{
LOGGER.debug("Found block at {}", (Object)this.exitPortal);
}
this.exitPortal = findHighestBlock(this.world, this.exitPortal, 16, true);
LOGGER.debug("Creating portal at {}", (Object)this.exitPortal);
this.exitPortal = this.exitPortal.up(10);
this.createExitPortal(this.exitPortal);
this.markDirty();
}
private static BlockPos findHighestBlock(World p_184308_0_, BlockPos p_184308_1_, int p_184308_2_, boolean p_184308_3_)
{
BlockPos blockpos = null;
for (int i = -p_184308_2_; i <= p_184308_2_; ++i)
{
for (int j = -p_184308_2_; j <= p_184308_2_; ++j)
{
if (i != 0 || j != 0 || p_184308_3_)
{
for (int k = 255; k > (blockpos == null ? 0 : blockpos.getY()); --k)
{
BlockPos blockpos1 = new BlockPos(p_184308_1_.getX() + i, k, p_184308_1_.getZ() + j);
IBlockState iblockstate = p_184308_0_.getBlockState(blockpos1);
if (iblockstate.isBlockNormalCube() && (p_184308_3_ || iblockstate.getBlock() != Blocks.BEDROCK))
{
blockpos = blockpos1;
break;
}
}
}
}
}
return blockpos == null ? p_184308_1_ : blockpos;
}
private static Chunk getChunk(World worldIn, Vec3d vec3)
{
return worldIn.getChunkFromChunkCoords(MathHelper.floor(vec3.x / 16.0D), MathHelper.floor(vec3.z / 16.0D));
}
@Nullable
private static BlockPos findSpawnpointInChunk(Chunk chunkIn)
{
BlockPos blockpos = new BlockPos(chunkIn.x * 16, 30, chunkIn.z * 16);
int i = chunkIn.getTopFilledSegment() + 16 - 1;
BlockPos blockpos1 = new BlockPos(chunkIn.x * 16 + 16 - 1, i, chunkIn.z * 16 + 16 - 1);
BlockPos blockpos2 = null;
double d0 = 0.0D;
for (BlockPos blockpos3 : BlockPos.getAllInBox(blockpos, blockpos1))
{
IBlockState iblockstate = chunkIn.getBlockState(blockpos3);
if (iblockstate.getBlock() == Blocks.END_STONE && !chunkIn.getBlockState(blockpos3.up(1)).isBlockNormalCube() && !chunkIn.getBlockState(blockpos3.up(2)).isBlockNormalCube())
{
double d1 = blockpos3.distanceSqToCenter(0.0D, 0.0D, 0.0D);
if (blockpos2 == null || d1 < d0)
{
blockpos2 = blockpos3;
d0 = d1;
}
}
}
return blockpos2;
}
private void createExitPortal(BlockPos posIn)
{
(new WorldGenEndGateway()).generate(this.world, new Random(), posIn);
TileEntity tileentity = this.world.getTileEntity(posIn);
if (tileentity instanceof TileEntityEndGateway)
{
TileEntityEndGateway tileentityendgateway = (TileEntityEndGateway)tileentity;
tileentityendgateway.exitPortal = new BlockPos(this.getPos());
tileentityendgateway.markDirty();
}
else
{
LOGGER.warn("Couldn't save exit portal at {}", (Object)posIn);
}
}
@SideOnly(Side.CLIENT)
public boolean shouldRenderFace(EnumFacing p_184313_1_)
{
return this.getBlockType().getDefaultState().shouldSideBeRendered(this.world, this.getPos(), p_184313_1_);
}
@SideOnly(Side.CLIENT)
public int getParticleAmount()
{
int i = 0;
for (EnumFacing enumfacing : EnumFacing.values())
{
i += this.shouldRenderFace(enumfacing) ? 1 : 0;
}
return i;
}
public void setExactPosition(BlockPos p_190603_1_)
{
this.exactTeleport = true;
this.exitPortal = p_190603_1_;
}
}

View File

@@ -0,0 +1,14 @@
package net.minecraft.tileentity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityEndPortal extends TileEntity
{
@SideOnly(Side.CLIENT)
public boolean shouldRenderFace(EnumFacing p_184313_1_)
{
return p_184313_1_ == EnumFacing.UP;
}
}

View File

@@ -0,0 +1,119 @@
package net.minecraft.tileentity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.ITickable;
import net.minecraft.util.SoundCategory;
public class TileEntityEnderChest extends TileEntity implements ITickable
{
public float lidAngle;
/** The angle of the ender chest lid last tick */
public float prevLidAngle;
public int numPlayersUsing;
private int ticksSinceSync;
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
if (++this.ticksSinceSync % 20 * 4 == 0)
{
this.world.addBlockEvent(this.pos, Blocks.ENDER_CHEST, 1, this.numPlayersUsing);
}
this.prevLidAngle = this.lidAngle;
int i = this.pos.getX();
int j = this.pos.getY();
int k = this.pos.getZ();
float f = 0.1F;
if (this.numPlayersUsing > 0 && this.lidAngle == 0.0F)
{
double d0 = (double)i + 0.5D;
double d1 = (double)k + 0.5D;
this.world.playSound((EntityPlayer)null, d0, (double)j + 0.5D, d1, SoundEvents.BLOCK_ENDERCHEST_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
}
if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F)
{
float f2 = this.lidAngle;
if (this.numPlayersUsing > 0)
{
this.lidAngle += 0.1F;
}
else
{
this.lidAngle -= 0.1F;
}
if (this.lidAngle > 1.0F)
{
this.lidAngle = 1.0F;
}
float f1 = 0.5F;
if (this.lidAngle < 0.5F && f2 >= 0.5F)
{
double d3 = (double)i + 0.5D;
double d2 = (double)k + 0.5D;
this.world.playSound((EntityPlayer)null, d3, (double)j + 0.5D, d2, SoundEvents.BLOCK_ENDERCHEST_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
}
if (this.lidAngle < 0.0F)
{
this.lidAngle = 0.0F;
}
}
}
public boolean receiveClientEvent(int id, int type)
{
if (id == 1)
{
this.numPlayersUsing = type;
return true;
}
else
{
return super.receiveClientEvent(id, type);
}
}
/**
* invalidates a tile entity
*/
public void invalidate()
{
this.updateContainingBlockInfo();
super.invalidate();
}
public void openChest()
{
++this.numPlayersUsing;
this.world.addBlockEvent(this.pos, Blocks.ENDER_CHEST, 1, this.numPlayersUsing);
}
public void closeChest()
{
--this.numPlayersUsing;
this.world.addBlockEvent(this.pos, Blocks.ENDER_CHEST, 1, this.numPlayersUsing);
}
public boolean canBeUsed(EntityPlayer player)
{
if (this.world.getTileEntity(this.pos) != this)
{
return false;
}
else
{
return player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
}
}

View File

@@ -0,0 +1,87 @@
package net.minecraft.tileentity;
import javax.annotation.Nullable;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.datafix.DataFixer;
public class TileEntityFlowerPot extends TileEntity
{
private Item flowerPotItem;
private int flowerPotData;
public TileEntityFlowerPot()
{
}
public TileEntityFlowerPot(Item potItem, int potData)
{
this.flowerPotItem = potItem;
this.flowerPotData = potData;
}
public static void registerFixesFlowerPot(DataFixer fixer)
{
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
ResourceLocation resourcelocation = Item.REGISTRY.getNameForObject(this.flowerPotItem);
compound.setString("Item", resourcelocation == null ? "" : resourcelocation.toString());
compound.setInteger("Data", this.flowerPotData);
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
if (compound.hasKey("Item", 8))
{
this.flowerPotItem = Item.getByNameOrId(compound.getString("Item"));
}
else
{
this.flowerPotItem = Item.getItemById(compound.getInteger("Item"));
}
this.flowerPotData = compound.getInteger("Data");
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 5, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public void setItemStack(ItemStack stack)
{
this.flowerPotItem = stack.getItem();
this.flowerPotData = stack.getMetadata();
}
public ItemStack getFlowerItemStack()
{
return this.flowerPotItem == null ? ItemStack.EMPTY : new ItemStack(this.flowerPotItem, 1, this.flowerPotData);
}
@Nullable
public Item getFlowerPotItem()
{
return this.flowerPotItem;
}
public int getFlowerPotData()
{
return this.flowerPotData;
}
}

View File

@@ -0,0 +1,610 @@
package net.minecraft.tileentity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFurnace;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerFurnace;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.inventory.SlotFurnaceFuel;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBoat;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemHoe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityFurnace extends TileEntityLockable implements ITickable, ISidedInventory
{
private static final int[] SLOTS_TOP = new int[] {0};
private static final int[] SLOTS_BOTTOM = new int[] {2, 1};
private static final int[] SLOTS_SIDES = new int[] {1};
/** The ItemStacks that hold the items currently being used in the furnace */
private NonNullList<ItemStack> furnaceItemStacks = NonNullList.<ItemStack>withSize(3, ItemStack.EMPTY);
/** The number of ticks that the furnace will keep burning */
private int furnaceBurnTime;
/** The number of ticks that a fresh copy of the currently-burning item would keep the furnace burning for */
private int currentItemBurnTime;
private int cookTime;
private int totalCookTime;
private String furnaceCustomName;
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return this.furnaceItemStacks.size();
}
public boolean isEmpty()
{
for (ItemStack itemstack : this.furnaceItemStacks)
{
if (!itemstack.isEmpty())
{
return false;
}
}
return true;
}
/**
* Returns the stack in the given slot.
*/
public ItemStack getStackInSlot(int index)
{
return this.furnaceItemStacks.get(index);
}
/**
* Removes up to a specified number of items from an inventory slot and returns them in a new stack.
*/
public ItemStack decrStackSize(int index, int count)
{
return ItemStackHelper.getAndSplit(this.furnaceItemStacks, index, count);
}
/**
* Removes a stack from the given slot and returns it.
*/
public ItemStack removeStackFromSlot(int index)
{
return ItemStackHelper.getAndRemove(this.furnaceItemStacks, index);
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int index, ItemStack stack)
{
ItemStack itemstack = this.furnaceItemStacks.get(index);
boolean flag = !stack.isEmpty() && stack.isItemEqual(itemstack) && ItemStack.areItemStackTagsEqual(stack, itemstack);
this.furnaceItemStacks.set(index, stack);
if (stack.getCount() > this.getInventoryStackLimit())
{
stack.setCount(this.getInventoryStackLimit());
}
if (index == 0 && !flag)
{
this.totalCookTime = this.getCookTime(stack);
this.cookTime = 0;
this.markDirty();
}
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.furnaceCustomName : "container.furnace";
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return this.furnaceCustomName != null && !this.furnaceCustomName.isEmpty();
}
public void setCustomInventoryName(String p_145951_1_)
{
this.furnaceCustomName = p_145951_1_;
}
public static void registerFixesFurnace(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityFurnace.class, new String[] {"Items"}));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.furnaceItemStacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, this.furnaceItemStacks);
this.furnaceBurnTime = compound.getInteger("BurnTime");
this.cookTime = compound.getInteger("CookTime");
this.totalCookTime = compound.getInteger("CookTimeTotal");
this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks.get(1));
if (compound.hasKey("CustomName", 8))
{
this.furnaceCustomName = compound.getString("CustomName");
}
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setInteger("BurnTime", (short)this.furnaceBurnTime);
compound.setInteger("CookTime", (short)this.cookTime);
compound.setInteger("CookTimeTotal", (short)this.totalCookTime);
ItemStackHelper.saveAllItems(compound, this.furnaceItemStacks);
if (this.hasCustomName())
{
compound.setString("CustomName", this.furnaceCustomName);
}
return compound;
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 64;
}
/**
* Furnace isBurning
*/
public boolean isBurning()
{
return this.furnaceBurnTime > 0;
}
@SideOnly(Side.CLIENT)
public static boolean isBurning(IInventory inventory)
{
return inventory.getField(0) > 0;
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
boolean flag = this.isBurning();
boolean flag1 = false;
if (this.isBurning())
{
--this.furnaceBurnTime;
}
if (!this.world.isRemote)
{
ItemStack itemstack = this.furnaceItemStacks.get(1);
if (this.isBurning() || !itemstack.isEmpty() && !((ItemStack)this.furnaceItemStacks.get(0)).isEmpty())
{
if (!this.isBurning() && this.canSmelt())
{
this.furnaceBurnTime = getItemBurnTime(itemstack);
this.currentItemBurnTime = this.furnaceBurnTime;
if (this.isBurning())
{
flag1 = true;
if (!itemstack.isEmpty())
{
Item item = itemstack.getItem();
itemstack.shrink(1);
if (itemstack.isEmpty())
{
ItemStack item1 = item.getContainerItem(itemstack);
this.furnaceItemStacks.set(1, item1);
}
}
}
}
if (this.isBurning() && this.canSmelt())
{
++this.cookTime;
if (this.cookTime == this.totalCookTime)
{
this.cookTime = 0;
this.totalCookTime = this.getCookTime(this.furnaceItemStacks.get(0));
this.smeltItem();
flag1 = true;
}
}
else
{
this.cookTime = 0;
}
}
else if (!this.isBurning() && this.cookTime > 0)
{
this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.totalCookTime);
}
if (flag != this.isBurning())
{
flag1 = true;
BlockFurnace.setState(this.isBurning(), this.world, this.pos);
}
}
if (flag1)
{
this.markDirty();
}
}
public int getCookTime(ItemStack stack)
{
return 200;
}
/**
* Returns true if the furnace can smelt an item, i.e. has a source item, destination stack isn't full, etc.
*/
private boolean canSmelt()
{
if (((ItemStack)this.furnaceItemStacks.get(0)).isEmpty())
{
return false;
}
else
{
ItemStack itemstack = FurnaceRecipes.instance().getSmeltingResult(this.furnaceItemStacks.get(0));
if (itemstack.isEmpty())
{
return false;
}
else
{
ItemStack itemstack1 = this.furnaceItemStacks.get(2);
if (itemstack1.isEmpty())
{
return true;
}
else if (!itemstack1.isItemEqual(itemstack))
{
return false;
}
else if (itemstack1.getCount() + itemstack.getCount() <= this.getInventoryStackLimit() && itemstack1.getCount() + itemstack.getCount() <= itemstack1.getMaxStackSize()) // Forge fix: make furnace respect stack sizes in furnace recipes
{
return true;
}
else
{
return itemstack1.getCount() + itemstack.getCount() <= itemstack.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes
}
}
}
}
/**
* Turn one item from the furnace source stack into the appropriate smelted item in the furnace result stack
*/
public void smeltItem()
{
if (this.canSmelt())
{
ItemStack itemstack = this.furnaceItemStacks.get(0);
ItemStack itemstack1 = FurnaceRecipes.instance().getSmeltingResult(itemstack);
ItemStack itemstack2 = this.furnaceItemStacks.get(2);
if (itemstack2.isEmpty())
{
this.furnaceItemStacks.set(2, itemstack1.copy());
}
else if (itemstack2.getItem() == itemstack1.getItem())
{
itemstack2.grow(itemstack1.getCount());
}
if (itemstack.getItem() == Item.getItemFromBlock(Blocks.SPONGE) && itemstack.getMetadata() == 1 && !((ItemStack)this.furnaceItemStacks.get(1)).isEmpty() && ((ItemStack)this.furnaceItemStacks.get(1)).getItem() == Items.BUCKET)
{
this.furnaceItemStacks.set(1, new ItemStack(Items.WATER_BUCKET));
}
itemstack.shrink(1);
}
}
/**
* Returns the number of ticks that the supplied fuel item will keep the furnace burning, or 0 if the item isn't
* fuel
*/
public static int getItemBurnTime(ItemStack stack)
{
if (stack.isEmpty())
{
return 0;
}
else
{
int burnTime = net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(stack);
if (burnTime >= 0) return burnTime;
Item item = stack.getItem();
if (item == Item.getItemFromBlock(Blocks.WOODEN_SLAB))
{
return 150;
}
else if (item == Item.getItemFromBlock(Blocks.WOOL))
{
return 100;
}
else if (item == Item.getItemFromBlock(Blocks.CARPET))
{
return 67;
}
else if (item == Item.getItemFromBlock(Blocks.LADDER))
{
return 300;
}
else if (item == Item.getItemFromBlock(Blocks.WOODEN_BUTTON))
{
return 100;
}
else if (Block.getBlockFromItem(item).getDefaultState().getMaterial() == Material.WOOD)
{
return 300;
}
else if (item == Item.getItemFromBlock(Blocks.COAL_BLOCK))
{
return 16000;
}
else if (item instanceof ItemTool && "WOOD".equals(((ItemTool)item).getToolMaterialName()))
{
return 200;
}
else if (item instanceof ItemSword && "WOOD".equals(((ItemSword)item).getToolMaterialName()))
{
return 200;
}
else if (item instanceof ItemHoe && "WOOD".equals(((ItemHoe)item).getMaterialName()))
{
return 200;
}
else if (item == Items.STICK)
{
return 100;
}
else if (item != Items.BOW && item != Items.FISHING_ROD)
{
if (item == Items.SIGN)
{
return 200;
}
else if (item == Items.COAL)
{
return 1600;
}
else if (item == Items.LAVA_BUCKET)
{
return 20000;
}
else if (item != Item.getItemFromBlock(Blocks.SAPLING) && item != Items.BOWL)
{
if (item == Items.BLAZE_ROD)
{
return 2400;
}
else if (item instanceof ItemDoor && item != Items.IRON_DOOR)
{
return 200;
}
else
{
return item instanceof ItemBoat ? 400 : 0;
}
}
else
{
return 100;
}
}
else
{
return 300;
}
}
}
public static boolean isItemFuel(ItemStack stack)
{
return getItemBurnTime(stack) > 0;
}
/**
* Don't rename this method to canInteractWith due to conflicts with Container
*/
public boolean isUsableByPlayer(EntityPlayer player)
{
if (this.world.getTileEntity(this.pos) != this)
{
return false;
}
else
{
return player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
}
public void openInventory(EntityPlayer player)
{
}
public void closeInventory(EntityPlayer player)
{
}
/**
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. For
* guis use Slot.isItemValid
*/
public boolean isItemValidForSlot(int index, ItemStack stack)
{
if (index == 2)
{
return false;
}
else if (index != 1)
{
return true;
}
else
{
ItemStack itemstack = this.furnaceItemStacks.get(1);
return isItemFuel(stack) || SlotFurnaceFuel.isBucket(stack) && itemstack.getItem() != Items.BUCKET;
}
}
public int[] getSlotsForFace(EnumFacing side)
{
if (side == EnumFacing.DOWN)
{
return SLOTS_BOTTOM;
}
else
{
return side == EnumFacing.UP ? SLOTS_TOP : SLOTS_SIDES;
}
}
/**
* Returns true if automation can insert the given item in the given slot from the given side.
*/
public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction)
{
return this.isItemValidForSlot(index, itemStackIn);
}
/**
* Returns true if automation can extract the given item in the given slot from the given side.
*/
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{
if (direction == EnumFacing.DOWN && index == 1)
{
Item item = stack.getItem();
if (item != Items.WATER_BUCKET && item != Items.BUCKET)
{
return false;
}
}
return true;
}
public String getGuiID()
{
return "minecraft:furnace";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
return new ContainerFurnace(playerInventory, this);
}
public int getField(int id)
{
switch (id)
{
case 0:
return this.furnaceBurnTime;
case 1:
return this.currentItemBurnTime;
case 2:
return this.cookTime;
case 3:
return this.totalCookTime;
default:
return 0;
}
}
public void setField(int id, int value)
{
switch (id)
{
case 0:
this.furnaceBurnTime = value;
break;
case 1:
this.currentItemBurnTime = value;
break;
case 2:
this.cookTime = value;
break;
case 3:
this.totalCookTime = value;
}
}
public int getFieldCount()
{
return 4;
}
public void clear()
{
this.furnaceItemStacks.clear();
}
net.minecraftforge.items.IItemHandler handlerTop = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP);
net.minecraftforge.items.IItemHandler handlerBottom = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN);
net.minecraftforge.items.IItemHandler handlerSide = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.WEST);
@SuppressWarnings("unchecked")
@Override
@javax.annotation.Nullable
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing)
{
if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
if (facing == EnumFacing.DOWN)
return (T) handlerBottom;
else if (facing == EnumFacing.UP)
return (T) handlerTop;
else
return (T) handlerSide;
return super.getCapability(capability, facing);
}
}

View File

@@ -0,0 +1,695 @@
package net.minecraft.tileentity;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockChest;
import net.minecraft.block.BlockHopper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerHopper;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class TileEntityHopper extends TileEntityLockableLoot implements IHopper, ITickable
{
private NonNullList<ItemStack> inventory = NonNullList.<ItemStack>withSize(5, ItemStack.EMPTY);
private int transferCooldown = -1;
private long tickedGameTime;
public static void registerFixesHopper(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityHopper.class, new String[] {"Items"}));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.inventory = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (!this.checkLootAndRead(compound))
{
ItemStackHelper.loadAllItems(compound, this.inventory);
}
if (compound.hasKey("CustomName", 8))
{
this.customName = compound.getString("CustomName");
}
this.transferCooldown = compound.getInteger("TransferCooldown");
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
if (!this.checkLootAndWrite(compound))
{
ItemStackHelper.saveAllItems(compound, this.inventory);
}
compound.setInteger("TransferCooldown", this.transferCooldown);
if (this.hasCustomName())
{
compound.setString("CustomName", this.customName);
}
return compound;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return this.inventory.size();
}
/**
* Removes up to a specified number of items from an inventory slot and returns them in a new stack.
*/
public ItemStack decrStackSize(int index, int count)
{
this.fillWithLoot((EntityPlayer)null);
ItemStack itemstack = ItemStackHelper.getAndSplit(this.getItems(), index, count);
return itemstack;
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int index, ItemStack stack)
{
this.fillWithLoot((EntityPlayer)null);
this.getItems().set(index, stack);
if (stack.getCount() > this.getInventoryStackLimit())
{
stack.setCount(this.getInventoryStackLimit());
}
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.hopper";
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 64;
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
if (this.world != null && !this.world.isRemote)
{
--this.transferCooldown;
this.tickedGameTime = this.world.getTotalWorldTime();
if (!this.isOnTransferCooldown())
{
this.setTransferCooldown(0);
this.updateHopper();
}
}
}
protected boolean updateHopper()
{
if (this.world != null && !this.world.isRemote)
{
if (!this.isOnTransferCooldown() && BlockHopper.isEnabled(this.getBlockMetadata()))
{
boolean flag = false;
if (!this.isInventoryEmpty())
{
flag = this.transferItemsOut();
}
if (!this.isFull())
{
flag = pullItems(this) || flag;
}
if (flag)
{
this.setTransferCooldown(8);
this.markDirty();
return true;
}
}
return false;
}
else
{
return false;
}
}
private boolean isInventoryEmpty()
{
for (ItemStack itemstack : this.inventory)
{
if (!itemstack.isEmpty())
{
return false;
}
}
return true;
}
public boolean isEmpty()
{
return this.isInventoryEmpty();
}
private boolean isFull()
{
for (ItemStack itemstack : this.inventory)
{
if (itemstack.isEmpty() || itemstack.getCount() != itemstack.getMaxStackSize())
{
return false;
}
}
return true;
}
private boolean transferItemsOut()
{
if (net.minecraftforge.items.VanillaInventoryCodeHooks.insertHook(this)) { return true; }
IInventory iinventory = this.getInventoryForHopperTransfer();
if (iinventory == null)
{
return false;
}
else
{
EnumFacing enumfacing = BlockHopper.getFacing(this.getBlockMetadata()).getOpposite();
if (this.isInventoryFull(iinventory, enumfacing))
{
return false;
}
else
{
for (int i = 0; i < this.getSizeInventory(); ++i)
{
if (!this.getStackInSlot(i).isEmpty())
{
ItemStack itemstack = this.getStackInSlot(i).copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(this, iinventory, this.decrStackSize(i, 1), enumfacing);
if (itemstack1.isEmpty())
{
iinventory.markDirty();
return true;
}
this.setInventorySlotContents(i, itemstack);
}
}
return false;
}
}
}
/**
* Returns false if the inventory has any room to place items in
*/
private boolean isInventoryFull(IInventory inventoryIn, EnumFacing side)
{
if (inventoryIn instanceof ISidedInventory)
{
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn;
int[] aint = isidedinventory.getSlotsForFace(side);
for (int k : aint)
{
ItemStack itemstack1 = isidedinventory.getStackInSlot(k);
if (itemstack1.isEmpty() || itemstack1.getCount() != itemstack1.getMaxStackSize())
{
return false;
}
}
}
else
{
int i = inventoryIn.getSizeInventory();
for (int j = 0; j < i; ++j)
{
ItemStack itemstack = inventoryIn.getStackInSlot(j);
if (itemstack.isEmpty() || itemstack.getCount() != itemstack.getMaxStackSize())
{
return false;
}
}
}
return true;
}
/**
* Returns false if the specified IInventory contains any items
*/
private static boolean isInventoryEmpty(IInventory inventoryIn, EnumFacing side)
{
if (inventoryIn instanceof ISidedInventory)
{
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn;
int[] aint = isidedinventory.getSlotsForFace(side);
for (int i : aint)
{
if (!isidedinventory.getStackInSlot(i).isEmpty())
{
return false;
}
}
}
else
{
int j = inventoryIn.getSizeInventory();
for (int k = 0; k < j; ++k)
{
if (!inventoryIn.getStackInSlot(k).isEmpty())
{
return false;
}
}
}
return true;
}
/**
* Pull dropped {@link net.minecraft.entity.item.EntityItem EntityItem}s from the world above the hopper and items
* from any inventory attached to this hopper into the hopper's inventory.
*
* @param hopper the hopper in question
* @return whether any items were successfully added to the hopper
*/
public static boolean pullItems(IHopper hopper)
{
Boolean ret = net.minecraftforge.items.VanillaInventoryCodeHooks.extractHook(hopper);
if (ret != null) return ret;
IInventory iinventory = getSourceInventory(hopper);
if (iinventory != null)
{
EnumFacing enumfacing = EnumFacing.DOWN;
if (isInventoryEmpty(iinventory, enumfacing))
{
return false;
}
if (iinventory instanceof ISidedInventory)
{
ISidedInventory isidedinventory = (ISidedInventory)iinventory;
int[] aint = isidedinventory.getSlotsForFace(enumfacing);
for (int i : aint)
{
if (pullItemFromSlot(hopper, iinventory, i, enumfacing))
{
return true;
}
}
}
else
{
int j = iinventory.getSizeInventory();
for (int k = 0; k < j; ++k)
{
if (pullItemFromSlot(hopper, iinventory, k, enumfacing))
{
return true;
}
}
}
}
else
{
for (EntityItem entityitem : getCaptureItems(hopper.getWorld(), hopper.getXPos(), hopper.getYPos(), hopper.getZPos()))
{
if (putDropInInventoryAllSlots((IInventory)null, hopper, entityitem))
{
return true;
}
}
}
return false;
}
/**
* Pulls from the specified slot in the inventory and places in any available slot in the hopper. Returns true if
* the entire stack was moved
*/
private static boolean pullItemFromSlot(IHopper hopper, IInventory inventoryIn, int index, EnumFacing direction)
{
ItemStack itemstack = inventoryIn.getStackInSlot(index);
if (!itemstack.isEmpty() && canExtractItemFromSlot(inventoryIn, itemstack, index, direction))
{
ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = putStackInInventoryAllSlots(inventoryIn, hopper, inventoryIn.decrStackSize(index, 1), (EnumFacing)null);
if (itemstack2.isEmpty())
{
inventoryIn.markDirty();
return true;
}
inventoryIn.setInventorySlotContents(index, itemstack1);
}
return false;
}
/**
* Attempts to place the passed EntityItem's stack into the inventory using as many slots as possible. Returns false
* if the stackSize of the drop was not depleted.
*/
public static boolean putDropInInventoryAllSlots(IInventory source, IInventory destination, EntityItem entity)
{
boolean flag = false;
if (entity == null)
{
return false;
}
else
{
ItemStack itemstack = entity.getItem().copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(source, destination, itemstack, (EnumFacing)null);
if (itemstack1.isEmpty())
{
flag = true;
entity.setDead();
}
else
{
entity.setItem(itemstack1);
}
return flag;
}
}
protected net.minecraftforge.items.IItemHandler createUnSidedHandler()
{
return new net.minecraftforge.items.VanillaHopperItemHandler(this);
}
/**
* Attempts to place the passed stack in the inventory, using as many slots as required. Returns leftover items
*/
public static ItemStack putStackInInventoryAllSlots(IInventory source, IInventory destination, ItemStack stack, @Nullable EnumFacing direction)
{
if (destination instanceof ISidedInventory && direction != null)
{
ISidedInventory isidedinventory = (ISidedInventory)destination;
int[] aint = isidedinventory.getSlotsForFace(direction);
for (int k = 0; k < aint.length && !stack.isEmpty(); ++k)
{
stack = insertStack(source, destination, stack, aint[k], direction);
}
}
else
{
int i = destination.getSizeInventory();
for (int j = 0; j < i && !stack.isEmpty(); ++j)
{
stack = insertStack(source, destination, stack, j, direction);
}
}
return stack;
}
/**
* Can this hopper insert the specified item from the specified slot on the specified side?
*/
private static boolean canInsertItemInSlot(IInventory inventoryIn, ItemStack stack, int index, EnumFacing side)
{
if (!inventoryIn.isItemValidForSlot(index, stack))
{
return false;
}
else
{
return !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canInsertItem(index, stack, side);
}
}
/**
* Can this hopper extract the specified item from the specified slot on the specified side?
*/
private static boolean canExtractItemFromSlot(IInventory inventoryIn, ItemStack stack, int index, EnumFacing side)
{
return !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canExtractItem(index, stack, side);
}
/**
* Insert the specified stack to the specified inventory and return any leftover items
*/
private static ItemStack insertStack(IInventory source, IInventory destination, ItemStack stack, int index, EnumFacing direction)
{
ItemStack itemstack = destination.getStackInSlot(index);
if (canInsertItemInSlot(destination, stack, index, direction))
{
boolean flag = false;
boolean flag1 = destination.isEmpty();
if (itemstack.isEmpty())
{
destination.setInventorySlotContents(index, stack);
stack = ItemStack.EMPTY;
flag = true;
}
else if (canCombine(itemstack, stack))
{
int i = stack.getMaxStackSize() - itemstack.getCount();
int j = Math.min(stack.getCount(), i);
stack.shrink(j);
itemstack.grow(j);
flag = j > 0;
}
if (flag)
{
if (flag1 && destination instanceof TileEntityHopper)
{
TileEntityHopper tileentityhopper1 = (TileEntityHopper)destination;
if (!tileentityhopper1.mayTransfer())
{
int k = 0;
if (source != null && source instanceof TileEntityHopper)
{
TileEntityHopper tileentityhopper = (TileEntityHopper)source;
if (tileentityhopper1.tickedGameTime >= tileentityhopper.tickedGameTime)
{
k = 1;
}
}
tileentityhopper1.setTransferCooldown(8 - k);
}
}
destination.markDirty();
}
}
return stack;
}
/**
* Returns the IInventory that this hopper is pointing into
*/
private IInventory getInventoryForHopperTransfer()
{
EnumFacing enumfacing = BlockHopper.getFacing(this.getBlockMetadata());
return getInventoryAtPosition(this.getWorld(), this.getXPos() + (double)enumfacing.getFrontOffsetX(), this.getYPos() + (double)enumfacing.getFrontOffsetY(), this.getZPos() + (double)enumfacing.getFrontOffsetZ());
}
/**
* Gets the inventory that the provided hopper will transfer items from.
*/
public static IInventory getSourceInventory(IHopper hopper)
{
return getInventoryAtPosition(hopper.getWorld(), hopper.getXPos(), hopper.getYPos() + 1.0D, hopper.getZPos());
}
public static List<EntityItem> getCaptureItems(World worldIn, double p_184292_1_, double p_184292_3_, double p_184292_5_)
{
return worldIn.<EntityItem>getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(p_184292_1_ - 0.5D, p_184292_3_, p_184292_5_ - 0.5D, p_184292_1_ + 0.5D, p_184292_3_ + 1.5D, p_184292_5_ + 0.5D), EntitySelectors.IS_ALIVE);
}
/**
* Returns the IInventory (if applicable) of the TileEntity at the specified position
*/
public static IInventory getInventoryAtPosition(World worldIn, double x, double y, double z)
{
IInventory iinventory = null;
int i = MathHelper.floor(x);
int j = MathHelper.floor(y);
int k = MathHelper.floor(z);
BlockPos blockpos = new BlockPos(i, j, k);
net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos);
Block block = state.getBlock();
if (block.hasTileEntity(state))
{
TileEntity tileentity = worldIn.getTileEntity(blockpos);
if (tileentity instanceof IInventory)
{
iinventory = (IInventory)tileentity;
if (iinventory instanceof TileEntityChest && block instanceof BlockChest)
{
iinventory = ((BlockChest)block).getContainer(worldIn, blockpos, true);
}
}
}
if (iinventory == null)
{
List<Entity> list = worldIn.getEntitiesInAABBexcluding((Entity)null, new AxisAlignedBB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelectors.HAS_INVENTORY);
if (!list.isEmpty())
{
iinventory = (IInventory)list.get(worldIn.rand.nextInt(list.size()));
}
}
return iinventory;
}
private static boolean canCombine(ItemStack stack1, ItemStack stack2)
{
if (stack1.getItem() != stack2.getItem())
{
return false;
}
else if (stack1.getMetadata() != stack2.getMetadata())
{
return false;
}
else if (stack1.getCount() > stack1.getMaxStackSize())
{
return false;
}
else
{
return ItemStack.areItemStackTagsEqual(stack1, stack2);
}
}
/**
* Gets the world X position for this hopper entity.
*/
public double getXPos()
{
return (double)this.pos.getX() + 0.5D;
}
/**
* Gets the world Y position for this hopper entity.
*/
public double getYPos()
{
return (double)this.pos.getY() + 0.5D;
}
/**
* Gets the world Z position for this hopper entity.
*/
public double getZPos()
{
return (double)this.pos.getZ() + 0.5D;
}
public void setTransferCooldown(int ticks)
{
this.transferCooldown = ticks;
}
private boolean isOnTransferCooldown()
{
return this.transferCooldown > 0;
}
public boolean mayTransfer()
{
return this.transferCooldown > 8;
}
public String getGuiID()
{
return "minecraft:hopper";
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
this.fillWithLoot(playerIn);
return new ContainerHopper(playerInventory, this, playerIn);
}
protected NonNullList<ItemStack> getItems()
{
return this.inventory;
}
public long getLastUpdateTime() { return tickedGameTime; } // Forge
}

View File

@@ -0,0 +1,77 @@
package net.minecraft.tileentity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.ILockableContainer;
import net.minecraft.world.LockCode;
public abstract class TileEntityLockable extends TileEntity implements ILockableContainer
{
private LockCode code = LockCode.EMPTY_CODE;
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.code = LockCode.fromNBT(compound);
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
if (this.code != null)
{
this.code.toNBT(compound);
}
return compound;
}
public boolean isLocked()
{
return this.code != null && !this.code.isEmpty();
}
public LockCode getLockCode()
{
return this.code;
}
public void setLockCode(LockCode code)
{
this.code = code;
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
public ITextComponent getDisplayName()
{
return (ITextComponent)(this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName(), new Object[0]));
}
private net.minecraftforge.items.IItemHandler itemHandler;
protected net.minecraftforge.items.IItemHandler createUnSidedHandler()
{
return new net.minecraftforge.items.wrapper.InvWrapper(this);
}
@SuppressWarnings("unchecked")
@Override
@javax.annotation.Nullable
public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing)
{
if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return (T) (itemHandler == null ? (itemHandler = createUnSidedHandler()) : itemHandler);
return super.getCapability(capability, facing);
}
@Override
public boolean hasCapability(net.minecraftforge.common.capabilities.Capability<?> capability, @javax.annotation.Nullable net.minecraft.util.EnumFacing facing)
{
return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
}
}

View File

@@ -0,0 +1,210 @@
package net.minecraft.tileentity;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.WorldServer;
import net.minecraft.world.storage.loot.ILootContainer;
import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.world.storage.loot.LootTable;
public abstract class TileEntityLockableLoot extends TileEntityLockable implements ILootContainer
{
protected ResourceLocation lootTable;
protected long lootTableSeed;
protected String customName;
protected boolean checkLootAndRead(NBTTagCompound compound)
{
if (compound.hasKey("LootTable", 8))
{
this.lootTable = new ResourceLocation(compound.getString("LootTable"));
this.lootTableSeed = compound.getLong("LootTableSeed");
return true;
}
else
{
return false;
}
}
protected boolean checkLootAndWrite(NBTTagCompound compound)
{
if (this.lootTable != null)
{
compound.setString("LootTable", this.lootTable.toString());
if (this.lootTableSeed != 0L)
{
compound.setLong("LootTableSeed", this.lootTableSeed);
}
return true;
}
else
{
return false;
}
}
public void fillWithLoot(@Nullable EntityPlayer player)
{
if (this.lootTable != null)
{
LootTable loottable = this.world.getLootTableManager().getLootTableFromLocation(this.lootTable);
this.lootTable = null;
Random random;
if (this.lootTableSeed == 0L)
{
random = new Random();
}
else
{
random = new Random(this.lootTableSeed);
}
LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.world);
if (player != null)
{
lootcontext$builder.withLuck(player.getLuck()).withPlayer(player); // Forge: add player to LootContext
}
loottable.fillInventory(this, random, lootcontext$builder.build());
}
}
public ResourceLocation getLootTable()
{
return this.lootTable;
}
public void setLootTable(ResourceLocation p_189404_1_, long p_189404_2_)
{
this.lootTable = p_189404_1_;
this.lootTableSeed = p_189404_2_;
}
/**
* Returns true if this thing is named
*/
public boolean hasCustomName()
{
return this.customName != null && !this.customName.isEmpty();
}
public void setCustomName(String p_190575_1_)
{
this.customName = p_190575_1_;
}
/**
* Returns the stack in the given slot.
*/
public ItemStack getStackInSlot(int index)
{
this.fillWithLoot((EntityPlayer)null);
return (ItemStack)this.getItems().get(index);
}
/**
* Removes up to a specified number of items from an inventory slot and returns them in a new stack.
*/
public ItemStack decrStackSize(int index, int count)
{
this.fillWithLoot((EntityPlayer)null);
ItemStack itemstack = ItemStackHelper.getAndSplit(this.getItems(), index, count);
if (!itemstack.isEmpty())
{
this.markDirty();
}
return itemstack;
}
/**
* Removes a stack from the given slot and returns it.
*/
public ItemStack removeStackFromSlot(int index)
{
this.fillWithLoot((EntityPlayer)null);
return ItemStackHelper.getAndRemove(this.getItems(), index);
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int index, @Nullable ItemStack stack)
{
this.fillWithLoot((EntityPlayer)null);
this.getItems().set(index, stack);
if (stack.getCount() > this.getInventoryStackLimit())
{
stack.setCount(this.getInventoryStackLimit());
}
this.markDirty();
}
/**
* Don't rename this method to canInteractWith due to conflicts with Container
*/
public boolean isUsableByPlayer(EntityPlayer player)
{
if (this.world.getTileEntity(this.pos) != this)
{
return false;
}
else
{
return player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D;
}
}
public void openInventory(EntityPlayer player)
{
}
public void closeInventory(EntityPlayer player)
{
}
/**
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. For
* guis use Slot.isItemValid
*/
public boolean isItemValidForSlot(int index, ItemStack stack)
{
return true;
}
public int getField(int id)
{
return 0;
}
public void setField(int id, int value)
{
}
public int getFieldCount()
{
return 0;
}
public void clear()
{
this.fillWithLoot((EntityPlayer)null);
this.getItems().clear();
}
protected abstract NonNullList<ItemStack> getItems();
}

View File

@@ -0,0 +1,122 @@
package net.minecraft.tileentity;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.WeightedSpawnerEntity;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.IDataFixer;
import net.minecraft.util.datafix.IDataWalker;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class TileEntityMobSpawner extends TileEntity implements ITickable
{
private final MobSpawnerBaseLogic spawnerLogic = new MobSpawnerBaseLogic()
{
public void broadcastEvent(int id)
{
TileEntityMobSpawner.this.world.addBlockEvent(TileEntityMobSpawner.this.pos, Blocks.MOB_SPAWNER, id, 0);
}
public World getSpawnerWorld()
{
return TileEntityMobSpawner.this.world;
}
public BlockPos getSpawnerPosition()
{
return TileEntityMobSpawner.this.pos;
}
public void setNextSpawnData(WeightedSpawnerEntity p_184993_1_)
{
super.setNextSpawnData(p_184993_1_);
if (this.getSpawnerWorld() != null)
{
IBlockState iblockstate = this.getSpawnerWorld().getBlockState(this.getSpawnerPosition());
this.getSpawnerWorld().notifyBlockUpdate(TileEntityMobSpawner.this.pos, iblockstate, iblockstate, 4);
}
}
};
public static void registerFixesMobSpawner(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new IDataWalker()
{
public NBTTagCompound process(IDataFixer fixer, NBTTagCompound compound, int versionIn)
{
if (TileEntity.getKey(TileEntityMobSpawner.class).equals(new ResourceLocation(compound.getString("id"))))
{
if (compound.hasKey("SpawnPotentials", 9))
{
NBTTagList nbttaglist = compound.getTagList("SpawnPotentials", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
nbttagcompound.setTag("Entity", fixer.process(FixTypes.ENTITY, nbttagcompound.getCompoundTag("Entity"), versionIn));
}
}
compound.setTag("SpawnData", fixer.process(FixTypes.ENTITY, compound.getCompoundTag("SpawnData"), versionIn));
}
return compound;
}
});
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.spawnerLogic.readFromNBT(compound);
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
this.spawnerLogic.writeToNBT(compound);
return compound;
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
this.spawnerLogic.updateSpawner();
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 1, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
NBTTagCompound nbttagcompound = this.writeToNBT(new NBTTagCompound());
nbttagcompound.removeTag("SpawnPotentials");
return nbttagcompound;
}
public boolean receiveClientEvent(int id, int type)
{
return this.spawnerLogic.setDelayToMin(id) ? true : super.receiveClientEvent(id, type);
}
public boolean onlyOpsCanSetNbt()
{
return true;
}
public MobSpawnerBaseLogic getSpawnerBaseLogic()
{
return this.spawnerLogic;
}
}

View File

@@ -0,0 +1,104 @@
package net.minecraft.tileentity;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public class TileEntityNote extends TileEntity
{
/** Note to play */
public byte note;
/** stores the latest redstone state */
public boolean previousRedstoneState;
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setByte("note", this.note);
compound.setBoolean("powered", this.previousRedstoneState);
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.note = compound.getByte("note");
this.note = (byte)MathHelper.clamp(this.note, 0, 24);
this.previousRedstoneState = compound.getBoolean("powered");
}
/**
* change pitch by -> (currentPitch + 1) % 25
*/
public void changePitch()
{
byte old = note;
this.note = (byte)((this.note + 1) % 25);
if (!net.minecraftforge.common.ForgeHooks.onNoteChange(this, old)) return;
this.markDirty();
}
public void triggerNote(World worldIn, BlockPos posIn)
{
if (worldIn.getBlockState(posIn.up()).getMaterial() == Material.AIR)
{
IBlockState iblockstate = worldIn.getBlockState(posIn.down());
Material material = iblockstate.getMaterial();
int i = 0;
if (material == Material.ROCK)
{
i = 1;
}
if (material == Material.SAND)
{
i = 2;
}
if (material == Material.GLASS)
{
i = 3;
}
if (material == Material.WOOD)
{
i = 4;
}
Block block = iblockstate.getBlock();
if (block == Blocks.CLAY)
{
i = 5;
}
if (block == Blocks.GOLD_BLOCK)
{
i = 6;
}
if (block == Blocks.WOOL)
{
i = 7;
}
if (block == Blocks.PACKED_ICE)
{
i = 8;
}
if (block == Blocks.BONE_BLOCK)
{
i = 9;
}
worldIn.addBlockEvent(posIn, Blocks.NOTEBLOCK, i, this.note);
}
}
}

View File

@@ -0,0 +1,431 @@
package net.minecraft.tileentity;
import com.google.common.collect.Lists;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockPistonBase;
import net.minecraft.block.BlockPistonExtension;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.MoverType;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityPiston extends TileEntity implements ITickable
{
private IBlockState pistonState;
private EnumFacing pistonFacing;
/** if this piston is extending or not */
private boolean extending;
private boolean shouldHeadBeRendered;
private static final ThreadLocal<EnumFacing> MOVING_ENTITY = new ThreadLocal<EnumFacing>()
{
protected EnumFacing initialValue()
{
return null;
}
};
private float progress;
/** the progress in (de)extending */
private float lastProgress;
public TileEntityPiston()
{
}
public TileEntityPiston(IBlockState pistonStateIn, EnumFacing pistonFacingIn, boolean extendingIn, boolean shouldHeadBeRenderedIn)
{
this.pistonState = pistonStateIn;
this.pistonFacing = pistonFacingIn;
this.extending = extendingIn;
this.shouldHeadBeRendered = shouldHeadBeRenderedIn;
}
public IBlockState getPistonState()
{
return this.pistonState;
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public int getBlockMetadata()
{
return 0;
}
/**
* Returns true if a piston is extending
*/
public boolean isExtending()
{
return this.extending;
}
public EnumFacing getFacing()
{
return this.pistonFacing;
}
public boolean shouldPistonHeadBeRendered()
{
return this.shouldHeadBeRendered;
}
/**
* Get interpolated progress value (between lastProgress and progress) given the fractional time between ticks as an
* argument
*/
@SideOnly(Side.CLIENT)
public float getProgress(float ticks)
{
if (ticks > 1.0F)
{
ticks = 1.0F;
}
return this.lastProgress + (this.progress - this.lastProgress) * ticks;
}
@SideOnly(Side.CLIENT)
public float getOffsetX(float ticks)
{
return (float)this.pistonFacing.getFrontOffsetX() * this.getExtendedProgress(this.getProgress(ticks));
}
@SideOnly(Side.CLIENT)
public float getOffsetY(float ticks)
{
return (float)this.pistonFacing.getFrontOffsetY() * this.getExtendedProgress(this.getProgress(ticks));
}
@SideOnly(Side.CLIENT)
public float getOffsetZ(float ticks)
{
return (float)this.pistonFacing.getFrontOffsetZ() * this.getExtendedProgress(this.getProgress(ticks));
}
private float getExtendedProgress(float p_184320_1_)
{
return this.extending ? p_184320_1_ - 1.0F : 1.0F - p_184320_1_;
}
public AxisAlignedBB getAABB(IBlockAccess p_184321_1_, BlockPos p_184321_2_)
{
return this.getAABB(p_184321_1_, p_184321_2_, this.progress).union(this.getAABB(p_184321_1_, p_184321_2_, this.lastProgress));
}
public AxisAlignedBB getAABB(IBlockAccess p_184319_1_, BlockPos p_184319_2_, float p_184319_3_)
{
p_184319_3_ = this.getExtendedProgress(p_184319_3_);
IBlockState iblockstate = this.getCollisionRelatedBlockState();
return iblockstate.getBoundingBox(p_184319_1_, p_184319_2_).offset((double)(p_184319_3_ * (float)this.pistonFacing.getFrontOffsetX()), (double)(p_184319_3_ * (float)this.pistonFacing.getFrontOffsetY()), (double)(p_184319_3_ * (float)this.pistonFacing.getFrontOffsetZ()));
}
private IBlockState getCollisionRelatedBlockState()
{
return !this.isExtending() && this.shouldPistonHeadBeRendered() ? Blocks.PISTON_HEAD.getDefaultState().withProperty(BlockPistonExtension.TYPE, this.pistonState.getBlock() == Blocks.STICKY_PISTON ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT).withProperty(BlockPistonExtension.FACING, this.pistonState.getValue(BlockPistonBase.FACING)) : this.pistonState;
}
private void moveCollidedEntities(float p_184322_1_)
{
EnumFacing enumfacing = this.extending ? this.pistonFacing : this.pistonFacing.getOpposite();
double d0 = (double)(p_184322_1_ - this.progress);
List<AxisAlignedBB> list = Lists.<AxisAlignedBB>newArrayList();
this.getCollisionRelatedBlockState().addCollisionBoxToList(this.world, BlockPos.ORIGIN, new AxisAlignedBB(BlockPos.ORIGIN), list, (Entity)null, true);
if (!list.isEmpty())
{
AxisAlignedBB axisalignedbb = this.moveByPositionAndProgress(this.getMinMaxPiecesAABB(list));
List<Entity> list1 = this.world.getEntitiesWithinAABBExcludingEntity((Entity)null, this.getMovementArea(axisalignedbb, enumfacing, d0).union(axisalignedbb));
if (!list1.isEmpty())
{
boolean flag = this.pistonState.getBlock().isStickyBlock(this.pistonState);
for (int i = 0; i < list1.size(); ++i)
{
Entity entity = list1.get(i);
if (entity.getPushReaction() != EnumPushReaction.IGNORE)
{
if (flag)
{
switch (enumfacing.getAxis())
{
case X:
entity.motionX = (double)enumfacing.getFrontOffsetX();
break;
case Y:
entity.motionY = (double)enumfacing.getFrontOffsetY();
break;
case Z:
entity.motionZ = (double)enumfacing.getFrontOffsetZ();
}
}
double d1 = 0.0D;
for (int j = 0; j < list.size(); ++j)
{
AxisAlignedBB axisalignedbb1 = this.getMovementArea(this.moveByPositionAndProgress(list.get(j)), enumfacing, d0);
AxisAlignedBB axisalignedbb2 = entity.getEntityBoundingBox();
if (axisalignedbb1.intersects(axisalignedbb2))
{
d1 = Math.max(d1, this.getMovement(axisalignedbb1, enumfacing, axisalignedbb2));
if (d1 >= d0)
{
break;
}
}
}
if (d1 > 0.0D)
{
d1 = Math.min(d1, d0) + 0.01D;
MOVING_ENTITY.set(enumfacing);
entity.move(MoverType.PISTON, d1 * (double)enumfacing.getFrontOffsetX(), d1 * (double)enumfacing.getFrontOffsetY(), d1 * (double)enumfacing.getFrontOffsetZ());
MOVING_ENTITY.set(null);
if (!this.extending && this.shouldHeadBeRendered)
{
this.fixEntityWithinPistonBase(entity, enumfacing, d0);
}
}
}
}
}
}
}
private AxisAlignedBB getMinMaxPiecesAABB(List<AxisAlignedBB> p_191515_1_)
{
double d0 = 0.0D;
double d1 = 0.0D;
double d2 = 0.0D;
double d3 = 1.0D;
double d4 = 1.0D;
double d5 = 1.0D;
for (AxisAlignedBB axisalignedbb : p_191515_1_)
{
d0 = Math.min(axisalignedbb.minX, d0);
d1 = Math.min(axisalignedbb.minY, d1);
d2 = Math.min(axisalignedbb.minZ, d2);
d3 = Math.max(axisalignedbb.maxX, d3);
d4 = Math.max(axisalignedbb.maxY, d4);
d5 = Math.max(axisalignedbb.maxZ, d5);
}
return new AxisAlignedBB(d0, d1, d2, d3, d4, d5);
}
private double getMovement(AxisAlignedBB p_190612_1_, EnumFacing facing, AxisAlignedBB p_190612_3_)
{
switch (facing.getAxis())
{
case X:
return getDeltaX(p_190612_1_, facing, p_190612_3_);
case Y:
default:
return getDeltaY(p_190612_1_, facing, p_190612_3_);
case Z:
return getDeltaZ(p_190612_1_, facing, p_190612_3_);
}
}
private AxisAlignedBB moveByPositionAndProgress(AxisAlignedBB p_190607_1_)
{
double d0 = (double)this.getExtendedProgress(this.progress);
return p_190607_1_.offset((double)this.pos.getX() + d0 * (double)this.pistonFacing.getFrontOffsetX(), (double)this.pos.getY() + d0 * (double)this.pistonFacing.getFrontOffsetY(), (double)this.pos.getZ() + d0 * (double)this.pistonFacing.getFrontOffsetZ());
}
private AxisAlignedBB getMovementArea(AxisAlignedBB p_190610_1_, EnumFacing p_190610_2_, double p_190610_3_)
{
double d0 = p_190610_3_ * (double)p_190610_2_.getAxisDirection().getOffset();
double d1 = Math.min(d0, 0.0D);
double d2 = Math.max(d0, 0.0D);
switch (p_190610_2_)
{
case WEST:
return new AxisAlignedBB(p_190610_1_.minX + d1, p_190610_1_.minY, p_190610_1_.minZ, p_190610_1_.minX + d2, p_190610_1_.maxY, p_190610_1_.maxZ);
case EAST:
return new AxisAlignedBB(p_190610_1_.maxX + d1, p_190610_1_.minY, p_190610_1_.minZ, p_190610_1_.maxX + d2, p_190610_1_.maxY, p_190610_1_.maxZ);
case DOWN:
return new AxisAlignedBB(p_190610_1_.minX, p_190610_1_.minY + d1, p_190610_1_.minZ, p_190610_1_.maxX, p_190610_1_.minY + d2, p_190610_1_.maxZ);
case UP:
default:
return new AxisAlignedBB(p_190610_1_.minX, p_190610_1_.maxY + d1, p_190610_1_.minZ, p_190610_1_.maxX, p_190610_1_.maxY + d2, p_190610_1_.maxZ);
case NORTH:
return new AxisAlignedBB(p_190610_1_.minX, p_190610_1_.minY, p_190610_1_.minZ + d1, p_190610_1_.maxX, p_190610_1_.maxY, p_190610_1_.minZ + d2);
case SOUTH:
return new AxisAlignedBB(p_190610_1_.minX, p_190610_1_.minY, p_190610_1_.maxZ + d1, p_190610_1_.maxX, p_190610_1_.maxY, p_190610_1_.maxZ + d2);
}
}
private void fixEntityWithinPistonBase(Entity p_190605_1_, EnumFacing p_190605_2_, double p_190605_3_)
{
AxisAlignedBB axisalignedbb = p_190605_1_.getEntityBoundingBox();
AxisAlignedBB axisalignedbb1 = Block.FULL_BLOCK_AABB.offset(this.pos);
if (axisalignedbb.intersects(axisalignedbb1))
{
EnumFacing enumfacing = p_190605_2_.getOpposite();
double d0 = this.getMovement(axisalignedbb1, enumfacing, axisalignedbb) + 0.01D;
double d1 = this.getMovement(axisalignedbb1, enumfacing, axisalignedbb.intersect(axisalignedbb1)) + 0.01D;
if (Math.abs(d0 - d1) < 0.01D)
{
d0 = Math.min(d0, p_190605_3_) + 0.01D;
MOVING_ENTITY.set(p_190605_2_);
p_190605_1_.move(MoverType.PISTON, d0 * (double)enumfacing.getFrontOffsetX(), d0 * (double)enumfacing.getFrontOffsetY(), d0 * (double)enumfacing.getFrontOffsetZ());
MOVING_ENTITY.set(null);
}
}
}
private static double getDeltaX(AxisAlignedBB p_190611_0_, EnumFacing facing, AxisAlignedBB p_190611_2_)
{
return facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? p_190611_0_.maxX - p_190611_2_.minX : p_190611_2_.maxX - p_190611_0_.minX;
}
private static double getDeltaY(AxisAlignedBB p_190608_0_, EnumFacing facing, AxisAlignedBB p_190608_2_)
{
return facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? p_190608_0_.maxY - p_190608_2_.minY : p_190608_2_.maxY - p_190608_0_.minY;
}
private static double getDeltaZ(AxisAlignedBB p_190604_0_, EnumFacing facing, AxisAlignedBB p_190604_2_)
{
return facing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? p_190604_0_.maxZ - p_190604_2_.minZ : p_190604_2_.maxZ - p_190604_0_.minZ;
}
/**
* removes a piston's tile entity (and if the piston is moving, stops it)
*/
public void clearPistonTileEntity()
{
if (this.lastProgress < 1.0F && this.world != null)
{
this.progress = 1.0F;
this.lastProgress = this.progress;
this.world.removeTileEntity(this.pos);
this.invalidate();
if (this.world.getBlockState(this.pos).getBlock() == Blocks.PISTON_EXTENSION)
{
this.world.setBlockState(this.pos, this.pistonState, 3);
this.world.neighborChanged(this.pos, this.pistonState.getBlock(), this.pos);
}
}
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
this.lastProgress = this.progress;
if (this.lastProgress >= 1.0F)
{
this.world.removeTileEntity(this.pos);
this.invalidate();
if (this.world.getBlockState(this.pos).getBlock() == Blocks.PISTON_EXTENSION)
{
this.world.setBlockState(this.pos, this.pistonState, 3);
this.world.neighborChanged(this.pos, this.pistonState.getBlock(), this.pos);
}
}
else
{
float f = this.progress + 0.5F;
this.moveCollidedEntities(f);
this.progress = f;
if (this.progress >= 1.0F)
{
this.progress = 1.0F;
}
}
}
public static void registerFixesPiston(DataFixer fixer)
{
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.pistonState = Block.getBlockById(compound.getInteger("blockId")).getStateFromMeta(compound.getInteger("blockData"));
this.pistonFacing = EnumFacing.getFront(compound.getInteger("facing"));
this.progress = compound.getFloat("progress");
this.lastProgress = this.progress;
this.extending = compound.getBoolean("extending");
this.shouldHeadBeRendered = compound.getBoolean("source");
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setInteger("blockId", Block.getIdFromBlock(this.pistonState.getBlock()));
compound.setInteger("blockData", this.pistonState.getBlock().getMetaFromState(this.pistonState));
compound.setInteger("facing", this.pistonFacing.getIndex());
compound.setFloat("progress", this.lastProgress);
compound.setBoolean("extending", this.extending);
compound.setBoolean("source", this.shouldHeadBeRendered);
return compound;
}
public void addCollissionAABBs(World p_190609_1_, BlockPos p_190609_2_, AxisAlignedBB p_190609_3_, List<AxisAlignedBB> p_190609_4_, @Nullable Entity p_190609_5_)
{
if (!this.extending && this.shouldHeadBeRendered)
{
this.pistonState.withProperty(BlockPistonBase.EXTENDED, Boolean.valueOf(true)).addCollisionBoxToList(p_190609_1_, p_190609_2_, p_190609_3_, p_190609_4_, p_190609_5_, false);
}
EnumFacing enumfacing = MOVING_ENTITY.get();
if ((double)this.progress >= 1.0D || enumfacing != (this.extending ? this.pistonFacing : this.pistonFacing.getOpposite()))
{
int i = p_190609_4_.size();
IBlockState iblockstate;
if (this.shouldPistonHeadBeRendered())
{
iblockstate = Blocks.PISTON_HEAD.getDefaultState().withProperty(BlockPistonExtension.FACING, this.pistonFacing).withProperty(BlockPistonExtension.SHORT, Boolean.valueOf(this.extending != 1.0F - this.progress < 0.25F));
}
else
{
iblockstate = this.pistonState;
}
float f = this.getExtendedProgress(this.progress);
double d0 = (double)((float)this.pistonFacing.getFrontOffsetX() * f);
double d1 = (double)((float)this.pistonFacing.getFrontOffsetY() * f);
double d2 = (double)((float)this.pistonFacing.getFrontOffsetZ() * f);
iblockstate.addCollisionBoxToList(p_190609_1_, p_190609_2_, p_190609_3_.offset(-d0, -d1, -d2), p_190609_4_, p_190609_5_, true);
for (int j = i; j < p_190609_4_.size(); ++j)
{
p_190609_4_.set(j, ((AxisAlignedBB)p_190609_4_.get(j)).offset(d0, d1, d2));
}
}
}
}

View File

@@ -0,0 +1,448 @@
package net.minecraft.tileentity;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockShulkerBox;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerShulkerBox;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.walkers.ItemStackDataLists;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityShulkerBox extends TileEntityLockableLoot implements ITickable, ISidedInventory
{
private static final int[] SLOTS = new int[27];
private NonNullList<ItemStack> items;
private boolean hasBeenCleared;
private int openCount;
private TileEntityShulkerBox.AnimationStatus animationStatus;
private float progress;
private float progressOld;
private EnumDyeColor color;
private boolean destroyedByCreativePlayer;
public TileEntityShulkerBox()
{
this((EnumDyeColor)null);
}
public TileEntityShulkerBox(@Nullable EnumDyeColor colorIn)
{
this.items = NonNullList.<ItemStack>withSize(27, ItemStack.EMPTY);
this.animationStatus = TileEntityShulkerBox.AnimationStatus.CLOSED;
this.color = colorIn;
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
this.updateAnimation();
if (this.animationStatus == TileEntityShulkerBox.AnimationStatus.OPENING || this.animationStatus == TileEntityShulkerBox.AnimationStatus.CLOSING)
{
this.moveCollidedEntities();
}
}
protected void updateAnimation()
{
this.progressOld = this.progress;
switch (this.animationStatus)
{
case CLOSED:
this.progress = 0.0F;
break;
case OPENING:
this.progress += 0.1F;
if (this.progress >= 1.0F)
{
this.moveCollidedEntities();
this.animationStatus = TileEntityShulkerBox.AnimationStatus.OPENED;
this.progress = 1.0F;
}
break;
case CLOSING:
this.progress -= 0.1F;
if (this.progress <= 0.0F)
{
this.animationStatus = TileEntityShulkerBox.AnimationStatus.CLOSED;
this.progress = 0.0F;
}
break;
case OPENED:
this.progress = 1.0F;
}
}
public TileEntityShulkerBox.AnimationStatus getAnimationStatus()
{
return this.animationStatus;
}
public AxisAlignedBB getBoundingBox(IBlockState p_190584_1_)
{
return this.getBoundingBox((EnumFacing)p_190584_1_.getValue(BlockShulkerBox.FACING));
}
public AxisAlignedBB getBoundingBox(EnumFacing p_190587_1_)
{
return Block.FULL_BLOCK_AABB.expand((double)(0.5F * this.getProgress(1.0F) * (float)p_190587_1_.getFrontOffsetX()), (double)(0.5F * this.getProgress(1.0F) * (float)p_190587_1_.getFrontOffsetY()), (double)(0.5F * this.getProgress(1.0F) * (float)p_190587_1_.getFrontOffsetZ()));
}
private AxisAlignedBB getTopBoundingBox(EnumFacing p_190588_1_)
{
EnumFacing enumfacing = p_190588_1_.getOpposite();
return this.getBoundingBox(p_190588_1_).contract((double)enumfacing.getFrontOffsetX(), (double)enumfacing.getFrontOffsetY(), (double)enumfacing.getFrontOffsetZ());
}
private void moveCollidedEntities()
{
IBlockState iblockstate = this.world.getBlockState(this.getPos());
if (iblockstate.getBlock() instanceof BlockShulkerBox)
{
EnumFacing enumfacing = (EnumFacing)iblockstate.getValue(BlockShulkerBox.FACING);
AxisAlignedBB axisalignedbb = this.getTopBoundingBox(enumfacing).offset(this.pos);
List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity((Entity)null, axisalignedbb);
if (!list.isEmpty())
{
for (int i = 0; i < list.size(); ++i)
{
Entity entity = list.get(i);
if (entity.getPushReaction() != EnumPushReaction.IGNORE)
{
double d0 = 0.0D;
double d1 = 0.0D;
double d2 = 0.0D;
AxisAlignedBB axisalignedbb1 = entity.getEntityBoundingBox();
switch (enumfacing.getAxis())
{
case X:
if (enumfacing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE)
{
d0 = axisalignedbb.maxX - axisalignedbb1.minX;
}
else
{
d0 = axisalignedbb1.maxX - axisalignedbb.minX;
}
d0 = d0 + 0.01D;
break;
case Y:
if (enumfacing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE)
{
d1 = axisalignedbb.maxY - axisalignedbb1.minY;
}
else
{
d1 = axisalignedbb1.maxY - axisalignedbb.minY;
}
d1 = d1 + 0.01D;
break;
case Z:
if (enumfacing.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE)
{
d2 = axisalignedbb.maxZ - axisalignedbb1.minZ;
}
else
{
d2 = axisalignedbb1.maxZ - axisalignedbb.minZ;
}
d2 = d2 + 0.01D;
}
entity.move(MoverType.SHULKER_BOX, d0 * (double)enumfacing.getFrontOffsetX(), d1 * (double)enumfacing.getFrontOffsetY(), d2 * (double)enumfacing.getFrontOffsetZ());
}
}
}
}
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return this.items.size();
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
*/
public int getInventoryStackLimit()
{
return 64;
}
public boolean receiveClientEvent(int id, int type)
{
if (id == 1)
{
this.openCount = type;
if (type == 0)
{
this.animationStatus = TileEntityShulkerBox.AnimationStatus.CLOSING;
}
if (type == 1)
{
this.animationStatus = TileEntityShulkerBox.AnimationStatus.OPENING;
}
return true;
}
else
{
return super.receiveClientEvent(id, type);
}
}
public void openInventory(EntityPlayer player)
{
if (!player.isSpectator())
{
if (this.openCount < 0)
{
this.openCount = 0;
}
++this.openCount;
this.world.addBlockEvent(this.pos, this.getBlockType(), 1, this.openCount);
if (this.openCount == 1)
{
this.world.playSound((EntityPlayer)null, this.pos, SoundEvents.BLOCK_SHULKER_BOX_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
}
}
}
public void closeInventory(EntityPlayer player)
{
if (!player.isSpectator())
{
--this.openCount;
this.world.addBlockEvent(this.pos, this.getBlockType(), 1, this.openCount);
if (this.openCount <= 0)
{
this.world.playSound((EntityPlayer)null, this.pos, SoundEvents.BLOCK_SHULKER_BOX_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.rand.nextFloat() * 0.1F + 0.9F);
}
}
}
public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn)
{
return new ContainerShulkerBox(playerInventory, this, playerIn);
}
public String getGuiID()
{
return "minecraft:shulker_box";
}
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return this.hasCustomName() ? this.customName : "container.shulkerBox";
}
public static void registerFixesShulkerBox(DataFixer fixer)
{
fixer.registerWalker(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityShulkerBox.class, new String[] {"Items"}));
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.loadFromNbt(compound);
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
return this.saveToNbt(compound);
}
public void loadFromNbt(NBTTagCompound compound)
{
this.items = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (!this.checkLootAndRead(compound) && compound.hasKey("Items", 9))
{
ItemStackHelper.loadAllItems(compound, this.items);
}
if (compound.hasKey("CustomName", 8))
{
this.customName = compound.getString("CustomName");
}
}
public NBTTagCompound saveToNbt(NBTTagCompound compound)
{
if (!this.checkLootAndWrite(compound))
{
ItemStackHelper.saveAllItems(compound, this.items, false);
}
if (this.hasCustomName())
{
compound.setString("CustomName", this.customName);
}
if (!compound.hasKey("Lock") && this.isLocked())
{
this.getLockCode().toNBT(compound);
}
return compound;
}
protected NonNullList<ItemStack> getItems()
{
return this.items;
}
public boolean isEmpty()
{
for (ItemStack itemstack : this.items)
{
if (!itemstack.isEmpty())
{
return false;
}
}
return true;
}
public int[] getSlotsForFace(EnumFacing side)
{
return SLOTS;
}
/**
* Returns true if automation can insert the given item in the given slot from the given side.
*/
public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction)
{
return !(Block.getBlockFromItem(itemStackIn.getItem()) instanceof BlockShulkerBox);
}
/**
* Returns true if automation can extract the given item in the given slot from the given side.
*/
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{
return true;
}
public void clear()
{
this.hasBeenCleared = true;
super.clear();
}
public boolean isCleared()
{
return this.hasBeenCleared;
}
public float getProgress(float p_190585_1_)
{
return this.progressOld + (this.progress - this.progressOld) * p_190585_1_;
}
@SideOnly(Side.CLIENT)
public EnumDyeColor getColor()
{
if (this.color == null)
{
this.color = BlockShulkerBox.getColorFromBlock(this.getBlockType());
}
return this.color;
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 10, this.getUpdateTag());
}
public boolean isDestroyedByCreativePlayer()
{
return this.destroyedByCreativePlayer;
}
public void setDestroyedByCreativePlayer(boolean p_190579_1_)
{
this.destroyedByCreativePlayer = p_190579_1_;
}
public boolean shouldDrop()
{
return !this.isDestroyedByCreativePlayer() || !this.isEmpty() || this.hasCustomName() || this.lootTable != null;
}
static
{
for (int i = 0; i < SLOTS.length; SLOTS[i] = i++)
{
;
}
}
public static enum AnimationStatus
{
CLOSED,
OPENING,
OPENED,
CLOSING;
}
protected net.minecraftforge.items.IItemHandler createUnSidedHandler()
{
return new net.minecraftforge.items.wrapper.SidedInvWrapper(this, EnumFacing.UP);
}
}

View File

@@ -0,0 +1,277 @@
package net.minecraft.tileentity;
import javax.annotation.Nullable;
import net.minecraft.command.CommandException;
import net.minecraft.command.CommandResultStats;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.Style;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentUtils;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntitySign extends TileEntity
{
public final ITextComponent[] signText = new ITextComponent[] {new TextComponentString(""), new TextComponentString(""), new TextComponentString(""), new TextComponentString("")};
/**
* The index of the line currently being edited. Only used on client side, but defined on both. Note this is only
* really used when the > < are going to be visible.
*/
public int lineBeingEdited = -1;
private boolean isEditable = true;
private EntityPlayer player;
private final CommandResultStats stats = new CommandResultStats();
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
for (int i = 0; i < 4; ++i)
{
String s = ITextComponent.Serializer.componentToJson(this.signText[i]);
compound.setString("Text" + (i + 1), s);
}
this.stats.writeStatsToNBT(compound);
return compound;
}
protected void setWorldCreate(World worldIn)
{
this.setWorld(worldIn);
}
public void readFromNBT(NBTTagCompound compound)
{
this.isEditable = false;
super.readFromNBT(compound);
ICommandSender icommandsender = new ICommandSender()
{
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return "Sign";
}
/**
* Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not
*/
public boolean canUseCommand(int permLevel, String commandName)
{
return permLevel <= 2; //Forge: Fixes MC-75630 - Exploit with signs and command blocks
}
/**
* Get the position in the world. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return the coordinates 0, 0, 0
*/
public BlockPos getPosition()
{
return TileEntitySign.this.pos;
}
/**
* Get the position vector. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return 0.0D, 0.0D, 0.0D
*/
public Vec3d getPositionVector()
{
return new Vec3d((double)TileEntitySign.this.pos.getX() + 0.5D, (double)TileEntitySign.this.pos.getY() + 0.5D, (double)TileEntitySign.this.pos.getZ() + 0.5D);
}
/**
* Get the world, if available. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return the overworld
*/
public World getEntityWorld()
{
return TileEntitySign.this.world;
}
/**
* Get the Minecraft server instance
*/
public MinecraftServer getServer()
{
return TileEntitySign.this.world.getMinecraftServer();
}
};
for (int i = 0; i < 4; ++i)
{
String s = compound.getString("Text" + (i + 1));
ITextComponent itextcomponent = ITextComponent.Serializer.jsonToComponent(s);
try
{
this.signText[i] = TextComponentUtils.processComponent(icommandsender, itextcomponent, (Entity)null);
}
catch (CommandException var7)
{
this.signText[i] = itextcomponent;
}
}
this.stats.readStatsFromNBT(compound);
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 9, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public boolean onlyOpsCanSetNbt()
{
return true;
}
public boolean getIsEditable()
{
return this.isEditable;
}
/**
* Sets the sign's isEditable flag to the specified parameter.
*/
@SideOnly(Side.CLIENT)
public void setEditable(boolean isEditableIn)
{
this.isEditable = isEditableIn;
if (!isEditableIn)
{
this.player = null;
}
}
public void setPlayer(EntityPlayer playerIn)
{
this.player = playerIn;
}
public EntityPlayer getPlayer()
{
return this.player;
}
public boolean executeCommand(final EntityPlayer playerIn)
{
ICommandSender icommandsender = new ICommandSender()
{
/**
* Get the name of this object. For players this returns their username
*/
public String getName()
{
return playerIn.getName();
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
public ITextComponent getDisplayName()
{
return playerIn.getDisplayName();
}
/**
* Send a chat message to the CommandSender
*/
public void sendMessage(ITextComponent component)
{
}
/**
* Returns {@code true} if the CommandSender is allowed to execute the command, {@code false} if not
*/
public boolean canUseCommand(int permLevel, String commandName)
{
return permLevel <= 2;
}
/**
* Get the position in the world. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return the coordinates 0, 0, 0
*/
public BlockPos getPosition()
{
return TileEntitySign.this.pos;
}
/**
* Get the position vector. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return 0.0D, 0.0D, 0.0D
*/
public Vec3d getPositionVector()
{
return new Vec3d((double)TileEntitySign.this.pos.getX() + 0.5D, (double)TileEntitySign.this.pos.getY() + 0.5D, (double)TileEntitySign.this.pos.getZ() + 0.5D);
}
/**
* Get the world, if available. <b>{@code null} is not allowed!</b> If you are not an entity in the world,
* return the overworld
*/
public World getEntityWorld()
{
return playerIn.getEntityWorld();
}
/**
* Returns the entity associated with the command sender. MAY BE NULL!
*/
public Entity getCommandSenderEntity()
{
return playerIn;
}
/**
* Returns true if the command sender should be sent feedback about executed commands
*/
public boolean sendCommandFeedback()
{
return false;
}
public void setCommandStat(CommandResultStats.Type type, int amount)
{
if (TileEntitySign.this.world != null && !TileEntitySign.this.world.isRemote)
{
TileEntitySign.this.stats.setCommandStatForSender(TileEntitySign.this.world.getMinecraftServer(), this, type, amount);
}
}
/**
* Get the Minecraft server instance
*/
public MinecraftServer getServer()
{
return playerIn.getServer();
}
};
for (ITextComponent itextcomponent : this.signText)
{
Style style = itextcomponent == null ? null : itextcomponent.getStyle();
if (style != null && style.getClickEvent() != null)
{
ClickEvent clickevent = style.getClickEvent();
if (clickevent.getAction() == ClickEvent.Action.RUN_COMMAND)
{
playerIn.getServer().getCommandManager().executeCommand(icommandsender, clickevent.getValue());
}
}
}
return true;
}
public CommandResultStats getStats()
{
return this.stats;
}
}

View File

@@ -0,0 +1,214 @@
package net.minecraft.tileentity;
import com.google.common.collect.Iterables;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.block.BlockSkull;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.server.management.PlayerProfileCache;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.StringUtils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntitySkull extends TileEntity implements ITickable
{
private int skullType;
private int skullRotation;
private GameProfile playerProfile;
private int dragonAnimatedTicks;
private boolean dragonAnimated;
private static PlayerProfileCache profileCache;
private static MinecraftSessionService sessionService;
public static void setProfileCache(PlayerProfileCache profileCacheIn)
{
profileCache = profileCacheIn;
}
public static void setSessionService(MinecraftSessionService sessionServiceIn)
{
sessionService = sessionServiceIn;
}
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setByte("SkullType", (byte)(this.skullType & 255));
compound.setByte("Rot", (byte)(this.skullRotation & 255));
if (this.playerProfile != null)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
NBTUtil.writeGameProfile(nbttagcompound, this.playerProfile);
compound.setTag("Owner", nbttagcompound);
}
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.skullType = compound.getByte("SkullType");
this.skullRotation = compound.getByte("Rot");
if (this.skullType == 3)
{
if (compound.hasKey("Owner", 10))
{
this.playerProfile = NBTUtil.readGameProfileFromNBT(compound.getCompoundTag("Owner"));
}
else if (compound.hasKey("ExtraType", 8))
{
String s = compound.getString("ExtraType");
if (!StringUtils.isNullOrEmpty(s))
{
this.playerProfile = new GameProfile((UUID)null, s);
this.updatePlayerProfile();
}
}
}
}
/**
* Like the old updateEntity(), except more generic.
*/
public void update()
{
if (this.skullType == 5)
{
if (this.world.isBlockPowered(this.pos))
{
this.dragonAnimated = true;
++this.dragonAnimatedTicks;
}
else
{
this.dragonAnimated = false;
}
}
}
@SideOnly(Side.CLIENT)
public float getAnimationProgress(float p_184295_1_)
{
return this.dragonAnimated ? (float)this.dragonAnimatedTicks + p_184295_1_ : (float)this.dragonAnimatedTicks;
}
@Nullable
public GameProfile getPlayerProfile()
{
return this.playerProfile;
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 4, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public void setType(int type)
{
this.skullType = type;
this.playerProfile = null;
}
public void setPlayerProfile(@Nullable GameProfile playerProfile)
{
this.skullType = 3;
this.playerProfile = playerProfile;
this.updatePlayerProfile();
}
private void updatePlayerProfile()
{
this.playerProfile = updateGameprofile(this.playerProfile);
this.markDirty();
}
public static GameProfile updateGameprofile(GameProfile input)
{
if (input != null && !StringUtils.isNullOrEmpty(input.getName()))
{
if (input.isComplete() && input.getProperties().containsKey("textures"))
{
return input;
}
else if (profileCache != null && sessionService != null)
{
GameProfile gameprofile = profileCache.getGameProfileForUsername(input.getName());
if (gameprofile == null)
{
return input;
}
else
{
Property property = (Property)Iterables.getFirst(gameprofile.getProperties().get("textures"), (Object)null);
if (property == null)
{
gameprofile = sessionService.fillProfileProperties(gameprofile, true);
}
return gameprofile;
}
}
else
{
return input;
}
}
else
{
return input;
}
}
public int getSkullType()
{
return this.skullType;
}
@SideOnly(Side.CLIENT)
public int getSkullRotation()
{
return this.skullRotation;
}
public void setSkullRotation(int rotation)
{
this.skullRotation = rotation;
}
public void mirror(Mirror mirrorIn)
{
if (this.world != null && this.world.getBlockState(this.getPos()).getValue(BlockSkull.FACING) == EnumFacing.UP)
{
this.skullRotation = mirrorIn.mirrorRotation(this.skullRotation, 16);
}
}
public void rotate(Rotation rotationIn)
{
if (this.world != null && this.world.getBlockState(this.getPos()).getValue(BlockSkull.FACING) == EnumFacing.UP)
{
this.skullRotation = rotationIn.rotate(this.skullRotation, 16);
}
}
}

View File

@@ -0,0 +1,677 @@
package net.minecraft.tileentity;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStructure;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatAllowedCharacters;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.Mirror;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.StringUtils;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.Template;
import net.minecraft.world.gen.structure.template.TemplateManager;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class TileEntityStructure extends TileEntity
{
private String name = "";
private String author = "";
private String metadata = "";
private BlockPos position = new BlockPos(0, 1, 0);
private BlockPos size = BlockPos.ORIGIN;
private Mirror mirror = Mirror.NONE;
private Rotation rotation = Rotation.NONE;
private TileEntityStructure.Mode mode = TileEntityStructure.Mode.DATA;
private boolean ignoreEntities = true;
private boolean powered;
private boolean showAir;
private boolean showBoundingBox = true;
private float integrity = 1.0F;
private long seed;
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{
super.writeToNBT(compound);
compound.setString("name", this.name);
compound.setString("author", this.author);
compound.setString("metadata", this.metadata);
compound.setInteger("posX", this.position.getX());
compound.setInteger("posY", this.position.getY());
compound.setInteger("posZ", this.position.getZ());
compound.setInteger("sizeX", this.size.getX());
compound.setInteger("sizeY", this.size.getY());
compound.setInteger("sizeZ", this.size.getZ());
compound.setString("rotation", this.rotation.toString());
compound.setString("mirror", this.mirror.toString());
compound.setString("mode", this.mode.toString());
compound.setBoolean("ignoreEntities", this.ignoreEntities);
compound.setBoolean("powered", this.powered);
compound.setBoolean("showair", this.showAir);
compound.setBoolean("showboundingbox", this.showBoundingBox);
compound.setFloat("integrity", this.integrity);
compound.setLong("seed", this.seed);
return compound;
}
public void readFromNBT(NBTTagCompound compound)
{
super.readFromNBT(compound);
this.setName(compound.getString("name"));
this.author = compound.getString("author");
this.metadata = compound.getString("metadata");
int i = MathHelper.clamp(compound.getInteger("posX"), -32, 32);
int j = MathHelper.clamp(compound.getInteger("posY"), -32, 32);
int k = MathHelper.clamp(compound.getInteger("posZ"), -32, 32);
this.position = new BlockPos(i, j, k);
int l = MathHelper.clamp(compound.getInteger("sizeX"), 0, 32);
int i1 = MathHelper.clamp(compound.getInteger("sizeY"), 0, 32);
int j1 = MathHelper.clamp(compound.getInteger("sizeZ"), 0, 32);
this.size = new BlockPos(l, i1, j1);
try
{
this.rotation = Rotation.valueOf(compound.getString("rotation"));
}
catch (IllegalArgumentException var11)
{
this.rotation = Rotation.NONE;
}
try
{
this.mirror = Mirror.valueOf(compound.getString("mirror"));
}
catch (IllegalArgumentException var10)
{
this.mirror = Mirror.NONE;
}
try
{
this.mode = TileEntityStructure.Mode.valueOf(compound.getString("mode"));
}
catch (IllegalArgumentException var9)
{
this.mode = TileEntityStructure.Mode.DATA;
}
this.ignoreEntities = compound.getBoolean("ignoreEntities");
this.powered = compound.getBoolean("powered");
this.showAir = compound.getBoolean("showair");
this.showBoundingBox = compound.getBoolean("showboundingbox");
if (compound.hasKey("integrity"))
{
this.integrity = compound.getFloat("integrity");
}
else
{
this.integrity = 1.0F;
}
this.seed = compound.getLong("seed");
this.updateBlockState();
}
private void updateBlockState()
{
if (this.world != null)
{
BlockPos blockpos = this.getPos();
IBlockState iblockstate = this.world.getBlockState(blockpos);
if (iblockstate.getBlock() == Blocks.STRUCTURE_BLOCK)
{
this.world.setBlockState(blockpos, iblockstate.withProperty(BlockStructure.MODE, this.mode), 2);
}
}
}
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{
return new SPacketUpdateTileEntity(this.pos, 7, this.getUpdateTag());
}
public NBTTagCompound getUpdateTag()
{
return this.writeToNBT(new NBTTagCompound());
}
public boolean usedBy(EntityPlayer player)
{
if (!player.canUseCommandBlock())
{
return false;
}
else
{
if (player.getEntityWorld().isRemote)
{
player.openEditStructure(this);
}
return true;
}
}
public String getName()
{
return this.name;
}
public void setName(String nameIn)
{
String s = nameIn;
for (char c0 : ChatAllowedCharacters.ILLEGAL_STRUCTURE_CHARACTERS)
{
s = s.replace(c0, '_');
}
this.name = s;
}
public void createdBy(EntityLivingBase p_189720_1_)
{
if (!StringUtils.isNullOrEmpty(p_189720_1_.getName()))
{
this.author = p_189720_1_.getName();
}
}
@SideOnly(Side.CLIENT)
public BlockPos getPosition()
{
return this.position;
}
public void setPosition(BlockPos posIn)
{
this.position = posIn;
}
@SideOnly(Side.CLIENT)
public BlockPos getStructureSize()
{
return this.size;
}
public void setSize(BlockPos sizeIn)
{
this.size = sizeIn;
}
@SideOnly(Side.CLIENT)
public Mirror getMirror()
{
return this.mirror;
}
public void setMirror(Mirror mirrorIn)
{
this.mirror = mirrorIn;
}
public void setRotation(Rotation rotationIn)
{
this.rotation = rotationIn;
}
public void setMetadata(String metadataIn)
{
this.metadata = metadataIn;
}
@SideOnly(Side.CLIENT)
public Rotation getRotation()
{
return this.rotation;
}
@SideOnly(Side.CLIENT)
public String getMetadata()
{
return this.metadata;
}
public TileEntityStructure.Mode getMode()
{
return this.mode;
}
public void setMode(TileEntityStructure.Mode modeIn)
{
this.mode = modeIn;
IBlockState iblockstate = this.world.getBlockState(this.getPos());
if (iblockstate.getBlock() == Blocks.STRUCTURE_BLOCK)
{
this.world.setBlockState(this.getPos(), iblockstate.withProperty(BlockStructure.MODE, modeIn), 2);
}
}
public void setIgnoresEntities(boolean ignoreEntitiesIn)
{
this.ignoreEntities = ignoreEntitiesIn;
}
public void setIntegrity(float integrityIn)
{
this.integrity = integrityIn;
}
public void setSeed(long seedIn)
{
this.seed = seedIn;
}
@SideOnly(Side.CLIENT)
public void nextMode()
{
switch (this.getMode())
{
case SAVE:
this.setMode(TileEntityStructure.Mode.LOAD);
break;
case LOAD:
this.setMode(TileEntityStructure.Mode.CORNER);
break;
case CORNER:
this.setMode(TileEntityStructure.Mode.DATA);
break;
case DATA:
this.setMode(TileEntityStructure.Mode.SAVE);
}
}
@SideOnly(Side.CLIENT)
public boolean ignoresEntities()
{
return this.ignoreEntities;
}
@SideOnly(Side.CLIENT)
public float getIntegrity()
{
return this.integrity;
}
@SideOnly(Side.CLIENT)
public long getSeed()
{
return this.seed;
}
public boolean detectSize()
{
if (this.mode != TileEntityStructure.Mode.SAVE)
{
return false;
}
else
{
BlockPos blockpos = this.getPos();
int i = 80;
BlockPos blockpos1 = new BlockPos(blockpos.getX() - 80, 0, blockpos.getZ() - 80);
BlockPos blockpos2 = new BlockPos(blockpos.getX() + 80, 255, blockpos.getZ() + 80);
List<TileEntityStructure> list = this.getNearbyCornerBlocks(blockpos1, blockpos2);
List<TileEntityStructure> list1 = this.filterRelatedCornerBlocks(list);
if (list1.size() < 1)
{
return false;
}
else
{
StructureBoundingBox structureboundingbox = this.calculateEnclosingBoundingBox(blockpos, list1);
if (structureboundingbox.maxX - structureboundingbox.minX > 1 && structureboundingbox.maxY - structureboundingbox.minY > 1 && structureboundingbox.maxZ - structureboundingbox.minZ > 1)
{
this.position = new BlockPos(structureboundingbox.minX - blockpos.getX() + 1, structureboundingbox.minY - blockpos.getY() + 1, structureboundingbox.minZ - blockpos.getZ() + 1);
this.size = new BlockPos(structureboundingbox.maxX - structureboundingbox.minX - 1, structureboundingbox.maxY - structureboundingbox.minY - 1, structureboundingbox.maxZ - structureboundingbox.minZ - 1);
this.markDirty();
IBlockState iblockstate = this.world.getBlockState(blockpos);
this.world.notifyBlockUpdate(blockpos, iblockstate, iblockstate, 3);
return true;
}
else
{
return false;
}
}
}
}
private List<TileEntityStructure> filterRelatedCornerBlocks(List<TileEntityStructure> p_184415_1_)
{
Iterable<TileEntityStructure> iterable = Iterables.filter(p_184415_1_, new Predicate<TileEntityStructure>()
{
public boolean apply(@Nullable TileEntityStructure p_apply_1_)
{
return p_apply_1_.mode == TileEntityStructure.Mode.CORNER && TileEntityStructure.this.name.equals(p_apply_1_.name);
}
});
return Lists.newArrayList(iterable);
}
private List<TileEntityStructure> getNearbyCornerBlocks(BlockPos p_184418_1_, BlockPos p_184418_2_)
{
List<TileEntityStructure> list = Lists.<TileEntityStructure>newArrayList();
for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(p_184418_1_, p_184418_2_))
{
IBlockState iblockstate = this.world.getBlockState(blockpos$mutableblockpos);
if (iblockstate.getBlock() == Blocks.STRUCTURE_BLOCK)
{
TileEntity tileentity = this.world.getTileEntity(blockpos$mutableblockpos);
if (tileentity != null && tileentity instanceof TileEntityStructure)
{
list.add((TileEntityStructure)tileentity);
}
}
}
return list;
}
private StructureBoundingBox calculateEnclosingBoundingBox(BlockPos p_184416_1_, List<TileEntityStructure> p_184416_2_)
{
StructureBoundingBox structureboundingbox;
if (p_184416_2_.size() > 1)
{
BlockPos blockpos = ((TileEntityStructure)p_184416_2_.get(0)).getPos();
structureboundingbox = new StructureBoundingBox(blockpos, blockpos);
}
else
{
structureboundingbox = new StructureBoundingBox(p_184416_1_, p_184416_1_);
}
for (TileEntityStructure tileentitystructure : p_184416_2_)
{
BlockPos blockpos1 = tileentitystructure.getPos();
if (blockpos1.getX() < structureboundingbox.minX)
{
structureboundingbox.minX = blockpos1.getX();
}
else if (blockpos1.getX() > structureboundingbox.maxX)
{
structureboundingbox.maxX = blockpos1.getX();
}
if (blockpos1.getY() < structureboundingbox.minY)
{
structureboundingbox.minY = blockpos1.getY();
}
else if (blockpos1.getY() > structureboundingbox.maxY)
{
structureboundingbox.maxY = blockpos1.getY();
}
if (blockpos1.getZ() < structureboundingbox.minZ)
{
structureboundingbox.minZ = blockpos1.getZ();
}
else if (blockpos1.getZ() > structureboundingbox.maxZ)
{
structureboundingbox.maxZ = blockpos1.getZ();
}
}
return structureboundingbox;
}
@SideOnly(Side.CLIENT)
public void writeCoordinates(ByteBuf buf)
{
buf.writeInt(this.pos.getX());
buf.writeInt(this.pos.getY());
buf.writeInt(this.pos.getZ());
}
/**
* Saves the template, writing it to disk.
*
* @return true if the template was successfully saved.
*/
public boolean save()
{
return this.save(true);
}
/**
* Saves the template, either updating the local version or writing it to disk.
*
* @return true if the template was successfully saved.
*
* @param writeToDisk If true, {@link TemplateManager#writeTemplate} will be called with the template, and its
* return value will dictate the return value of this method. If false, the template will be updated but not written
* to disk.
*/
public boolean save(boolean writeToDisk)
{
if (this.mode == TileEntityStructure.Mode.SAVE && !this.world.isRemote && !StringUtils.isNullOrEmpty(this.name))
{
BlockPos blockpos = this.getPos().add(this.position);
WorldServer worldserver = (WorldServer)this.world;
MinecraftServer minecraftserver = this.world.getMinecraftServer();
TemplateManager templatemanager = worldserver.getStructureTemplateManager();
Template template = templatemanager.getTemplate(minecraftserver, new ResourceLocation(this.name));
template.takeBlocksFromWorld(this.world, blockpos, this.size, !this.ignoreEntities, Blocks.STRUCTURE_VOID);
template.setAuthor(this.author);
return !writeToDisk || templatemanager.writeTemplate(minecraftserver, new ResourceLocation(this.name));
}
else
{
return false;
}
}
/**
* Loads the given template, both into this structure block and into the world, aborting if the size of the template
* does not match the size in this structure block.
*
* @return true if the template was successfully added to the world.
*/
public boolean load()
{
return this.load(true);
}
/**
* Loads the given template, both into this structure block and into the world.
*
* @return true if the template was successfully added to the world.
*
* @param requireMatchingSize If true, and the size of the loaded template does not match the size in this structure
* block, the structure will not be loaded into the world and false will be returned. Regardless of the value of
* this parameter, the size in the structure block will be updated after calling this method.
*/
public boolean load(boolean requireMatchingSize)
{
if (this.mode == TileEntityStructure.Mode.LOAD && !this.world.isRemote && !StringUtils.isNullOrEmpty(this.name))
{
BlockPos blockpos = this.getPos();
BlockPos blockpos1 = blockpos.add(this.position);
WorldServer worldserver = (WorldServer)this.world;
MinecraftServer minecraftserver = this.world.getMinecraftServer();
TemplateManager templatemanager = worldserver.getStructureTemplateManager();
Template template = templatemanager.get(minecraftserver, new ResourceLocation(this.name));
if (template == null)
{
return false;
}
else
{
if (!StringUtils.isNullOrEmpty(template.getAuthor()))
{
this.author = template.getAuthor();
}
BlockPos blockpos2 = template.getSize();
boolean flag = this.size.equals(blockpos2);
if (!flag)
{
this.size = blockpos2;
this.markDirty();
IBlockState iblockstate = this.world.getBlockState(blockpos);
this.world.notifyBlockUpdate(blockpos, iblockstate, iblockstate, 3);
}
if (requireMatchingSize && !flag)
{
return false;
}
else
{
PlacementSettings placementsettings = (new PlacementSettings()).setMirror(this.mirror).setRotation(this.rotation).setIgnoreEntities(this.ignoreEntities).setChunk((ChunkPos)null).setReplacedBlock((Block)null).setIgnoreStructureBlock(false);
if (this.integrity < 1.0F)
{
placementsettings.setIntegrity(MathHelper.clamp(this.integrity, 0.0F, 1.0F)).setSeed(Long.valueOf(this.seed));
}
template.addBlocksToWorldChunk(this.world, blockpos1, placementsettings);
return true;
}
}
}
else
{
return false;
}
}
public void unloadStructure()
{
WorldServer worldserver = (WorldServer)this.world;
TemplateManager templatemanager = worldserver.getStructureTemplateManager();
templatemanager.remove(new ResourceLocation(this.name));
}
public boolean isStructureLoadable()
{
if (this.mode == TileEntityStructure.Mode.LOAD && !this.world.isRemote)
{
WorldServer worldserver = (WorldServer)this.world;
MinecraftServer minecraftserver = this.world.getMinecraftServer();
TemplateManager templatemanager = worldserver.getStructureTemplateManager();
return templatemanager.get(minecraftserver, new ResourceLocation(this.name)) != null;
}
else
{
return false;
}
}
public boolean isPowered()
{
return this.powered;
}
public void setPowered(boolean poweredIn)
{
this.powered = poweredIn;
}
@SideOnly(Side.CLIENT)
public boolean showsAir()
{
return this.showAir;
}
public void setShowAir(boolean showAirIn)
{
this.showAir = showAirIn;
}
@SideOnly(Side.CLIENT)
public boolean showsBoundingBox()
{
return this.showBoundingBox;
}
public void setShowBoundingBox(boolean showBoundingBoxIn)
{
this.showBoundingBox = showBoundingBoxIn;
}
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
@Nullable
public ITextComponent getDisplayName()
{
return new TextComponentTranslation("structure_block.hover." + this.mode.modeName, new Object[] {this.mode == TileEntityStructure.Mode.DATA ? this.metadata : this.name});
}
public static enum Mode implements IStringSerializable
{
SAVE("save", 0),
LOAD("load", 1),
CORNER("corner", 2),
DATA("data", 3);
private static final TileEntityStructure.Mode[] MODES = new TileEntityStructure.Mode[values().length];
private final String modeName;
private final int modeId;
private Mode(String modeNameIn, int modeIdIn)
{
this.modeName = modeNameIn;
this.modeId = modeIdIn;
}
public String getName()
{
return this.modeName;
}
public int getModeId()
{
return this.modeId;
}
public static TileEntityStructure.Mode getById(int id)
{
return id >= 0 && id < MODES.length ? MODES[id] : MODES[0];
}
static
{
for (TileEntityStructure.Mode tileentitystructure$mode : values())
{
MODES[tileentitystructure$mode.getModeId()] = tileentitystructure$mode;
}
}
}
}

View File

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