[1.11] Fix nullability issues around ForgeHooks and Capabilities (#3395)

This commit is contained in:
mezz authored and LexManos committed 2016-11-17 10:44:31 -08:00
1 parent bf090cb4c2
commit 150566d9a3
26 files changed
+165 -108

No files matched your search

@@ -30,7 +30,6 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Throwables;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
@@ -45,7 +44,6 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityMinecartContainer;
@@ -55,7 +53,6 @@ import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerRepair;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
@@ -92,11 +89,9 @@ import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.GameType;
import net.minecraft.world.storage.loot.LootEntry;
import net.minecraft.world.storage.loot.LootTable;
import net.minecraft.world.storage.loot.LootTableManager;
import net.minecraft.world.storage.loot.conditions.LootCondition;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.AnvilUpdateEvent;
@@ -121,23 +116,25 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.NoteBlockEvent;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ForgeHooks
{
//TODO: Loot tables?
static class SeedEntry extends WeightedRandom.Item
{
@Nonnull
public final ItemStack seed;
public SeedEntry(ItemStack seed, int weight)
public SeedEntry(@Nonnull ItemStack seed, int weight)
{
super(weight);
this.seed = seed;
}
@Nonnull
public ItemStack getStack(Random rand, int fortune)
{
return seed.copy();
@@ -148,7 +145,7 @@ public class ForgeHooks
public static ItemStack getGrassSeed(Random rand, int fortune)
{
SeedEntry entry = WeightedRandom.getRandomItem(rand, seedList);
if (entry == null || entry.seed == null)
if (entry == null || entry.seed.func_190926_b())
{
return ItemStack.field_190927_a;
}
@@ -169,7 +166,7 @@ public class ForgeHooks
ItemStack stack = player.inventory.getCurrentItem();
String tool = block.getHarvestTool(state);
if (stack == null || tool == null)
if (stack.func_190926_b() || tool == null)
{
return player.canHarvestBlock(state);
}
@@ -183,12 +180,12 @@ public class ForgeHooks
return toolLevel >= block.getHarvestLevel(state);
}
public static boolean canToolHarvestBlock(IBlockAccess world, BlockPos pos, ItemStack stack)
public static boolean canToolHarvestBlock(IBlockAccess world, BlockPos pos, @Nonnull ItemStack stack)
{
IBlockState state = world.getBlockState(pos);
state = state.getBlock().getActualState(state, world, pos);
String tool = state.getBlock().getHarvestTool(state);
if (stack == null || tool == null) return false;
if (stack.func_190926_b() || tool == null) return false;
return stack.getItem().getHarvestLevel(stack, tool, null, null) >= state.getBlock().getHarvestLevel(state);
}
@@ -287,6 +284,8 @@ public class ForgeHooks
{
seedList.add(new SeedEntry(new ItemStack(Items.WHEAT_SEEDS), 10)
{
@Override
@Nonnull
public ItemStack getStack(Random rand, int fortune)
{
return new ItemStack(Items.WHEAT_SEEDS, 1 + rand.nextInt(fortune * 2 + 1));
@@ -455,7 +454,7 @@ public class ForgeHooks
}
}
*/
ItemStack result = null;
ItemStack result;
boolean isCreative = player.capabilities.isCreativeMode;
TileEntity te = null;
@@ -483,28 +482,11 @@ public class ForgeHooks
result = target.entityHit.getPickedResult(target);
}
if (result == null)
if (result.func_190926_b())
{
return false;
}
if (result.getItem() == null)
{
String s1 = "";
if (target.typeOfHit == RayTraceResult.Type.BLOCK)
{
s1 = Block.REGISTRY.getNameForObject(world.getBlockState(target.getBlockPos()).getBlock()).toString();
}
else if (target.typeOfHit == RayTraceResult.Type.ENTITY)
{
s1 = EntityList.getEntityString(target.entityHit);
}
FMLLog.warning("Picking on: [%s] %s gave null item", target.typeOfHit, s1);
return true;
}
if (te != null)
{
Minecraft.getMinecraft().storeTEInStack(result, te);
@@ -562,6 +544,7 @@ public class ForgeHooks
return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit));
}
@Nullable
public static float[] onLivingFall(EntityLivingBase entity, float distance, float damageMultiplier)
{
LivingFallEvent event = new LivingFallEvent(entity, distance, damageMultiplier);
@@ -597,13 +580,13 @@ public class ForgeHooks
return value >= maxXZDistance ? maxXZDistance : value;
}
public static boolean isLivingOnLadder(IBlockState state, World world, BlockPos pos, EntityLivingBase entity)
public static boolean isLivingOnLadder(@Nonnull IBlockState state, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EntityLivingBase entity)
{
boolean isSpectator = (entity instanceof EntityPlayer && ((EntityPlayer)entity).isSpectator());
if (isSpectator) return false;
if (!ForgeModContainer.fullBoundingBoxLadders)
{
return state != null && state.getBlock().isLadder(state, world, pos, entity);
return state.getBlock().isLadder(state, world, pos, entity);
}
else
{
@@ -635,7 +618,7 @@ public class ForgeHooks
MinecraftForge.EVENT_BUS.post(new LivingJumpEvent(entity));
}
public static EntityItem onPlayerTossEvent(EntityPlayer player, ItemStack item, boolean includeName)
public static EntityItem onPlayerTossEvent(@Nonnull EntityPlayer player, @Nonnull ItemStack item, boolean includeName)
{
player.captureDrops = true;
EntityItem ret = player.dropItem(item, false, includeName);
@@ -660,7 +643,7 @@ public class ForgeHooks
return event.getEntityItem();
}
public static float getEnchantPower(World world, BlockPos pos)
public static float getEnchantPower(@Nonnull World world, @Nonnull BlockPos pos)
{
return world.getBlockState(pos).getBlock().getEnchantPowerBonus(world, pos);
}
@@ -759,7 +742,7 @@ public class ForgeHooks
{
// Logic from tryHarvestBlock for pre-canceling the event
boolean preCancelEvent = false;
if (gameType.isCreative() && entityPlayer.getHeldItemMainhand() != null && entityPlayer.getHeldItemMainhand().getItem() instanceof ItemSword)
if (gameType.isCreative() && !entityPlayer.getHeldItemMainhand().func_190926_b() && entityPlayer.getHeldItemMainhand().getItem() instanceof ItemSword)
preCancelEvent = true;
if (gameType.isAdventure())
@@ -770,7 +753,7 @@ public class ForgeHooks
if (!entityPlayer.isAllowEdit())
{
ItemStack itemstack = entityPlayer.getHeldItemMainhand();
if (itemstack == null || !itemstack.canDestroy(world.getBlockState(pos).getBlock()))
if (itemstack.func_190926_b() || !itemstack.canDestroy(world.getBlockState(pos).getBlock()))
preCancelEvent = true;
}
}
@@ -885,7 +868,7 @@ public class ForgeHooks
int updateFlag = snap.getFlag();
IBlockState oldBlock = snap.getReplacedBlock();
IBlockState newBlock = world.getBlockState(snap.getPos());
if (newBlock != null && !(newBlock.getBlock().hasTileEntity(newBlock))) // Containers get placed automatically
if (!newBlock.getBlock().hasTileEntity(newBlock)) // Containers get placed automatically
{
newBlock.getBlock().onBlockAdded(world, snap.getPos(), newBlock);
}
@@ -904,7 +887,7 @@ public class ForgeHooks
{
AnvilUpdateEvent e = new AnvilUpdateEvent(left, right, name, baseCost);
if (MinecraftForge.EVENT_BUS.post(e)) return false;
if (e.getOutput() == null) return true;
if (e.getOutput().func_190926_b()) return true;
outputSlot.setInventorySlotContents(0, e.getOutput());
container.maximumCost = e.getCost();
@@ -1007,8 +990,7 @@ public class ForgeHooks
{
if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(player, target))) return false;
ItemStack stack = player.getHeldItemMainhand();
if (stack != null && stack.getItem().onLeftClickEntity(stack, player, target)) return false;
return true;
return stack.func_190926_b() || !stack.getItem().onLeftClickEntity(stack, player, target);
}
public static boolean onTravelToDimension(Entity entity, int dimension)
@@ -1147,7 +1129,7 @@ public class ForgeHooks
this.entryNames.clear();
}
public String validateEntryName(String name)
public String validateEntryName(@Nullable String name)
{
if (!this.entryNames.contains(name))
{
@@ -19,6 +19,7 @@
package net.minecraftforge.common.capabilities;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
@@ -86,7 +87,7 @@ public final class CapabilityDispatcher implements INBTSerializable<NBTTagCompou
}
@Override
public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing)
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing)
{
for (ICapabilityProvider cap : caps)
{
@@ -99,7 +100,8 @@ public final class CapabilityDispatcher implements INBTSerializable<NBTTagCompou
}
@Override
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
@Nullable
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
{
for (ICapabilityProvider cap : caps)
{
@@ -19,6 +19,7 @@
package net.minecraftforge.common.capabilities;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.util.EnumFacing;
@@ -40,7 +41,7 @@ public interface ICapabilityProvider
* CAN BE NULL. Null is defined to represent 'internal' or 'self'
* @return True if this object supports the capability.
*/
boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing);
boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing);
/**
* Retrieves the handler for the capability requested on the specific side.
@@ -50,7 +51,8 @@ public interface ICapabilityProvider
* @param capability The capability to check
* @param facing The Side to check from:
* CAN BE NULL. Null is defined to represent 'internal' or 'self'
* @return True if this object supports the capability.
* @return The requested capability. Returns null when {@link #hasCapability(Capability, EnumFacing)} would return false.
*/
<T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing);
@Nullable
<T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing);
}
@@ -28,6 +28,9 @@ import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class CapabilityAnimation
{
@CapabilityInject(IAnimationStateMachine.class)
@@ -61,12 +64,15 @@ public class CapabilityAnimation
this.asm = asm;
}
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing)
{
return capability == ANIMATION_CAPABILITY;
}
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
@Override
@Nullable
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
{
if(capability == ANIMATION_CAPABILITY)
{
@@ -23,6 +23,8 @@ import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
/**
*
* AnvilUpdateEvent is fired when a player places items in both the left and right slots of a anvil.
@@ -33,27 +35,34 @@ import net.minecraft.item.ItemStack;
@Cancelable
public class AnvilUpdateEvent extends Event
{
@Nonnull
private final ItemStack left; // The left side of the input
@Nonnull
private final ItemStack right; // The right side of the input
private final String name; // The name to set the item, if the user specified one.
@Nonnull
private ItemStack output; // Set this to set the output stack
private int cost; // The base cost, set this to change it if output != null
private int materialCost; // The number of items from the right slot to be consumed during the repair. Leave as 0 to consume the entire stack.
public AnvilUpdateEvent(ItemStack left, ItemStack right, String name, int cost)
public AnvilUpdateEvent(@Nonnull ItemStack left, @Nonnull ItemStack right, String name, int cost)
{
this.left = left;
this.right = right;
this.output = ItemStack.field_190927_a;
this.name = name;
this.setCost(cost);
this.setMaterialCost(0);
}
@Nonnull
public ItemStack getLeft() { return left; }
@Nonnull
public ItemStack getRight() { return right; }
public String getName() { return name; }
@Nonnull
public ItemStack getOutput() { return output; }
public void setOutput(ItemStack output) { this.output = output; }
public void setOutput(@Nonnull ItemStack output) { this.output = output; }
public int getCost() { return cost; }
public void setCost(int cost) { this.cost = cost; }
public int getMaterialCost() { return materialCost; }
@@ -113,6 +113,7 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.Event.Result;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ForgeEventFactory
@@ -173,7 +174,7 @@ public class ForgeEventFactory
return (MinecraftForge.EVENT_BUS.post(event) ? -1 : event.getNewSpeed());
}
public static void onPlayerDestroyItem(EntityPlayer player, ItemStack stack, EnumHand hand)
public static void onPlayerDestroyItem(EntityPlayer player, @Nonnull ItemStack stack, @Nullable EnumHand hand)
{
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, stack, hand));
}
@@ -38,6 +38,9 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* PlayerDestroyItemEvent is fired when a player destroys an item.<br>
* This event is fired whenever a player destroys an item in
@@ -61,16 +64,20 @@ import net.minecraft.util.EnumHand;
**/
public class PlayerDestroyItemEvent extends PlayerEvent
{
@Nonnull
private final ItemStack original;
@Nullable
private final EnumHand hand; // May be null if this player destroys the item by any use besides holding it.
public PlayerDestroyItemEvent(EntityPlayer player, ItemStack original, EnumHand hand)
public PlayerDestroyItemEvent(EntityPlayer player, @Nonnull ItemStack original, @Nullable EnumHand hand)
{
super(player);
this.original = original;
this.hand = hand;
}
@Nonnull
public ItemStack getOriginal() { return this.original; }
@Nullable
public EnumHand getHand() { return this.hand; }
}
@@ -26,6 +26,9 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidTank;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class TileFluidHandler extends TileEntity
{
protected FluidTank tank = new FluidTank(Fluid.BUCKET_VOLUME);
@@ -46,14 +49,15 @@ public class TileFluidHandler extends TileEntity
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
@Nullable
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
{
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
return (T) tank;
@@ -201,14 +201,15 @@ public class FluidHandlerItemStack implements IFluidHandlerItem, ICapabilityProv
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
@Nullable
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY ? (T) this : null;
}
@@ -178,14 +178,15 @@ public class FluidHandlerItemStackSimple implements IFluidHandlerItem, ICapabili
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
@Nullable
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY ? (T) this : null;
}
@@ -186,13 +186,14 @@ public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvide
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
@Nullable
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing)
{
if (capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY)
{