Fixed consumables giving wrong amount of food or saturation

This commit is contained in:
Indyuce 2022-02-26 13:33:26 +01:00
parent 970b55155e
commit a9bd80fac3
10 changed files with 51 additions and 20 deletions

View File

@ -9,6 +9,7 @@ import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.event.item.ConsumableConsumedEvent;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
import net.Indyuce.mmoitems.api.item.util.LoreUpdate;
import net.Indyuce.mmoitems.stat.type.ConsumableItemInteraction;
import net.Indyuce.mmoitems.stat.type.PlayerConsumable;
@ -52,9 +53,10 @@ public class Consumable extends UseItem {
}
/**
* @param vanillaEeating See {@link PlayerConsumable#onConsume(VolatileMMOItem, Player, boolean)}
* @return If the item should be consumed
*/
public ConsumableConsumeResult useOnPlayer(EquipmentSlot handUsed) {
public ConsumableConsumeResult useOnPlayer(EquipmentSlot handUsed, boolean vanillaEeating) {
NBTItem nbtItem = getNBTItem();
// Inedible stat cancels this operation from the beginning
@ -69,7 +71,7 @@ public class Consumable extends UseItem {
// Run through all
for (PlayerConsumable sc : MMOItems.plugin.getStats().getPlayerConsumables())
sc.onConsume(mmoitem, player);
sc.onConsume(mmoitem, player, vanillaEeating);
/**
* If the item does not have a maximum amount of uses, this will always

View File

@ -83,7 +83,7 @@ public class ItemUse implements Listener {
if (useItem instanceof Consumable) {
event.setUseItemInHand(Event.Result.DENY);
Consumable.ConsumableConsumeResult result = ((Consumable) useItem).useOnPlayer(event.getHand());
Consumable.ConsumableConsumeResult result = ((Consumable) useItem).useOnPlayer(event.getHand(), false);
if (result == Consumable.ConsumableConsumeResult.CANCEL)
return;
@ -327,7 +327,7 @@ public class ItemUse implements Listener {
* Consumables which can be eaten using the
* vanilla eating animation are handled here.
*/
@EventHandler
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void handleVanillaEatenConsumables(PlayerItemConsumeEvent event) {
NBTItem item = MythicLib.plugin.getVersion().getWrapper().getNBTItem(event.getItem());
if (!item.hasType())
@ -350,7 +350,7 @@ public class ItemUse implements Listener {
return;
}
Consumable.ConsumableConsumeResult result = ((Consumable) useItem).useOnPlayer(event.getItem().equals(player.getInventory().getItemInMainHand()) ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND);
Consumable.ConsumableConsumeResult result = ((Consumable) useItem).useOnPlayer(event.getItem().equals(player.getInventory().getItemInMainHand()) ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND, true);
// No effects are applied and not consumed
if (result == Consumable.ConsumableConsumeResult.CANCEL) {

View File

@ -222,7 +222,7 @@ public class CustomSounds extends ItemStat implements GemStoneStat, PlayerConsum
}
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
// No sound, straight up default-yo
if (!mmo.hasData(ItemStats.CUSTOM_SOUNDS)) {

View File

@ -219,7 +219,7 @@ public class Effects extends ItemStat implements PlayerConsumable {
}
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
// Does it have effects?
if (!mmo.hasData(ItemStats.EFFECTS))

View File

@ -1,5 +1,6 @@
package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmoitems.ItemStats;
@ -9,6 +10,7 @@ import net.Indyuce.mmoitems.stat.data.DoubleData;
import net.Indyuce.mmoitems.stat.type.DoubleStat;
import net.Indyuce.mmoitems.stat.type.PlayerConsumable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
@ -22,7 +24,7 @@ public class RestoreFood extends DoubleStat implements PlayerConsumable {
}
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
// No data no service
if (!mmo.hasData(ItemStats.RESTORE_FOOD))
@ -30,9 +32,20 @@ public class RestoreFood extends DoubleStat implements PlayerConsumable {
// Get value
DoubleData d = (DoubleData) mmo.getData(ItemStats.RESTORE_FOOD);
int actualValue = SilentNumbers.ceil(d.getValue() - (vanillaEating ? getFoodRestored(mmo.getNBT().getItem()) : 0));
// Any food being provided?
if (d.getValue() != 0)
MMOUtils.feed(player, SilentNumbers.ceil(d.getValue()));
if (actualValue != 0)
MMOUtils.feed(player, actualValue);
}
private int getFoodRestored(ItemStack item) {
try {
return MythicLib.plugin.getVersion().getWrapper().getFoodRestored(item);
} catch (Exception ignored) {
// If it is not a food item
return 0;
}
}
}

View File

@ -22,7 +22,7 @@ public class RestoreHealth extends DoubleStat implements PlayerConsumable {
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
// No data no service
if (!mmo.hasData(ItemStats.RESTORE_HEALTH))

View File

@ -21,7 +21,7 @@ public class RestoreMana extends DoubleStat implements PlayerConsumable {
}
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
// No data no service
if (!mmo.hasData(ItemStats.RESTORE_MANA))

View File

@ -1,5 +1,6 @@
package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
@ -8,6 +9,7 @@ import net.Indyuce.mmoitems.stat.type.DoubleStat;
import net.Indyuce.mmoitems.stat.type.PlayerConsumable;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
@ -20,21 +22,33 @@ public class RestoreSaturation extends DoubleStat implements PlayerConsumable {
super("RESTORE_SATURATION", Material.GOLDEN_CARROT, "Saturation Restoration", new String[]{"Saturation given when consumed."}, new String[]{"consumable"});
}
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
/*
* For some reason, it was in the earlier code that the default value
* of restored saturation is 6... I am all for backwards compatibility
* such that this must be respected.
*
* 6 is the saturation for a cooked beef
* 6 is the saturation for a cooked beef. Since 6.7 it now uses the item
* default saturation modifier using NMS code
*/
double saturation = mmo.hasData(ItemStats.RESTORE_SATURATION) ? ((DoubleData) mmo.getData(ItemStats.RESTORE_SATURATION)).getValue() : 6;
double defSaturation = getSaturationRestored(mmo.getNBT().getItem());
double saturation = mmo.hasData(ItemStats.RESTORE_SATURATION) ? ((DoubleData) mmo.getData(ItemStats.RESTORE_SATURATION)).getValue() : defSaturation;
saturation = saturation - (vanillaEating ? defSaturation : 0);
// Any saturation being provided?
if (saturation != 0)
MMOUtils.saturate(player, saturation);
}
private float getSaturationRestored(ItemStack item) {
try {
return MythicLib.plugin.getVersion().getWrapper().getSaturationRestored(item);
} catch (Exception ignored) {
// If it is not a food item
return 0;
}
}
}

View File

@ -21,7 +21,7 @@ public class RestoreStamina extends DoubleStat implements PlayerConsumable {
}
@Override
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player) {
public void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating) {
// No data no service
if (!mmo.hasData(ItemStats.RESTORE_STAMINA)) return;

View File

@ -15,13 +15,15 @@ import org.jetbrains.annotations.NotNull;
*
* @author Gunging
*/
@FunctionalInterface
public interface PlayerConsumable {
/**
* Called when the item is being consumed directly by a player.
*
* @return The return value is not being used anymore.
* @since 6.7 You need to specify if the item is being eaten the vanilla
* way or not. This is used to fix an issue where when eating through the
* vanilla eating animation, the default food and saturation modifier is
* applied so MMOItems needs to apply some offset to food/saturation.
*/
void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player);
void onConsume(@NotNull VolatileMMOItem mmo, @NotNull Player player, boolean vanillaEating);
}