Skip to content

Integrating food items with AppleCore

Ryan Liptak edited this page Jan 24, 2016 · 17 revisions

If you want your food to integrate with AppleCore, do not call FoodStats.addStats(int, float) when it is eaten. Use the ItemStack-aware FoodStats.func_151686_a(ItemFood, ItemStack) method instead.

ItemFood integration checklist

If your food extends ItemFood and uses the standard Minecraft ItemFood methods, your food will integrate with AppleCore without issue.

  • Have your item extend ItemFood.
  • Use the ItemStack-aware hunger and saturation getters (getHealAmount/func_150905_g for hunger value and getSaturationModifier/func_150906_h for the saturation modifier).
  • Use the default ItemFood.onEaten (1.7.10) / ItemFood.onItemUseFinish (1.8+) implementation or make sure that your overridden version still calls FoodStats.func_151686_a(ItemFood, ItemStack) (the ItemStack-aware version of FoodStats.addStats).

That's it. Your food will integrate properly with AppleCore if you're able to check off all of the above. If you want to use metadata-based food items, you can find an example AppleCore-compatible implementation in the example package.

Non-standard food integration

If your food does not extend ItemFood, then you can implement AppleCore's IEdible interface and use ItemFoodProxy to call FoodStats.func_151686_a(ItemFood, ItemStack) when the food is eaten.

Here is an example implementation with the irrelevant parts removed (full implementation):

@Optional.Interface(iface = "squeek.applecore.api.food.IEdible", modid = "AppleCore")
public class ItemNonStandardFood extends Item implements IEdible
{
	@Optional.Method(modid = "AppleCore")
	@Override
	public FoodValues getFoodValues(ItemStack itemStack)
	{
		return new FoodValues(1, 1f);
	}

	// This needs to be abstracted into an Optional method,
	// otherwise the ItemFoodProxy reference will cause problems
	@Optional.Method(modid = "AppleCore")
	public void onEatenCompatibility(ItemStack itemStack, EntityPlayer player)
	{
		// one possible compatible method
		player.getFoodStats().func_151686_a(new ItemFoodProxy(this), itemStack);

		// another possible compatible method:
		// new ItemFoodProxy(this).onEaten(itemStack, player);
	}

	@Override
	// this method was called onEaten in 1.7.10
	public ItemStack onItemUseFinish(ItemStack itemStack, World world, EntityPlayer player)
	{
		--itemStack.stackSize;

		if (Loader.isModLoaded("AppleCore"))
		{
			onEatenCompatibility(itemStack, player);
		}
		else
		{
			// this method is not compatible with AppleCore
			player.getFoodStats().addStats(1, 1f);
		}

		return itemStack;
	}
}

Note also that the above example degrades nicely: if AppleCore is not loaded, it will still function as expected.

Making a food item inedible

Foods are considered inedible, and therefore will return false when passed to AppleCoreAPI.accessor.isFood if the Item implementation does not return EnumAction.EAT or EnumAction.DRINK from Item.getItemUseAction.

public class ItemFoodEdibleSometimes extends ItemFood
{
	@Override
	public EnumAction getItemUseAction(ItemStack itemStack)
	{
		return someCondition(itemStack) ? EnumAction.EAT : EnumAction.NONE;
	}
}