Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check Food 'Edibility' #149

Merged
merged 9 commits into from
May 21, 2020
15 changes: 15 additions & 0 deletions java/squeek/applecore/api/IAppleCoreAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ public interface IAppleCoreAccessor
*/
boolean isFood(@Nonnull ItemStack food);

/**
* Check if the given ItemStack can currently be eaten by the player, taking into account their
* max hunger, and if the food item is always edible.<br>
* <br>
* In particular, this method will always return {@code true} if
* {@link net.minecraft.util.FoodStats#getFoodLevel} {@code <} {@link #getMaxHunger}
* or if this ItemStack's Item is an instance of ItemFood and has its alwaysEdible field set.<br>
* <br>
* Note: {@link ItemStack#EMPTY} can be passed to this function in order to check whether
* the player's hunger is currently below maximum.
*
* @return {@code true} if the player is currently able to eat the food item, {@code false} otherwise.
*/
boolean canPlayerEatFood(@Nonnull ItemStack food, @Nonnull EntityPlayer player);

/**
* Get player-agnostic food values.
*
Expand Down
25 changes: 25 additions & 0 deletions java/squeek/applecore/api_impl/AppleCoreAccessorMutatorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import squeek.applecore.api.AppleCoreAPI;
import squeek.applecore.api.IAppleCoreAccessor;
import squeek.applecore.api.IAppleCoreMutator;
Expand All @@ -19,6 +20,7 @@
import squeek.applecore.asm.util.IAppleCoreFoodStats;

import javax.annotation.Nonnull;
import java.lang.reflect.Field;

public enum AppleCoreAccessorMutatorImpl implements IAppleCoreAccessor, IAppleCoreMutator
{
Expand Down Expand Up @@ -52,6 +54,29 @@ private boolean isEdible(@Nonnull ItemStack food)
return AppleCoreAPI.registry.getEdibleBlockFromItem(food.getItem()) != null;
}

@Override
public boolean canPlayerEatFood(@Nonnull ItemStack food, @Nonnull EntityPlayer player)
{
return player.getFoodStats().getFoodLevel() < getMaxHunger(player) || isAlwaysEdible(food);
}

protected static final Field itemFoodAlwaysEdible = ReflectionHelper.findField(ItemFood.class, "alwaysEdible", "field_77852_bZ", "e");

private boolean isAlwaysEdible(@Nonnull ItemStack food)
{
if (food == ItemStack.EMPTY || !(food.getItem() instanceof ItemFood))
return false;

try
{
return itemFoodAlwaysEdible.getBoolean(food.getItem());
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}

@Override
public FoodValues getUnmodifiedFoodValues(@Nonnull ItemStack food)
{
Expand Down
6 changes: 6 additions & 0 deletions java/squeek/applecore/example/FoodValuesTooltipHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public void onItemTooltip(ItemTooltipEvent event)
event.getToolTip().add("- Player-specific: " + playerValues.hunger + " : " + playerValues.saturationModifier + " (+" + DF.format(playerValues.getSaturationIncrement(event.getEntityPlayer())) + ")");
event.getToolTip().add("- Player-agnostic: " + modifiedValues.hunger + " : " + modifiedValues.saturationModifier + " (+" + DF.format(modifiedValues.getSaturationIncrement(event.getEntityPlayer())) + ")");
event.getToolTip().add("- Unmodified: " + unmodifiedValues.hunger + " : " + unmodifiedValues.saturationModifier + " (+" + DF.format(unmodifiedValues.getSaturationIncrement(event.getEntityPlayer())) + ")");

if (event.getEntityPlayer() != null)
{
boolean isCurrentlyEdible = AppleCoreAPI.accessor.canPlayerEatFood(event.getItemStack(), event.getEntityPlayer());
event.getToolTip().add(isCurrentlyEdible ? "Can currently be eaten" : "Can not currently be eaten");
}
}
}
}