diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 7eb7649b..91b4fcae 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -1,7 +1,5 @@ package com.minelittlepony.unicopia; -import com.minelittlepony.unicopia.item.toxin.Toxics; - import net.minecraft.block.Block; import net.minecraft.entity.EntityType; import net.minecraft.entity.damage.DamageType; @@ -79,8 +77,4 @@ public interface UTags { static TagKey dimension(String name) { return TagKey.of(RegistryKeys.DIMENSION_TYPE, new Identifier("c", name)); } - - static void bootstrap() { - Toxics.bootstrap(); - } } diff --git a/src/main/java/com/minelittlepony/unicopia/Unicopia.java b/src/main/java/com/minelittlepony/unicopia/Unicopia.java index e683b561..03e48838 100644 --- a/src/main/java/com/minelittlepony/unicopia/Unicopia.java +++ b/src/main/java/com/minelittlepony/unicopia/Unicopia.java @@ -22,8 +22,8 @@ import com.minelittlepony.unicopia.command.Commands; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.container.SpellbookChapterLoader; import com.minelittlepony.unicopia.container.UScreenHandlers; -import com.minelittlepony.unicopia.diet.AfflictionType; import com.minelittlepony.unicopia.diet.DietsLoader; +import com.minelittlepony.unicopia.diet.affliction.AfflictionType; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.effect.UPotions; import com.minelittlepony.unicopia.entity.mob.UEntities; @@ -66,7 +66,6 @@ public class Unicopia implements ModInitializer { @Override public void onInitialize() { Channel.bootstrap(); - UTags.bootstrap(); UCriteria.bootstrap(); UEntities.bootstrap(); Commands.bootstrap(); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/Ailment.java b/src/main/java/com/minelittlepony/unicopia/diet/Ailment.java index f16ae703..9dadb1a8 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/Ailment.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/Ailment.java @@ -1,23 +1,22 @@ package com.minelittlepony.unicopia.diet; -import com.minelittlepony.unicopia.item.toxin.Toxicity; +import com.minelittlepony.unicopia.diet.affliction.Affliction; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.network.PacketByteBuf; -public record Ailment(Toxicity toxicity, Affliction effects) { +public record Ailment(Affliction effects) { + public static final Ailment EMPTY = new Ailment(Affliction.EMPTY); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Toxicity.CODEC.fieldOf("toxicity").forGetter(Ailment::toxicity), Affliction.CODEC.fieldOf("effects").forGetter(Ailment::effects) ).apply(instance, Ailment::new)); public Ailment(PacketByteBuf buffer) { - this(Toxicity.byName(buffer.readString()), Affliction.read(buffer)); + this(Affliction.read(buffer)); } public void toBuffer(PacketByteBuf buffer) { - buffer.writeString(toxicity.name()); Affliction.write(buffer, effects); } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java index bb14b3e4..46900f8f 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java @@ -8,30 +8,43 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.item.ItemDuck; +import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.FoodComponent; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.tag.TagKey; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.UseAction; public record DietProfile( float defaultMultiplier, float foragingMultiplier, List multipliers, - List effects + List effects, + Optional defaultEffect ) { + public static final DietProfile EMPTY = new DietProfile(1, 1, List.of(), List.of(), Optional.empty()); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.FLOAT.fieldOf("default_multiplier").forGetter(DietProfile::defaultMultiplier), Codec.FLOAT.fieldOf("foraging_multiplier").forGetter(DietProfile::foragingMultiplier), Codec.list(Multiplier.CODEC).fieldOf("multipliers").forGetter(DietProfile::multipliers), - Codec.list(Effect.CODEC).fieldOf("effects").forGetter(DietProfile::effects) + Codec.list(Effect.CODEC).fieldOf("effects").forGetter(DietProfile::effects), + Effect.CODEC.optionalFieldOf("default_effect").forGetter(DietProfile::defaultEffect) ).apply(instance, DietProfile::new)); public DietProfile(PacketByteBuf buffer) { - this(buffer.readFloat(), buffer.readFloat(), buffer.readList(Multiplier::new), buffer.readList(Effect::new)); + this(buffer.readFloat(), buffer.readFloat(), buffer.readList(Multiplier::new), buffer.readList(Effect::new), buffer.readOptional(Effect::new)); } public void toBuffer(PacketByteBuf buffer) { @@ -39,6 +52,7 @@ public record DietProfile( buffer.writeFloat(foragingMultiplier); buffer.writeCollection(multipliers, (b, t) -> t.toBuffer(b)); buffer.writeCollection(effects, (b, t) -> t.toBuffer(b)); + buffer.writeOptional(defaultEffect, (b, t) -> t.toBuffer(b)); } public Optional findMultiplier(ItemStack stack) { @@ -46,7 +60,68 @@ public record DietProfile( } public Optional findEffect(ItemStack stack) { - return effects.stream().filter(m -> m.test(stack)).findFirst(); + return effects.stream().filter(m -> m.test(stack)).findFirst().or(this::defaultEffect); + } + + static boolean isForaged(ItemStack stack) { + return ((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty(); + } + + @Nullable + public FoodComponent getAdjustedFoodComponent(ItemStack stack) { + var food = stack.getItem().getFoodComponent(); + if (this == EMPTY) { + return food; + } + + var ratios = getRatios(stack); + if (isInedible(ratios)) { + return null; + } + + return FoodAttributes.copy(food) + .hunger(Math.max(1, (int)(food.getHunger() * ratios.getFirst()))) + .saturationModifier(food.getSaturationModifier() * ratios.getSecond()) + .build(); + } + + public boolean isInedible(ItemStack stack) { + return isInedible(getRatios(stack)); + } + + public boolean isInedible(Pair ratios) { + return ratios.getFirst() <= 0.01F && ratios.getSecond() <= 0.01F; + } + + public Pair getRatios(ItemStack stack) { + Optional multiplier = findMultiplier(stack); + + float baseMultiplier = (isForaged(stack) ? foragingMultiplier() : defaultMultiplier()); + float hungerMultiplier = multiplier.map(Multiplier::hunger).orElse(baseMultiplier); + float saturationMultiplier = multiplier.map(Multiplier::saturation).orElse(baseMultiplier); + return Pair.of(hungerMultiplier, saturationMultiplier); + } + + public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipContext context) { + var food = stack.getItem().getFoodComponent(); + var ratios = getRatios(stack); + if (food == null || isInedible(ratios)) { + if (stack.getUseAction() != UseAction.DRINK) { + tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.not_edible")).formatted(Formatting.DARK_GRAY)); + } + return; + } + + float baseMultiplier = (isForaged(stack) ? foragingMultiplier() : defaultMultiplier()); + + if (context.isAdvanced()) { + tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.base_multiplier", baseMultiplier).formatted(Formatting.DARK_GRAY))); + tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.hunger.detailed", Math.max(1, (int)(ratios.getFirst() * food.getHunger())), food.getHunger(), (int)(ratios.getFirst() * 100))).formatted(Formatting.DARK_GRAY)); + tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.saturation.detailed", String.format("%.2f", ratios.getSecond() * food.getSaturationModifier()), (int)(ratios.getSecond() * 100))).formatted(Formatting.DARK_GRAY)); + } else { + tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.hunger", (int)(ratios.getFirst() * 100))).formatted(Formatting.DARK_GRAY)); + tooltip.add(Text.literal(" ").append(Text.translatable("unicopia.diet.saturation", (int)(ratios.getSecond() * 100))).formatted(Formatting.DARK_GRAY)); + } } public record Multiplier( diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietView.java b/src/main/java/com/minelittlepony/unicopia/diet/DietView.java new file mode 100644 index 00000000..4d872462 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietView.java @@ -0,0 +1,27 @@ +package com.minelittlepony.unicopia.diet; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.text.Text; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; + +public interface DietView { + TypedActionResult startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand); + + void finishUsing(ItemStack stack, World world, LivingEntity entity); + + void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipContext context); + + interface Holder { + default DietView getDiets(ItemStack stack) { + return PonyDiets.getInstance(); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java index 35801d78..963efb77 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java @@ -40,23 +40,34 @@ public class DietsLoader implements IdentifiableResourceReloadListener { Map profiles = new HashMap<>(); for (var entry : data.entrySet()) { Identifier id = entry.getKey(); - Race.REGISTRY.getOrEmpty(id).ifPresentOrElse(race -> DietProfile.CODEC.parse(JsonOps.INSTANCE, entry.getValue()) - .resultOrPartial(LOGGER::error) - .ifPresent(profile -> profiles.put(race, profile)), () -> LOGGER.warn("Skipped diet for unknown race: " + id)); + try { + Race.REGISTRY.getOrEmpty(id).ifPresentOrElse(race -> { + DietProfile.CODEC.parse(JsonOps.INSTANCE, entry.getValue()) + .resultOrPartial(error -> LOGGER.error("Could not load diet profile {}: {}", id, error)) + .ifPresent(profile -> profiles.put(race, profile)); + }, () -> LOGGER.warn("Skipped diet for unknown race: " + id)); + } catch (Throwable t) { + LOGGER.error("Could not load diet profile {}", id, t); + } } return profiles; - }, applyExecutor); + }, prepareExecutor); - var effectsLoadTask = loadData(manager, prepareExecutor, "diets/food_effects").thenApplyAsync(data -> data.values().stream() - .map(value -> Effect.CODEC.parse(JsonOps.INSTANCE, value) - .resultOrPartial(LOGGER::error)) + var effectsLoadTask = loadData(manager, prepareExecutor, "diets/food_effects").thenApplyAsync(data -> data.entrySet().stream() + .map(entry -> { + try { + return Effect.CODEC.parse(JsonOps.INSTANCE, entry.getValue()) + .resultOrPartial(error -> LOGGER.error("Could not load food effect {}: {}", entry.getKey(), error)); + } catch (Throwable t) { + LOGGER.error("Could not load food effects {}", entry.getKey(), t); + } + return Optional.empty(); + }) .filter(Optional::isPresent) .map(Optional::get) - .toList()); + .toList(), prepareExecutor); - var future = CompletableFuture.allOf(dietsLoadTask, effectsLoadTask); - sync.getClass(); - return future.thenRunAsync(() -> { + return CompletableFuture.allOf(dietsLoadTask, effectsLoadTask).thenCompose(sync::whenPrepared).thenRunAsync(() -> { PonyDiets.load(new PonyDiets( dietsLoadTask.getNow(Map.of()), effectsLoadTask.getNow(List.of()) diff --git a/src/main/java/com/minelittlepony/unicopia/diet/Effect.java b/src/main/java/com/minelittlepony/unicopia/diet/Effect.java index 49a3c249..4d0f1bb4 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/Effect.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/Effect.java @@ -1,56 +1,76 @@ package com.minelittlepony.unicopia.diet; +import java.util.List; import java.util.Optional; import java.util.function.Predicate; +import com.minelittlepony.unicopia.entity.player.Pony; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.item.FoodComponent; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.tag.TagKey; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.UseAction; +import net.minecraft.util.Util; public record Effect( - TagKey tag, + List> tags, Optional foodComponent, Ailment ailment ) implements Predicate { + public static final Effect EMPTY = new Effect(List.of(), Optional.empty(), Ailment.EMPTY); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - TagKey.unprefixedCodec(RegistryKeys.ITEM).fieldOf("tag").forGetter(Effect::tag), - FoodComponent.CODEC.optionalFieldOf("food_component").forGetter(Effect::foodComponent), + TagKey.unprefixedCodec(RegistryKeys.ITEM).listOf().fieldOf("tags").forGetter(Effect::tags), + FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(Effect::foodComponent), Ailment.CODEC.fieldOf("ailment").forGetter(Effect::ailment) ).apply(instance, Effect::new)); public Effect(PacketByteBuf buffer) { - this(TagKey.of(RegistryKeys.ITEM, buffer.readIdentifier()), buffer.readOptional(FoodComponent::new), new Ailment(buffer)); + this(buffer.readList(b -> TagKey.of(RegistryKeys.ITEM, b.readIdentifier())), buffer.readOptional(FoodAttributes::read), new Ailment(buffer)); + } + + public void afflict(Pony pony, ItemStack stack) { + ailment().effects().afflict(pony.asEntity(), stack); + } + + public void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { + int size = tooltip.size(); + tags.forEach(tag -> { + if (stack.isIn(tag)) { + tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("tag", tag.id()))).formatted(Formatting.GRAY)); + } + }); + if (tooltip.size() == size) { + if (stack.isFood()) { + tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.fruits_and_vegetables")).formatted(Formatting.GRAY)); + } else if (stack.getUseAction() == UseAction.DRINK) { + tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.drinks")).formatted(Formatting.GRAY)); + } + } + + if (context.isAdvanced() && stack.isFood()) { + if (!ailment().effects().isEmpty()) { + tooltip.add(Text.translatable("unicopia.diet.side_effects").formatted(Formatting.DARK_PURPLE)); + ailment().effects().appendTooltip(tooltip); + } + } } public void toBuffer(PacketByteBuf buffer) { - buffer.writeIdentifier(tag.id()); - buffer.writeOptional(foodComponent, (b, f) -> f.toBuffer(b)); + buffer.writeCollection(tags, (b, t) -> b.writeIdentifier(t.id())); + buffer.writeOptional(foodComponent, FoodAttributes::write); ailment.toBuffer(buffer); } @Override public boolean test(ItemStack stack) { - return stack.isIn(tag); - } - - public record FoodComponent (float hunger, float saturation) { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codec.FLOAT.fieldOf("hunger").forGetter(FoodComponent::hunger), - Codec.FLOAT.fieldOf("saturation").forGetter(FoodComponent::saturation) - ).apply(instance, FoodComponent::new)); - - public FoodComponent(PacketByteBuf buffer) { - this(buffer.readFloat(), buffer.readFloat()); - } - - public void toBuffer(PacketByteBuf buffer) { - buffer.writeFloat(hunger); - buffer.writeFloat(saturation); - } + return tags.stream().anyMatch(stack::isIn); } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodAttributes.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodAttributes.java new file mode 100644 index 00000000..d1682982 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodAttributes.java @@ -0,0 +1,60 @@ +package com.minelittlepony.unicopia.diet; + +import java.util.List; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.item.FoodComponent; +import net.minecraft.network.PacketByteBuf; + +final class FoodAttributes { + static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("hunger").forGetter(FoodComponent::getHunger), + Codec.FLOAT.fieldOf("saturation").forGetter(FoodComponent::getSaturationModifier), + Codec.BOOL.optionalFieldOf("petFood", false).forGetter(FoodComponent::isMeat), + Codec.BOOL.optionalFieldOf("fastFood", false).forGetter(FoodComponent::isAlwaysEdible), + Codec.BOOL.optionalFieldOf("eatenQuickly", false).forGetter(FoodComponent::isSnack) + ).apply(instance, FoodAttributes::create)); + + static FoodComponent create(int hunger, float saturation, boolean petFood, boolean fastFood, boolean eatenQuickly) { + return create(hunger, saturation, petFood, fastFood, eatenQuickly, List.of()).build(); + } + + static FoodComponent.Builder create(int hunger, float saturation, boolean petFood, boolean fastFood, boolean eatenQuickly, List> effects) { + var builder = new FoodComponent.Builder() + .hunger(hunger) + .saturationModifier(saturation); + if (petFood) { + builder.meat(); + } + if (fastFood) { + builder.alwaysEdible(); + } + if (eatenQuickly) { + builder.snack(); + } + for (var effect : effects) { + builder.statusEffect(effect.getFirst(), effect.getSecond()); + } + return builder; + } + + static FoodComponent.Builder copy(FoodComponent food) { + return create(food.getHunger(), food.getSaturationModifier(), food.isMeat(), food.isAlwaysEdible(), food.isSnack(), food.getStatusEffects()); + } + + static FoodComponent read(PacketByteBuf buffer) { + return create(buffer.readInt(), buffer.readFloat(), buffer.readBoolean(), buffer.readBoolean(), buffer.readBoolean()); + } + + static void write(PacketByteBuf buffer, FoodComponent food) { + buffer.writeInt(food.getHunger()); + buffer.writeFloat(food.getSaturationModifier()); + buffer.writeBoolean(food.isMeat()); + buffer.writeBoolean(food.isAlwaysEdible()); + buffer.writeBoolean(food.isSnack()); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/MultiplyHungerAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/MultiplyHungerAffliction.java deleted file mode 100644 index d503ff7e..00000000 --- a/src/main/java/com/minelittlepony/unicopia/diet/MultiplyHungerAffliction.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.minelittlepony.unicopia.diet; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; - -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.FoodComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.text.Text; - -public record MultiplyHungerAffliction(float multiplier) implements Affliction { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codec.FLOAT.fieldOf("multiplier").forGetter(MultiplyHungerAffliction::multiplier) - ).apply(instance, MultiplyHungerAffliction::new)); - - public MultiplyHungerAffliction(PacketByteBuf buffer) { - this(buffer.readFloat()); - } - - @Override - public void toBuffer(PacketByteBuf buffer) { - buffer.writeFloat(multiplier); - } - - @Override - public AfflictionType getType() { - return AfflictionType.MULTIPLY_HUNGER; - } - - @Override - public void afflict(PlayerEntity player, ItemStack stack) { - FoodComponent food = stack.getItem().getFoodComponent(); - player.getHungerManager().setFoodLevel((int)(food.getHunger() * multiplier)); - player.getHungerManager().setSaturationLevel(food.getSaturationModifier() * multiplier); - } - - @Override - public Text getName() { - return Text.translatable("Lose %s%% hunger", multiplier * 100); - } - -} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java index 5ef1a7e8..a9b5459b 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java @@ -4,20 +4,30 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.diet.DietProfile.Multiplier; -import com.minelittlepony.unicopia.entity.player.Pony; +import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.item.ItemDuck; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; -public class PonyDiets { +public class PonyDiets implements DietView { private final Map diets; private final List effects; - static PonyDiets INSTANCE = new PonyDiets(Map.of(), List.of()); + private static PonyDiets INSTANCE = new PonyDiets(Map.of(), List.of()); - public static PonyDiets getinstance() { + public static PonyDiets getInstance() { return INSTANCE; } @@ -39,19 +49,61 @@ public class PonyDiets { buffer.writeCollection(effects, (b, e) -> e.toBuffer(b)); } - public Optional getDiet(Race race) { - return Optional.ofNullable(diets.get(race)); + private DietProfile getDiet(Pony pony) { + return Optional.ofNullable(diets.get(pony.getObservedSpecies())).orElse(DietProfile.EMPTY); } - public Optional getEffects(ItemStack stack) { - return effects.stream().filter(effect -> effect.test(stack)).findFirst(); + private Effect getEffects(ItemStack stack) { + return effects.stream().filter(effect -> effect.test(stack)).findFirst().orElse(Effect.EMPTY); } - public Optional getEffects(ItemStack stack, Pony pony) { - return getDiet(pony.getObservedSpecies()).flatMap(diet -> diet.findEffect(stack)).or(() -> getEffects(stack)); + private Effect getEffects(ItemStack stack, Pony pony) { + return getDiet(pony).findEffect(stack).orElseGet(() -> getEffects(stack)); } - public Optional getMultiplier(ItemStack stack, Pony pony) { - return getDiet(pony.getObservedSpecies()).flatMap(diet -> diet.findMultiplier(stack)); + @Override + public TypedActionResult startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand) { + return initEdibility(stack, user) + ? FoodPoisoningStatusEffect.apply(stack, user) + : TypedActionResult.fail(stack); + } + + @Override + public void finishUsing(ItemStack stack, World world, LivingEntity entity) { + if (initEdibility(stack, entity)) { + Pony.of(entity).ifPresent(pony -> getEffects(stack, pony).afflict(pony, stack)); + } + } + + @Override + public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipContext context) { + if (initEdibility(stack, user)) { + Pony pony = Pony.of(user); + + tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE)); + getEffects(stack, pony).appendTooltip(stack, tooltip, context); + getDiet(pony).appendTooltip(stack, user, tooltip, context); + } + } + + private boolean initEdibility(ItemStack stack, LivingEntity user) { + ItemDuck item = (ItemDuck)stack.getItem(); + item.resetFoodComponent(); + return Pony.of(user).filter(pony -> { + DietProfile diet = getDiet(pony); + + if (!stack.isFood() && pony.getObservedSpecies().hasIronGut()) { + diet.findEffect(stack) + .flatMap(Effect::foodComponent) + .or(() -> getEffects(stack).foodComponent()) + .ifPresent(item::setFoodComponent); + } + + if (stack.isFood()) { + item.setFoodComponent(diet.getAdjustedFoodComponent(stack)); + } + + return true; + }).isPresent(); } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/Affliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java similarity index 75% rename from src/main/java/com/minelittlepony/unicopia/diet/Affliction.java rename to src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java index d3d69b3b..013d3f51 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/Affliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.diet; +package com.minelittlepony.unicopia.diet.affliction; import java.util.List; @@ -9,19 +9,14 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.dynamic.Codecs; public interface Affliction { - Text NO_EFFECT_TEXT = Text.of("No Effect"); Affliction EMPTY = new Affliction() { @Override public void afflict(PlayerEntity player, ItemStack stack) { } - @Override - public Text getName() { - return NO_EFFECT_TEXT; - } - @Override public AfflictionType getType() { return AfflictionType.EMPTY; @@ -30,11 +25,9 @@ public interface Affliction { @Override public void toBuffer(PacketByteBuf buffer) { } }; - Codec CODEC = Codecs.xor(Codec.list(AfflictionType.CODEC) - .mapResult(null) - .xmap( + Codec CODEC = Codecs.xor(AfflictionType.CODEC, Codec.list(AfflictionType.CODEC).xmap( afflictions -> { - afflictions.removeIf(f -> f.getType() == AfflictionType.EMPTY); + afflictions = afflictions.stream().filter(f -> !f.isEmpty()).toList(); return switch (afflictions.size()) { case 0 -> EMPTY; case 1 -> afflictions.get(0); @@ -42,18 +35,24 @@ public interface Affliction { }; }, affliction -> ((CompoundAffliction)affliction).afflictions - ), AfflictionType.CODEC).xmap( + )).xmap( either -> either.left().or(either::right).get(), affliction -> affliction instanceof CompoundAffliction ? Either.left(affliction) : Either.right(affliction) ); void afflict(PlayerEntity player, ItemStack stack); - default void appendTooltip(List tooltip) { - tooltip.add(getName()); + default boolean isEmpty() { + return getType() == AfflictionType.EMPTY; } - Text getName(); + default void appendTooltip(List tooltip) { + tooltip.add(Text.literal(" ").append(getName()).formatted(Formatting.DARK_GRAY)); + } + + default Text getName() { + return Text.translatable(getType().getTranslationKey()); + } AfflictionType getType(); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/AfflictionType.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/AfflictionType.java similarity index 64% rename from src/main/java/com/minelittlepony/unicopia/diet/AfflictionType.java rename to src/main/java/com/minelittlepony/unicopia/diet/affliction/AfflictionType.java index 5fae39f1..6d9f405f 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/AfflictionType.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/AfflictionType.java @@ -1,14 +1,16 @@ -package com.minelittlepony.unicopia.diet; +package com.minelittlepony.unicopia.diet.affliction; -import com.google.gson.JsonObject; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.util.RegistryUtils; import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; import net.minecraft.network.PacketByteBuf.PacketReader; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; +import net.minecraft.util.Util; import net.minecraft.util.dynamic.Codecs; public record AfflictionType(Codec codec, Identifier id, PacketReader reader) { @@ -16,10 +18,11 @@ public record AfflictionType(Codec codec, Identifier id public static final Registry> REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("affliction_type"), DEFAULT_ID); @SuppressWarnings("unchecked") public static final Codec CODEC = Codecs.JSON_ELEMENT.flatXmap(json -> { - JsonObject obj = json.getAsJsonObject(); - return Identifier.validate(obj.has("type") ? obj.get("type").getAsString() : AfflictionType.DEFAULT_ID).flatMap(type -> { - return AfflictionType.REGISTRY.get(type).codec().parse(JsonOps.INSTANCE, json); - }); + if (!json.isJsonObject()) { + return DataResult.error(() -> "Not a JSON object"); + } + return Identifier.validate(JsonHelper.getString(JsonHelper.asObject(json, "affliction"), "type", AfflictionType.DEFAULT_ID)) + .flatMap(type -> AfflictionType.REGISTRY.get(type).codec().parse(JsonOps.INSTANCE, json)); }, thing -> { AfflictionType type = thing.getType(); return ((Codec)type.codec()).encodeStart(JsonOps.INSTANCE, thing).map(json -> { @@ -33,12 +36,17 @@ public record AfflictionType(Codec codec, Identifier id public static final AfflictionType EMPTY = register("empty", Codec.unit(Affliction.EMPTY), buffer -> Affliction.EMPTY); public static final AfflictionType MANY = register("many", CompoundAffliction.CODEC, CompoundAffliction::new); public static final AfflictionType APPLY_STATUS_EFFECT = register("apply_status_effect", StatusEffectAffliction.CODEC, StatusEffectAffliction::new); - public static final AfflictionType MULTIPLY_HUNGER = register("multiply_hunger", MultiplyHungerAffliction.CODEC, MultiplyHungerAffliction::new); - public static final AfflictionType CLEAR_LOVE_SICKNESS = register("clear_love_sickness", ClearLoveSicknessAffliction.CODEC, buffer -> ClearLoveSicknessAffliction.INSTANCE); + public static final AfflictionType LOSE_HUNGER = register("lose_hunger", LoseHungerAffliction.CODEC, LoseHungerAffliction::new); + public static final AfflictionType HEALING = register("healing", HealingAffliction.CODEC, HealingAffliction::new); + public static final AfflictionType CURE_LOVE_SICKNESS = register("cure_love_sickness", ClearLoveSicknessAffliction.CODEC, buffer -> ClearLoveSicknessAffliction.INSTANCE); static AfflictionType register(String name, Codec codec, PacketReader reader) { return Registry.register(REGISTRY, Unicopia.id(name), new AfflictionType<>(codec, Unicopia.id(name), reader)); } + public String getTranslationKey() { + return Util.createTranslationKey("affliction", id()); + } + public static void bootstrap() { } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/ClearLoveSicknessAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java similarity index 76% rename from src/main/java/com/minelittlepony/unicopia/diet/ClearLoveSicknessAffliction.java rename to src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java index 17bbea7d..79343432 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/ClearLoveSicknessAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.diet; +package com.minelittlepony.unicopia.diet.affliction; import com.minelittlepony.unicopia.entity.effect.UEffects; import com.mojang.serialization.Codec; @@ -6,15 +6,14 @@ import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; -import net.minecraft.text.Text; -public final class ClearLoveSicknessAffliction implements Affliction { +final class ClearLoveSicknessAffliction implements Affliction { public static final ClearLoveSicknessAffliction INSTANCE = new ClearLoveSicknessAffliction(); public static final Codec CODEC = Codec.unit(INSTANCE); @Override public AfflictionType getType() { - return AfflictionType.CLEAR_LOVE_SICKNESS; + return AfflictionType.CURE_LOVE_SICKNESS; } @Override @@ -24,11 +23,6 @@ public final class ClearLoveSicknessAffliction implements Affliction { player.removeStatusEffect(UEffects.FOOD_POISONING); } - @Override - public Text getName() { - return Text.literal("Love"); - } - @Override public void toBuffer(PacketByteBuf buffer) { } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/CompoundAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java similarity index 89% rename from src/main/java/com/minelittlepony/unicopia/diet/CompoundAffliction.java rename to src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java index ba04a0db..d41cf4ad 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/CompoundAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.diet; +package com.minelittlepony.unicopia.diet.affliction; import java.util.List; @@ -32,6 +32,11 @@ class CompoundAffliction implements Affliction { return AfflictionType.MANY; } + @Override + public boolean isEmpty() { + return afflictions.isEmpty(); + } + @Override public void appendTooltip(List tooltip) { afflictions.forEach(i -> i.appendTooltip(tooltip)); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java new file mode 100644 index 00000000..71590879 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java @@ -0,0 +1,39 @@ +package com.minelittlepony.unicopia.diet.affliction; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; + +record HealingAffliction(float health) implements Affliction { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.FLOAT.fieldOf("health").forGetter(HealingAffliction::health) + ).apply(instance, HealingAffliction::new)); + + public HealingAffliction(PacketByteBuf buffer) { + this(buffer.readFloat()); + } + + @Override + public void toBuffer(PacketByteBuf buffer) { + buffer.writeFloat(health); + } + + @Override + public AfflictionType getType() { + return AfflictionType.HEALING; + } + + @Override + public void afflict(PlayerEntity player, ItemStack stack) { + player.heal(health()); + } + + @Override + public Text getName() { + return Text.translatable(getType().getTranslationKey(), health()); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/LoseHungerAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/LoseHungerAffliction.java new file mode 100644 index 00000000..fe9ff84f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/LoseHungerAffliction.java @@ -0,0 +1,41 @@ +package com.minelittlepony.unicopia.diet.affliction; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; + +public record LoseHungerAffliction(float multiplier) implements Affliction { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.FLOAT.fieldOf("multiplier").forGetter(LoseHungerAffliction::multiplier) + ).apply(instance, LoseHungerAffliction::new)); + + public LoseHungerAffliction(PacketByteBuf buffer) { + this(buffer.readFloat()); + } + + @Override + public void toBuffer(PacketByteBuf buffer) { + buffer.writeFloat(multiplier); + } + + @Override + public AfflictionType getType() { + return AfflictionType.LOSE_HUNGER; + } + + @Override + public void afflict(PlayerEntity player, ItemStack stack) { + var hunger = player.getHungerManager(); + hunger.setFoodLevel((int)(hunger.getFoodLevel() * multiplier)); + hunger.setSaturationLevel(hunger.getSaturationLevel() * multiplier); + } + + @Override + public Text getName() { + return Text.translatable(getType().getTranslationKey(), multiplier * 100); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/Range.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java similarity index 75% rename from src/main/java/com/minelittlepony/unicopia/diet/Range.java rename to src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java index 5b33c3a8..dfe7e009 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/Range.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.diet; +package com.minelittlepony.unicopia.diet.affliction; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; @@ -7,7 +7,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.dynamic.Codecs; -public record Range(int min, int max) { +record Range(int min, int max) { public static final Codec CODEC = Codecs.xor( Codec.INT.xmap(value -> Range.of(value, -1), range -> range.min()), RecordCodecBuilder.create(instance -> instance.group( @@ -29,11 +29,11 @@ public record Range(int min, int max) { buffer.writeInt(max); } - public int getTicks(int currentTicks) { - return clamp((min * 20) + currentTicks); + public int getClamped(int currentTicks, int multiplier) { + return clamp((min * multiplier) + currentTicks, multiplier); } - public int clamp(int value) { - return max > 0 ? Math.min(value, max * 20) : value; + public int clamp(int value, int multiplier) { + return max > 0 ? Math.min(value, max * multiplier) : value; } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/diet/StatusEffectAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java similarity index 86% rename from src/main/java/com/minelittlepony/unicopia/diet/StatusEffectAffliction.java rename to src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java index 9005b5dc..d0c0b91c 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/StatusEffectAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.diet; +package com.minelittlepony.unicopia.diet.affliction; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -15,7 +15,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.StringHelper; import net.minecraft.util.math.MathHelper; -public record StatusEffectAffliction(Identifier effect, Range seconds, Range amplifier, int chance) implements Affliction { +record StatusEffectAffliction(Identifier effect, Range seconds, Range amplifier, int chance) implements Affliction { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Identifier.CODEC.fieldOf("effect").forGetter(StatusEffectAffliction::effect), Range.CODEC.fieldOf("seconds").forGetter(StatusEffectAffliction::seconds), @@ -27,6 +27,7 @@ public record StatusEffectAffliction(Identifier effect, Range seconds, Range amp this(buffer.readIdentifier(), Range.of(buffer), Range.of(buffer), buffer.readInt()); } + @Override public void toBuffer(PacketByteBuf buffer) { buffer.writeIdentifier(effect); seconds.toBuffer(buffer); @@ -48,8 +49,8 @@ public record StatusEffectAffliction(Identifier effect, Range seconds, Range amp float health = player.getHealth(); StatusEffectInstance current = player.getStatusEffect(effect); player.addStatusEffect(new StatusEffectInstance(effect, - seconds.getTicks(current == null ? 0 : current.getDuration()), - amplifier.getTicks(current == null ? 0 : current.getAmplifier()) + seconds.getClamped(current == null ? 0 : current.getDuration(), 20), + amplifier.getClamped(current == null ? 0 : current.getAmplifier(), 1) )); // keep original health if (effect.getAttributeModifiers().containsKey(EntityAttributes.GENERIC_MAX_HEALTH)) { @@ -64,7 +65,7 @@ public record StatusEffectAffliction(Identifier effect, Range seconds, Range amp MutableText text = effect.getName().copy(); if (amplifier.min() > 0) { - text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + (amplifier.min() * 20))); + text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + (amplifier.min()))); } text = Text.translatable("potion.withDuration", text, StringHelper.formatTicks(seconds.min() * 20)); @@ -73,6 +74,6 @@ public record StatusEffectAffliction(Identifier effect, Range seconds, Range amp text = Text.translatable("potion.withChance", chance, text); } return (Text)text; - }).orElse(Text.of("No Effect")); + }).orElse(EMPTY.getName()); } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java b/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java new file mode 100644 index 00000000..ee280da5 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemDuck.java @@ -0,0 +1,16 @@ +package com.minelittlepony.unicopia.item; + +import java.util.Optional; + +import com.minelittlepony.unicopia.entity.ItemImpl; +import net.minecraft.item.*; + +public interface ItemDuck extends ItemConvertible, ItemImpl.TickableItem { + void setFoodComponent(FoodComponent food); + + Optional getOriginalFoodComponent(); + + default void resetFoodComponent() { + setFoodComponent(getOriginalFoodComponent().orElse(null)); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java similarity index 98% rename from src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java rename to src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java index 4d71bd2f..24dcf544 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.item.toxin; +package com.minelittlepony.unicopia.item; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 97c99e4e..e9863be6 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -12,7 +12,6 @@ import com.minelittlepony.unicopia.item.cloud.CloudBedItem; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.item.group.UItemGroups; -import com.minelittlepony.unicopia.item.toxin.UFoodComponents; import com.terraformersmc.terraform.boat.api.TerraformBoatType; import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; import com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper; diff --git a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java index 9d104e56..711cbec8 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java @@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.group.MultiItem; -import com.minelittlepony.unicopia.item.toxin.*; import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.util.TraceHelper; @@ -36,7 +35,7 @@ import net.minecraft.registry.Registries; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; -public class ZapAppleItem extends Item implements ChameleonItem, ToxicHolder, MultiItem { +public class ZapAppleItem extends Item implements ChameleonItem, MultiItem { public ZapAppleItem(Settings settings) { super(settings); } @@ -117,12 +116,6 @@ public class ZapAppleItem extends Item implements ChameleonItem, ToxicHolder, Mu return hasAppearance(stack) ? getAppearanceStack(stack).getName() : super.getName(stack); } - @SuppressWarnings("deprecation") - @Override - public Toxic getToxic(ItemStack stack, LivingEntity entity) { - return hasAppearance(stack) ? Toxic.SEVERE_INNERT : Toxics.FORAGE_EDIBLE; - } - @Override public Rarity getRarity(ItemStack stack) { if (hasAppearance(stack)) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Affliction.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Affliction.java deleted file mode 100644 index f2350be5..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Affliction.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; - -public interface Affliction { - void afflict(PlayerEntity player, ItemStack stack); - - interface Predicate { - boolean test(PlayerEntity player, ItemStack stack); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java deleted file mode 100644 index 0fa02187..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import java.util.*; - -import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.entity.player.Pony; -import net.minecraft.client.item.TooltipContext; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.Text; - -public record Ailment ( - Toxicity toxicity, - Toxin effect - ) { - public static final Ailment INNERT = of(Toxicity.SAFE, Toxin.INNERT); - - @Deprecated - public static Ailment of(Toxicity toxicity, Toxin effect) { - return new Ailment(toxicity, effect); - } - - public void appendTooltip(List tooltip, TooltipContext context) { - tooltip.add(toxicity().getTooltip()); - if (context.isAdvanced()) { - effect().appendTooltip(tooltip); - } - } - - public interface Set { - Set EMPTY = e -> Optional.empty(); - - Optional get(LivingEntity entity); - - static Ailment.Set of(Ailment def, Map map) { - if (map.isEmpty()) { - return of(def); - } - return entity -> Optional.of(entity instanceof PlayerEntity player ? map.getOrDefault(Pony.of(player).getObservedSpecies(), def) : def); - } - - static Ailment.Set of(Ailment ailment) { - final Optional value = Optional.of(ailment); - return entity -> value; - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/ItemDuck.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/ItemDuck.java deleted file mode 100644 index 4ff27425..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/ItemDuck.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import com.minelittlepony.unicopia.entity.ItemImpl; - -import net.minecraft.item.*; - -public interface ItemDuck extends ItemConvertible, ToxicHolder, ItemImpl.TickableItem { - void setFoodComponent(FoodComponent food); -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java deleted file mode 100644 index d2810839..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import static com.minelittlepony.unicopia.item.toxin.Toxicity.FAIR; -import static com.minelittlepony.unicopia.item.toxin.Toxicity.SEVERE; -import java.util.*; -import java.util.function.Function; - -import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect; -import com.minelittlepony.unicopia.entity.player.Pony; -import net.minecraft.client.item.TooltipContext; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.FoodComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.util.UseAction; -import net.minecraft.world.World; - -public record Toxic ( - Optional useAction, - Function> food, - Ailment.Set ailment - ) { - public static final Toxic EMPTY = new Toxic(Optional.empty(), entity -> Optional.empty(), Ailment.Set.EMPTY); - /** - * Default for all food that doesn't have a mapping - */ - @Deprecated - public static final Toxic DEFAULT = new Toxic.Builder(Ailment.INNERT) - .with(Race.CHANGELING, new Ailment(FAIR, Toxin.LOVE_SICKNESS)) - .with(Race.SEAPONY, new Ailment(FAIR, Toxin.FOOD_POISONING)) - .build(); - - public static final Toxic SEVERE_INNERT = new Builder(new Ailment(SEVERE, Toxin.INNERT)).build(); - - public void appendTooltip(PlayerEntity player, List tooltip, TooltipContext context) { - ailment.get(player).ifPresent(ailment -> ailment.appendTooltip(tooltip, context)); - } - - public TypedActionResult startUsing(ItemStack stack, World world, PlayerEntity user, Hand hand) { - if (stack.getItem() instanceof BlockItem && ailment().get(user).isPresent() && !Pony.of(user).getObservedSpecies().hasIronGut()) { - return TypedActionResult.fail(stack); - } - return FoodPoisoningStatusEffect.apply(stack, user); - } - - public void finishUsing(ItemStack stack, World world, LivingEntity entity) { - if (entity instanceof PlayerEntity player) { - ailment.get(entity).ifPresent(ailment -> ailment.effect().afflict(player, stack)); - } - if (stack.isFood() || stack.getUseAction() == UseAction.DRINK) { - Pony.of(entity).ifPresent(pony -> pony.onEat(stack)); - } - } - - @Deprecated - public static class Builder { - private final Ailment def; - private final Map overrides = new HashMap<>(); - private Optional action = Optional.of(UseAction.EAT); - private final Map components = new HashMap<>(); - private Optional component = Optional.empty(); - - public Builder(Ailment def) { - this.def = def; - } - - public Builder action(UseAction action) { - this.action = Optional.of(action); - return this; - } - - public Builder food(FoodComponent food) { - component = Optional.ofNullable(food); - return this; - } - - public Builder food(Race race, FoodComponent food) { - components.put(race, food); - return this; - } - - public Builder with(Race race, Ailment ailment) { - overrides.put(race, ailment); - return this; - } - - public Builder with(Ailment ailment, Race... races) { - for (Race race : races) { - overrides.put(race, ailment); - } - return this; - } - - public Toxic build() { - return new Toxic(action, entity -> { - if (entity instanceof PlayerEntity player) { - return Optional.ofNullable(components.get(Pony.of(player).getObservedSpecies())).or(() -> component); - } - return component; - }, Ailment.Set.of(def, overrides)); - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java deleted file mode 100644 index a873170c..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.*; - -public interface ToxicHolder { - Toxic getToxic(ItemStack stack, @Nullable LivingEntity entity); -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicRegistryEntry.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicRegistryEntry.java deleted file mode 100644 index 7c4e51ba..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicRegistryEntry.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import net.minecraft.item.Item; -import net.minecraft.registry.tag.TagKey; - -@Deprecated -public record ToxicRegistryEntry ( - Toxic value, - TagKey tag - ) { - - public boolean matches(Item item) { - return item.getRegistryEntry().isIn(tag); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java deleted file mode 100644 index 43355b79..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import java.util.Arrays; -import java.util.Locale; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.StringIdentifiable; - -public enum Toxicity implements StringIdentifiable { - SAFE(Formatting.GRAY), - MILD(Formatting.DARK_AQUA), - FAIR(Formatting.DARK_BLUE), - SEVERE(Formatting.DARK_PURPLE), - LETHAL(Formatting.RED); - - private static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Toxicity::name, Function.identity())); - @SuppressWarnings("deprecation") - public static final Codec CODEC = StringIdentifiable.createCodec(Toxicity::values); - - private final Formatting color; - private final String name = name().toLowerCase(Locale.ROOT); - - Toxicity(Formatting color) { - this.color = color; - } - - public String getTranslationKey() { - return String.format("toxicity.%s.name", name().toLowerCase()); - } - - public Text getTooltip() { - return Text.translatable(getTranslationKey()).formatted(color); - } - - public static Toxicity byName(String name) { - return REGISTRY.get(name.toUpperCase()); - } - - @Override - public String asString() { - return name; - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java deleted file mode 100644 index 30e0a97f..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import com.minelittlepony.unicopia.*; -import com.minelittlepony.unicopia.util.RegistryUtils; - -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.FoodComponent; -import net.minecraft.registry.Registry; - -import static com.minelittlepony.unicopia.item.toxin.Toxicity.*; -import static com.minelittlepony.unicopia.item.toxin.Ailment.*; -import static com.minelittlepony.unicopia.item.toxin.Toxin.*; - -import org.jetbrains.annotations.Nullable; - -@Deprecated -public interface Toxics { - Registry REGISTRY = RegistryUtils.createSimple(Unicopia.id("toxic")); - Toxic FORAGE_EDIBLE = register("forage_edible", new Toxic.Builder(Ailment.INNERT).food(UFoodComponents.RANDOM_FOLIAGE).with(Race.HUMAN, of(LETHAL, FOOD_POISONING)).with(Race.CHANGELING, of(FAIR, LOVE_SICKNESS)).with(Race.SEAPONY, of(FAIR, FOOD_POISONING))); - - static void bootstrap() { - register("forage_edible_filling", new Toxic.Builder(Ailment.INNERT).food(UFoodComponents.RANDOM_FOLIAGE_FILLING).with(Race.CHANGELING, of(FAIR, LOVE_SICKNESS)).with(Race.SEAPONY, of(FAIR, FOOD_POISONING))); - register("forage_risky", new Toxic.Builder(of(FAIR, FOOD_POISONING.withChance(20))).food(UFoodComponents.RANDOM_FOLIAGE)); - register("forage_moderate", new Toxic.Builder(of(MILD, FOOD_POISONING)).food(UFoodComponents.RANDOM_FOLIAGE)); - register("forage_dangerous", new Toxic.Builder(of(SEVERE, FOOD_POISONING)).food(UFoodComponents.RANDOM_FOLIAGE)); - register("forage_nauseating", new Toxic.Builder(of(SAFE, FOOD_POISONING.and(WEAKNESS.withChance(30)))).food(UFoodComponents.RANDOM_FOLIAGE)); - register("forage_radioactive", new Toxic.Builder(of(SAFE, FOOD_POISONING.and(GLOWING.withChance(30)))).food(UFoodComponents.RANDOM_FOLIAGE)); - register("forage_prickly", new Toxic.Builder(of(SAFE, INSTANT_DAMAGE.withChance(30))).food(UFoodComponents.RANDOM_FOLIAGE).with(Ailment.INNERT, Race.HIPPOGRIFF, Race.KIRIN)); - register("forage_strengthening", new Toxic.Builder(of(SEVERE, STRENGTH.and(FOOD_POISONING))).food(UFoodComponents.RANDOM_FOLIAGE).with(Race.KIRIN, Ailment.INNERT)); - register("forage_severely_nauseating", new Toxic.Builder(of(SEVERE, FOOD_POISONING.and(WEAKNESS))).food(UFoodComponents.RANDOM_FOLIAGE)); - register("forage_blinding", new Toxic.Builder(of(SEVERE, BLINDNESS.and(FOOD_POISONING))).food(UFoodComponents.RANDOM_FOLIAGE).with(Race.KIRIN, Ailment.INNERT)); - register("forage_severely_prickly", new Toxic.Builder(of(SEVERE, FOOD_POISONING.and(INSTANT_DAMAGE))).food(UFoodComponents.RANDOM_FOLIAGE).with(Race.KIRIN, Ailment.INNERT)); - register("raw_meat", new Toxic.Builder(of(SEVERE, FOOD_POISONING.withChance(5).and(CHANCE_OF_POISON))).with(Ailment.INNERT, Race.HUMAN, Race.CHANGELING, Race.KIRIN).with(of(MILD, FOOD_POISONING), Race.BAT)); - register("rotten_meat", new Toxic.Builder(of(SEVERE, STRONG_FOOD_POISONING)).with(Ailment.INNERT, Race.HUMAN, Race.CHANGELING).with(of(MILD, FOOD_POISONING), Race.BAT)); - register("cooked_meat", new Toxic.Builder(of(FAIR, FOOD_POISONING)).with(Ailment.INNERT, Race.HUMAN, Race.CHANGELING, Race.BAT, Race.KIRIN).with(of(MILD, FOOD_POISONING), Race.HIPPOGRIFF)); - register("raw_fish", new Toxic.Builder(of(FAIR, FOOD_POISONING.and(CHANCE_OF_POISON))).with(Ailment.INNERT, Race.HUMAN, Race.HIPPOGRIFF, Race.SEAPONY, Race.ALICORN).with(of(MILD, FOOD_POISONING), Race.PEGASUS).with(of(FAIR, LOVE_SICKNESS), Race.CHANGELING)); - register("cooked_fish", new Toxic.Builder(of(MILD, FOOD_POISONING)).with(Ailment.INNERT, Race.HUMAN, Race.PEGASUS, Race.HIPPOGRIFF, Race.SEAPONY, Race.ALICORN).with(of(FAIR, LOVE_SICKNESS), Race.CHANGELING)); - register("raw_insect", new Toxic.Builder(of(LETHAL, FOOD_POISONING)).food(UFoodComponents.INSECTS).with(Ailment.INNERT, Race.CHANGELING).with(of(MILD, WEAK_FOOD_POISONING), Race.BAT)); - register("cooked_insect", new Toxic.Builder(of(LETHAL, FOOD_POISONING)).food(UFoodComponents.INSECTS).with(Ailment.INNERT, Race.CHANGELING, Race.KIRIN, Race.BAT)); - register("love", new Toxic.Builder(Ailment.INNERT).with(of(Toxicity.SAFE, Toxin.LOVE_CONSUMPTION), Race.CHANGELING)); - register("bat_ponys_delight", new Toxic.Builder(Ailment.INNERT).with(of(Toxicity.SAFE, Toxin.BAT_PONY_INTOXICATION), Race.BAT)); - register("raw_sea_vegitable", new Toxic.Builder(Ailment.INNERT).food(Race.SEAPONY, UFoodComponents.RANDOM_FOLIAGE)); - register("cooked_sea_vegitable", new Toxic.Builder(Ailment.INNERT).food(Race.SEAPONY, UFoodComponents.RANDOM_FOLIAGE_FILLING)); - register("shells", new Toxic.Builder(Ailment.INNERT).food(Race.SEAPONY, UFoodComponents.SHELL)); - register("shelly", new Toxic.Builder(Ailment.INNERT).food(Race.SEAPONY, UFoodComponents.SHELLY)); - register("pinecone", new Toxic.Builder(of(Toxicity.SAFE, Toxin.healing(1))).with(Ailment.INNERT, Race.HUMAN).with(of(Toxicity.SAFE, Toxin.healing(3)), Race.HIPPOGRIFF)); - } - - static Toxic register(String name, Toxic.Builder builder) { - return Registry.register(REGISTRY, Unicopia.id(name), new ToxicRegistryEntry(builder.build(), UTags.item("food_types/" + name))).value(); - } - - static Toxic lookup(ItemDuck item, @Nullable LivingEntity entity) { - @Nullable FoodComponent food = item.asItem().getFoodComponent(); - return REGISTRY.stream() - .filter(i -> i.matches(item.asItem())) - .map(ToxicRegistryEntry::value) - .map(t -> { - if (food == null) { - t.food().apply(entity).ifPresent(item::setFoodComponent); - } - return t; - }).findFirst().orElse(food == null ? Toxic.EMPTY : Toxic.DEFAULT); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java deleted file mode 100644 index 6866a7b8..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -import java.util.List; - -import com.minelittlepony.unicopia.entity.effect.UEffects; -import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.entity.effect.StatusEffects; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.FoodComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.StringHelper; -import net.minecraft.util.math.MathHelper; - -public interface Toxin extends Affliction { - Toxin INNERT = of(Text.of("No Effect"), (player, stack) -> {}); - @Deprecated - Toxin INSTANT_DAMAGE = of(StatusEffects.INSTANT_DAMAGE, 1, 0); - @Deprecated - Toxin GLOWING = of(StatusEffects.GLOWING, 15, 0); - @Deprecated - Toxin WEAKNESS = of(StatusEffects.WEAKNESS, 200, 1); - @Deprecated - Toxin STRENGTH = of(StatusEffects.STRENGTH, 30, 0); - @Deprecated - Toxin BLINDNESS = of(StatusEffects.BLINDNESS, 30, 0); - @Deprecated - Toxin CHANCE_OF_POISON = of(StatusEffects.POISON, 45, 2).withChance(80); - @Deprecated - Toxin FOOD_POISONING = of(UEffects.FOOD_POISONING, 100, 2); - @Deprecated - Toxin WEAK_FOOD_POISONING = of(UEffects.FOOD_POISONING, 50, 1); - @Deprecated - Toxin STRONG_FOOD_POISONING = of(UEffects.FOOD_POISONING, 400, 3); - - @Deprecated - Toxin LOVE_SICKNESS = of(Text.of("Love Sickness "), (player, stack) -> { - FoodComponent food = stack.getItem().getFoodComponent(); - player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2); - }).and(FOOD_POISONING).and(WEAKNESS); - - @Deprecated - Toxin LOVE_CONSUMPTION = of(Text.literal("Love"), (player, stack) -> { - player.heal(stack.isFood() ? stack.getItem().getFoodComponent().getHunger() : 1); - player.removeStatusEffect(StatusEffects.NAUSEA); - player.removeStatusEffect(UEffects.FOOD_POISONING); - }); - - @Deprecated - Toxin BAT_PONY_INTOXICATION = Toxin.of(StatusEffects.HEALTH_BOOST, 30, 60, 2, 6) - .and(Toxin.of(StatusEffects.JUMP_BOOST, 30, 60, 1, 6)) - .and(Toxin.of(StatusEffects.SPEED, 30, 30, 1, 6)) - .and(Toxin.of(StatusEffects.REGENERATION, 3, 30, 3, 6)); - - @Deprecated - static Toxin healing(int hearts) { - return of(Text.literal("Healing " + hearts + " Hearts"), (player, stack) -> player.heal(hearts)); - } - - default void appendTooltip(List tooltip) { - tooltip.add(getName()); - } - - @Deprecated - default Toxin withChance(int max) { - return Predicate.of(Text.of("1 in " + max + " chance of "), (player, stack) -> player.getWorld().random.nextInt(max) == 0).then(this); - } - - Text getName(); - - @Deprecated - default Toxin and(Toxin other) { - Toxin self = this; - return new Toxin() { - @Override - public void afflict(PlayerEntity player, ItemStack stack) { - self.afflict(player, stack); - other.afflict(player, stack); - } - - @Override - public void appendTooltip(List tooltip) { - self.appendTooltip(tooltip); - other.appendTooltip(tooltip); - } - - @Override - public Text getName() { - return self.getName().copy().append(" + ").append(other.getName()); - } - }; - } - - static Toxin of(Text name, Affliction affliction) { - return new Toxin() { - @Override - public void afflict(PlayerEntity player, ItemStack stack) { - affliction.afflict(player, stack); - } - - @Override - public Text getName() { - return name; - } - }; - } - - @Deprecated - static Toxin of(StatusEffect effect, int seconds, int amplifier) { - return of(effect, seconds, -1, amplifier, -1); - } - - static Toxin of(StatusEffect effect, int seconds, int maxSeconds, int amplifier, int maxAmplifier) { - final int ticks = seconds * 20; - final int maxTicks = maxSeconds * 20; - - MutableText text = effect.getName().copy(); - - if (amplifier > 0) { - text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + amplifier)); - } - - text = Text.translatable("potion.withDuration", text, StringHelper.formatTicks(ticks)); - - return of(text, (player, stack) -> { - float health = player.getHealth(); - StatusEffectInstance current = player.getStatusEffect(effect); - int t = applyLimit(ticks + (current == null ? 0 : current.getDuration()), maxTicks); - int a = applyLimit(amplifier + (current == null ? 0 : current.getAmplifier()), maxAmplifier); - player.addStatusEffect(new StatusEffectInstance(effect, t, a)); - // keep original health - if (effect.getAttributeModifiers().containsKey(EntityAttributes.GENERIC_MAX_HEALTH)) { - player.setHealth(MathHelper.clamp(health, 0, player.getMaxHealth())); - } - }); - } - - private static int applyLimit(int value, int max) { - return max > 0 ? Math.min(value, max) : value; - } - - interface Predicate { - static Predicate of(Text name, Affliction.Predicate predicate) { - return new Predicate() { - @Override - public boolean test(PlayerEntity player, ItemStack stack) { - return predicate.test(player, stack); - } - - @Override - public Text getName() { - return name; - } - }; - } - - boolean test(PlayerEntity player, ItemStack stack); - - Text getName(); - - default Toxin then(Toxin toxin) { - return new Toxin() { - @Override - public void afflict(PlayerEntity player, ItemStack stack) { - if (test(player, stack)) { - toxin.afflict(player, stack); - } - } - - @Override - public Text getName() { - return Predicate.this.getName().copy().append(toxin.getName()); - } - }; - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java index 5cb06970..c7970a50 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java @@ -5,24 +5,21 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.minelittlepony.unicopia.item.toxin.ToxicHolder; import com.minelittlepony.unicopia.server.world.WaterLoggingManager; import net.minecraft.block.BlockState; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemPlacementContext; -import net.minecraft.item.ItemStack; -import net.minecraft.util.UseAction; @Mixin(BlockItem.class) -abstract class MixinBlockItem extends Item implements ToxicHolder { +abstract class MixinBlockItem extends Item { MixinBlockItem() {super(null); } - @Override + /*@Override public UseAction getUseAction(ItemStack stack) { - return getToxic(stack, null).useAction().orElseGet(() -> super.getUseAction(stack)); - } + return PonyDiets.getinstance().getUseAction(stack).orElseGet(() -> super.getUseAction(stack)); + }*/ @Inject(method = "getPlacementState", at = @At("RETURN"), cancellable = true) private void onGetPlacementState(ItemPlacementContext context, CallbackInfoReturnable info) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java index 5670dbbe..cad3a18e 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java @@ -2,26 +2,26 @@ package com.minelittlepony.unicopia.mixin; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.Supplier; -import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; import com.google.common.base.Suppliers; +import com.minelittlepony.unicopia.diet.DietView; import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.entity.ItemImpl.GroundTickCallback; -import com.minelittlepony.unicopia.item.toxin.*; - -import net.minecraft.entity.LivingEntity; +import com.minelittlepony.unicopia.item.ItemDuck; import net.minecraft.item.FoodComponent; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; @Mixin(Item.class) -abstract class MixinItem implements ItemDuck { +abstract class MixinItem implements ItemDuck, DietView.Holder { private final List tickCallbacks = new ArrayList<>(); - private final Supplier originalFoodComponent = Suppliers.memoize(((Item)(Object)this)::getFoodComponent); + private final Supplier> originalFoodComponent = Suppliers.memoize(() -> { + return Optional.ofNullable(((Item)(Object)this).getFoodComponent()); + }); @Override public List getCallbacks() { @@ -34,10 +34,7 @@ abstract class MixinItem implements ItemDuck { public abstract void setFoodComponent(FoodComponent food); @Override - public Toxic getToxic(ItemStack stack, @Nullable LivingEntity entity) { - if (entity != null) { - setFoodComponent(originalFoodComponent.get()); - } - return Toxics.lookup(this, entity); + public Optional getOriginalFoodComponent() { + return originalFoodComponent.get(); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java index 118f1b4c..35658fea 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java @@ -5,8 +5,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.minelittlepony.unicopia.item.toxin.ToxicHolder; - +import com.minelittlepony.unicopia.diet.DietView; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; @@ -20,7 +19,7 @@ abstract class MixinItemStack { @Inject(method = "use", at = @At("HEAD"), cancellable = true) private void onUse(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> info) { ItemStack self = (ItemStack)(Object)this; - TypedActionResult result = ((ToxicHolder)self.getItem()).getToxic(self, user).startUsing(self, world, user, hand); + TypedActionResult result = ((DietView.Holder)self.getItem()).getDiets(self).startUsing(self, world, user, hand); if (result.getResult() != ActionResult.PASS) { info.setReturnValue(result); } @@ -29,6 +28,6 @@ abstract class MixinItemStack { @Inject(method = "finishUsing", at = @At("HEAD")) private void onFinishUsing(World world, LivingEntity user, CallbackInfoReturnable info) { ItemStack self = (ItemStack)(Object)this; - ((ToxicHolder)self.getItem()).getToxic(self, user).finishUsing(self, world, user); + ((DietView.Holder)self.getItem()).getDiets(self).finishUsing(self, world, user); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java deleted file mode 100644 index 9918c27c..00000000 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.minelittlepony.unicopia.mixin.client; - -import java.util.List; -import org.jetbrains.annotations.Nullable; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.minelittlepony.unicopia.item.toxin.ToxicHolder; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.item.TooltipContext; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.world.World; - -@Mixin(Item.class) -abstract class MixinItem implements ToxicHolder { - @Inject(method = "appendTooltip", at = @At("RETURN")) - private void onAppendTooltip(ItemStack stack, @Nullable World world, List tooltip, TooltipContext context, CallbackInfo into) { - getToxic(stack, MinecraftClient.getInstance().player).appendTooltip(MinecraftClient.getInstance().player, tooltip, context); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemStack.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemStack.java new file mode 100644 index 00000000..81a3b67f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItemStack.java @@ -0,0 +1,24 @@ +package com.minelittlepony.unicopia.mixin.client; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.diet.DietView; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.text.Text; + +@Mixin(ItemStack.class) +abstract class MixinItemStack { + @Inject(method = "getTooltip", at = @At("RETURN")) + private void onGetTooltip(@Nullable PlayerEntity player, TooltipContext context, CallbackInfoReturnable> info) { + ItemStack self = (ItemStack)(Object)this; + ((DietView.Holder)self.getItem()).getDiets(self).appendTooltip(self, player, info.getReturnValue(), context); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java b/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java index dd3d8a27..715a0180 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java @@ -24,7 +24,7 @@ public record MsgServerResources ( SpellTraits.all(), SpellbookChapterLoader.INSTANCE.getChapters(), TreeTypeLoader.INSTANCE.getEntries(), - PonyDiets.getinstance() + PonyDiets.getInstance() ); } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 12db0baf..33c35b1e 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -469,11 +469,57 @@ "trait.unicopia.poison.name": "Poison", "trait.unicopia.poison.description": "A deadly dart kill a beast.", + "unicopia.diet.information": "Diet Information:", + "unicopia.diet.side_effects": "Side-Effects:", + "unicopia.diet.not_edible": "Item is not edible", + "unicopia.diet.base_multiplier": "Base Multiplier: %s%%", + "unicopia.diet.hunger.detailed": "Hunger gained: %s of %s (%s%%)", + "unicopia.diet.saturation.detailed": "Saturation gained: %s (%s%%)", + "unicopia.diet.hunger": "Hunger Ratio: %s%%", + "unicopia.diet.saturation": "Saturation Ratio: %s%%", + + "tag.unicopia.food_types.rotten_meat": "Rotting Meat", + "tag.unicopia.food_types.raw_meat": "Fresh Meat", + "tag.unicopia.food_types.cooked_meat": "Prepared Meat", + "tag.unicopia.food_types.raw_fish": "Fresh Fish", + "tag.unicopia.food_types.cooked_fish": "Prepared Fish", + "tag.unicopia.food_types.raw_insect": "Bugs & Insects", + "tag.unicopia.food_types.cooked_insect": "Cooked Bugs & Insects", + "tag.unicopia.food_types.love": "Love", + "tag.unicopia.food_types.rocks": "Rocks", + "tag.unicopia.food_types.pinecone": "Nuts & Seeds", + "tag.unicopia.food_types.bat_ponys_delight": "Bat Pony Treats", + "tag.unicopia.food_types.cooked_sea_vegitables": "Prepared Fish Food", + "tag.unicopia.food_types.raw_sea_vegitables": "Fresh Fish Food", + "tag.unicopia.food_types.shells": "Sea Shells", + "tag.unicopia.food_types.shelly": "Sea Shells", + "tag.unicopia.food_types.candy": "Candy", + "tag.unicopia.food_types.desserts": "Desserts", + "tag.unicopia.food_types.fruits_and_vegetables": "Fruits & Vegetables", + "tag.unicopia.food_types.drinks": "Drinks", + + "tag.unicopia.food_types.forage_edible_filling": "Bulky Plant Matter", + "tag.unicopia.food_types.forage_edible": "Plant Matter", + "tag.unicopia.food_types.forage_nauseating": "Nauseating", + "tag.unicopia.food_types.forage_prickly": "Prickly", + "tag.unicopia.food_types.forage_risky": "Unsafe", + "tag.unicopia.food_types.forage_strengthening": "Strength Enhancing", + "tag.unicopia.food_types.forage_severely_prickly": "Very Prickly", + "tag.unicopia.food_types.forage_severely_nauseating": "Sickening", + "tag.unicopia.food_types.forage_radioactive": "Glowy", + "tag.unicopia.food_types.forage_dangerous": "Dangerous", + "tag.unicopia.food_types.forage_blinding": "Toxic", + "toxicity.safe.name": "Safe", "toxicity.mild.name": "Mildly Toxic", "toxicity.fair.name": "Fairly Toxic", "toxicity.severe.name": "Toxic", "toxicity.lethal.name": "Lethal", + + "affliction.unicopia.empty": "No Effect", + "affliction.unicopia.healing": "Gain %s%% health", + "affliction.unicopia.cure_love_sickness": "Cure Love Sickness", + "affliction.unicopia.lose_hunger": "Lose %s%% hunger", "ability.unicopia.shoot": "Shoot Magic", "ability.unicopia.shoot.with_spell": "Shoot %s", @@ -1068,7 +1114,7 @@ "advancements.unicopia.apple_route.description": "Start your journey towards the apple of legend", "advancements.unicopia.juice.title": "Refreshing", "advancements.unicopia.juice.description": "Finally a use for all these apples", - "advancements.unicopia.toast.title": "He Crispy and delicious!", + "advancements.unicopia.toast.title": "He's Crispy and delicious!", "advancements.unicopia.toast.description": "Make a toasted companion", "advancements.unicopia.burn_toast.title": "Toasty NOOOOOOO!", "advancements.unicopia.burn_toast.description": "Burn Toasty", diff --git a/src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json b/src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json index deb27a4a..423e578f 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/cooked_fish", + "tags": [ "unicopia:food_types/cooked_fish" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, "ailment": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/fish/raw.json b/src/main/resources/data/unicopia/diets/food_effects/fish/raw.json index 49c0fa62..40368a26 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/fish/raw.json +++ b/src/main/resources/data/unicopia/diets/food_effects/fish/raw.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/raw_fish", + "tags": [ "unicopia:food_types/raw_fish" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, "ailment": { - "toxicity": "risky", "effects": [ { "effect": "minecraft:poison", diff --git a/src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json b/src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json index 6259f9a2..4259828b 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json +++ b/src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/rotten_fish", + "tags": [ "unicopia:food_types/rotten_fish" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:poison", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/blinding.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/blinding.json index c9d1e15e..ca392e74 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/blinding.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/blinding.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_blinding", + "tags": [ "unicopia:food_types/forage_blinding" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:blindness", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/dangerous.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/dangerous.json index 7ba1dfbb..372abede 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/dangerous.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/dangerous.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_dangerous", + "tags": [ "unicopia:food_types/forage_dangerous" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "mild", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/edible.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/edible.json index 0142aeab..33887410 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/edible.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/edible.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_edible", + "tags": [ "unicopia:food_types/forage_edible" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [] } } \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/edible_filling.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/edible_filling.json index 8ee0ec31..b6721b3f 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/edible_filling.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/edible_filling.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_edible_filling", + "tags": [ "unicopia:food_types/forage_edible_filling" ], "food_component": { "hunger": 18, "saturation": 9 }, "ailment": { - "toxicity": "safe", "effects": [] } } \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/moderate.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/moderate.json index 1a6682cb..4d7a238a 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/moderate.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/moderate.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_moderate", + "tags": [ "unicopia:food_types/forage_moderate" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "mild", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/nauseating.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/nauseating.json index 03b8943f..e79628a0 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/nauseating.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/nauseating.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_nauseating", + "tags": [ "unicopia:food_types/forage_nauseating" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:weakness", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/prickly.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/prickly.json index f341f99c..d3c61180 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/prickly.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/prickly.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_prickly", + "tags": [ "unicopia:food_types/forage_prickly" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ { "effect": "minecraft:instant_damage", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/radioactive.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/radioactive.json index 911aba9d..7a023788 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/radioactive.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/radioactive.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_radioactive", + "tags": [ "unicopia:food_types/forage_radioactive" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:glowing", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/risky.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/risky.json index c7053b6d..9ee5d1dc 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/risky.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/risky.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_risky", + "tags": [ "unicopia:food_types/forage_risky" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_nauseating.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_nauseating.json index fe8dd8a5..7f4ef36e 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_nauseating.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_nauseating.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_severely_nauseating", + "tags": [ "unicopia:food_types/forage_severely_nauseating" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:weakness", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_prickly.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_prickly.json index 263e9bdd..3b5a1cd6 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_prickly.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_prickly.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_severely_prickly", + "tags": [ "unicopia:food_types/forage_severely_prickly" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:instant_damage", diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/strengthening.json b/src/main/resources/data/unicopia/diets/food_effects/foraging/strengthening.json index 9d12fd6c..11477833 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/foraging/strengthening.json +++ b/src/main/resources/data/unicopia/diets/food_effects/foraging/strengthening.json @@ -1,11 +1,10 @@ { - "tag": "unicopia:food_types/forage_strengthening", + "tags": [ "unicopia:food_types/forage_strengthening" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ { "effect": "minecraft:strength", diff --git a/src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json b/src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json index fe3dcc3d..9dbdc566 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/cooked_insect", + "tags": [ "unicopia:food_types/cooked_insect" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json b/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json index 3d9d2860..8683f240 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json +++ b/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/raw_insect", + "tags": [ "unicopia:food_types/raw_insect" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, "ailment": { - "toxicity": "lethal", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/meat/cooked.json b/src/main/resources/data/unicopia/diets/food_effects/meat/cooked.json index dd186cf3..80b1e542 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/meat/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_effects/meat/cooked.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/cooked_meat", + "tags": [ "unicopia:food_types/cooked_meat" ], + "food_component": { + "hunger": 12, + "saturation": 1.2 + }, "ailment": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/food_effects/meat/raw.json b/src/main/resources/data/unicopia/diets/food_effects/meat/raw.json index eb105ca2..f2c547d9 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/meat/raw.json +++ b/src/main/resources/data/unicopia/diets/food_effects/meat/raw.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/raw_meat", + "tags": [ "unicopia:food_types/raw_meat" ], + "food_component": { + "hunger": 1, + "saturation": 1 + }, "ailment": { - "toxicity": "risky", "effects": [ { "effect": "minecraft:poison", diff --git a/src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json b/src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json index 4139359d..72faee0e 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json +++ b/src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/rotten_meat", + "tags": [ "unicopia:food_types/rotten_meat" ], + "food_component": { + "hunger": 1, + "saturation": 1 + }, "ailment": { - "toxicity": "severe", "effects": [ { "effect": "minecraft:poison", diff --git a/src/main/resources/data/unicopia/diets/food_effects/pinecone.json b/src/main/resources/data/unicopia/diets/food_effects/pinecone.json index a57d220d..75f92718 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/pinecone.json +++ b/src/main/resources/data/unicopia/diets/food_effects/pinecone.json @@ -1,7 +1,10 @@ { - "tag": "unicopia:food_types/pinecone", + "tags": [ "unicopia:food_types/pinecone" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, "ailment": { - "toxicity": "safe", "effects": [ { "type": "unicopia:healing", diff --git a/src/main/resources/data/unicopia/diets/food_effects/rocks.json b/src/main/resources/data/unicopia/diets/food_effects/rocks.json new file mode 100644 index 00000000..ebe7b986 --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_effects/rocks.json @@ -0,0 +1,10 @@ +{ + "tags": [ "unicopia:food_types/rocks" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, + "ailment": { + "effects": [] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/races/alicorn.json b/src/main/resources/data/unicopia/diets/races/alicorn.json index 76cdea56..d318454c 100644 --- a/src/main/resources/data/unicopia/diets/races/alicorn.json +++ b/src/main/resources/data/unicopia/diets/races/alicorn.json @@ -3,16 +3,12 @@ "foraging_multiplier": 1, "multipliers": [ { - "tags": [ - "unicopia:food_types/cooked_fish" - ], + "tags": [ "unicopia:food_types/cooked_fish" ], "hunger": 1.5, "saturation": 1.5 }, { - "tags": [ - "unicopia:food_types/raw_fish" - ], + "tags": [ "unicopia:food_types/raw_fish" ], "hunger": 0.5, "saturation": 0.6 }, @@ -35,29 +31,25 @@ "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 0.9, "saturation": 0.9 } ], "effects": [ { - "tag": "unicopia:food_types/cooked_fish", + "tags": [ "unicopia:food_types/cooked_fish" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/raw_fish", + "tags": [ "unicopia:food_types/raw_fish" ], "ailment": { - "toxicity": "safe", "effects": [ ] } } diff --git a/src/main/resources/data/unicopia/diets/races/bat.json b/src/main/resources/data/unicopia/diets/races/bat.json index e00adbee..2aedf250 100644 --- a/src/main/resources/data/unicopia/diets/races/bat.json +++ b/src/main/resources/data/unicopia/diets/races/bat.json @@ -3,74 +3,55 @@ "foraging_multiplier": 0.9, "multipliers": [ { - "tags": [ - "unicopia:food_types/cooked_fish" - ], + "tags": [ "unicopia:food_types/cooked_fish" ], "hunger": 0.75, "saturation": 0.75 }, { - "tags": [ - "unicopia:food_types/raw_fish" - ], + "tags": [ "unicopia:food_types/raw_fish" ], "hunger": 0.5, "saturation": 0.6 }, { - "tags": [ - "unicopia:food_types/cooked_insect" - ], + "tags": [ "unicopia:food_types/cooked_insect" ], "hunger": 1.75, "saturation": 1.75 }, { - "tags": [ - "unicopia:food_types/cooked_meat" - ], + "tags": [ "unicopia:food_types/cooked_meat" ], "hunger": 1.15, "saturation": 1.15 }, { - "tags": [ - "unicopia:food_types/raw_insect" - ], + "tags": [ "unicopia:food_types/raw_insect" ], "hunger": 1, "saturation": 1 }, { - "tags": [ - "unicopia:food_types/raw_meat" - ], + "tags": [ "unicopia:food_types/raw_meat" ], "hunger": 0.25, "saturation": 0.25 }, { - "tags": [ - "unicopia:food_types/rotten_meat" - ], + "tags": [ "unicopia:food_types/rotten_meat" ], "hunger": 0.2, "saturation": 0.2 }, { - "tags": [ - "unicopia:food_types/love" - ], + "tags": [ "unicopia:food_types/love" ], "hunger": 0, "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 0.9, "saturation": 0.9 } ], "effects": [ { - "tag": "unicopia:food_types/rotten_fish", + "tags": [ "unicopia:food_types/rotten_fish" ], "ailment": { - "toxicity": "mild", "effects": [ { "effect": "unicopia:food_poisoning", @@ -87,14 +68,12 @@ "unicopia:food_types/cooked_meat" ], "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/raw_insect", + "tags": [ "unicopia:food_types/raw_insect" ], "ailment": { - "toxicity": "mild", "effects": [ { "effect": "unicopia:food_poisoning", @@ -110,7 +89,6 @@ "unicopia:food_types/rotten_meat" ], "ailment": { - "toxicity": "risky", "effects": [ { "effect": "unicopia:food_poisoning", @@ -122,9 +100,8 @@ } }, { - "tag": "unicopia:food_types/bat_ponys_delight", + "tags": [ "unicopia:food_types/bat_ponys_delight" ], "ailment": { - "toxicity": "safe", "effects": [ { "effect": "minecraft:health_boost", diff --git a/src/main/resources/data/unicopia/diets/races/changeling.json b/src/main/resources/data/unicopia/diets/races/changeling.json index f4e04ebe..e6255344 100644 --- a/src/main/resources/data/unicopia/diets/races/changeling.json +++ b/src/main/resources/data/unicopia/diets/races/changeling.json @@ -3,50 +3,37 @@ "foraging_multiplier": 0, "multipliers": [ { - "tags": [ - "unicopia:food_types/cooked_insect" - ], + "tags": [ "unicopia:food_types/cooked_insect" ], "hunger": 0.3, "saturation": 0.3 }, { - "tags": [ - "unicopia:food_types/cooked_meat" - ], + "tags": [ "unicopia:food_types/cooked_meat" ], "hunger": 0.1, "saturation": 0.1 }, { - "tags": [ - "unicopia:food_types/raw_insect" - ], + "tags": [ "unicopia:food_types/raw_insect" ], "hunger": 1, "saturation": 1 }, { - "tags": [ - "unicopia:food_types/raw_meat" - ], + "tags": [ "unicopia:food_types/raw_meat" ], "hunger": 0.25, "saturation": 0.25 }, { - "tags": [ - "unicopia:food_types/rotten_meat" - ], + "tags": [ "unicopia:food_types/rotten_meat" ], "hunger": 0.6, "saturation": 0.6 }, { - "tags": [ - "unicopia:food_types/love" - ], + "tags": [ "unicopia:food_types/love" ], "hunger": 1, "saturation": 1 } ], "default_effects": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", @@ -66,15 +53,12 @@ }, "effects": [ { - "tags": [ - "unicopia:food_types/love" - ], + "tags": [ "unicopia:food_types/love" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ { "name": "Love Consumption", @@ -89,7 +73,6 @@ "unicopia:food_types/raw_fish" ], "ailment": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", @@ -114,21 +97,19 @@ "unicopia:food_types/rotten_meat" ], "ailment": { - "toxicity": "safe", "effects": [ ] } }, { "tags": [ "unicopia:food_types/forage_edible", - "unicopia:food_types/forage_edible_filling", + "unicopia:food_types/forage_edible_filling" ], "food_component": { "hunger": 18, "saturation": 9 }, "ailment": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/races/earth.json b/src/main/resources/data/unicopia/diets/races/earth.json index 0c429144..a8b48e87 100644 --- a/src/main/resources/data/unicopia/diets/races/earth.json +++ b/src/main/resources/data/unicopia/diets/races/earth.json @@ -1,11 +1,18 @@ { - "default_multiplier": 0.3, + "default_multiplier": 1, "foraging_multiplier": 1, "multipliers": [ { "tags": [ - "unicopia:food_types/cooked_fish" - ], + "unicopia:food_types/candy", + "unicopia:food_types/desserts", + "unicopia:food_types/rocks" + ], + "hunger": 2.5, + "saturation": 1.7 + }, + { + "tags": [ "unicopia:food_types/cooked_fish" ], "hunger": 0.2, "saturation": 0.2 }, @@ -29,11 +36,39 @@ "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 1, "saturation": 1 } + ], + "effects": [ + { + "tags": [ + "unicopia:food_types/candy", + "unicopia:food_types/rocks" + ], + "food_component": { + "hunger": 5, + "saturation": 12, + "fastFood": true + }, + "ailment": { + "effects": [ ] + } + }, + { + "tags": [ + "unicopia:food_types/desserts" + ], + "food_component": { + "hunger": 12, + "saturation": 32, + "eatenQuickly": true, + "fastFood": true + }, + "ailment": { + "effects": [ ] + } + } ] } diff --git a/src/main/resources/data/unicopia/diets/races/hippogriff.json b/src/main/resources/data/unicopia/diets/races/hippogriff.json index 15565d9e..8ecea1ad 100644 --- a/src/main/resources/data/unicopia/diets/races/hippogriff.json +++ b/src/main/resources/data/unicopia/diets/races/hippogriff.json @@ -19,9 +19,7 @@ "saturation": 0.6 }, { - "tags": [ - "unicopia:food_types/rotten_meat" - ], + "tags": [ "unicopia:food_types/rotten_meat" ], "hunger": 0.3, "saturation": 0.3 }, @@ -35,29 +33,25 @@ "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 1, "saturation": 1 } ], "effects": [ { - "tag": "unicopia:food_types/cooked_fish", + "tags": [ "unicopia:food_types/cooked_fish" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/raw_fish", + "tags": [ "unicopia:food_types/raw_fish" ], "ailment": { - "toxicity": "safe", "effects": [ ] } }, @@ -71,14 +65,12 @@ "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/pinecone", + "tags": [ "unicopia:food_types/pinecone" ], "ailment": { - "toxicity": "safe", "effects": [ { "type": "unicopia:healing", diff --git a/src/main/resources/data/unicopia/diets/races/human.json b/src/main/resources/data/unicopia/diets/races/human.json index a36216f0..ddf024b3 100644 --- a/src/main/resources/data/unicopia/diets/races/human.json +++ b/src/main/resources/data/unicopia/diets/races/human.json @@ -14,7 +14,6 @@ "unicopia:food_types/pinecone" ], "ailment": { - "toxicity": "safe", "effects": [ ] } } diff --git a/src/main/resources/data/unicopia/diets/races/kirin.json b/src/main/resources/data/unicopia/diets/races/kirin.json index 7eaac714..2f2f4172 100644 --- a/src/main/resources/data/unicopia/diets/races/kirin.json +++ b/src/main/resources/data/unicopia/diets/races/kirin.json @@ -3,16 +3,12 @@ "foraging_multiplier": 0.9, "multipliers": [ { - "tags": [ - "unicopia:food_types/cooked_meat" - ], + "tags": [ "unicopia:food_types/cooked_meat" ], "hunger": 1.5, "saturation": 1.5 }, { - "tags": [ - "unicopia:food_types/raw_meat" - ], + "tags": [ "unicopia:food_types/raw_meat" ], "hunger": 0.5, "saturation": 0.6 }, @@ -35,9 +31,7 @@ "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 0.9, "saturation": 0.9 } @@ -60,7 +54,6 @@ "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ ] } } diff --git a/src/main/resources/data/unicopia/diets/races/pegasus.json b/src/main/resources/data/unicopia/diets/races/pegasus.json index 11865b7a..da8220b7 100644 --- a/src/main/resources/data/unicopia/diets/races/pegasus.json +++ b/src/main/resources/data/unicopia/diets/races/pegasus.json @@ -1,18 +1,14 @@ { - "default_multiplier": 0, + "default_multiplier": 0.5, "foraging_multiplier": 1, "multipliers": [ { - "tags": [ - "unicopia:food_types/cooked_fish" - ], + "tags": [ "unicopia:food_types/cooked_fish" ], "hunger": 1.5, "saturation": 1.5 }, { - "tags": [ - "unicopia:food_types/raw_fish" - ], + "tags": [ "unicopia:food_types/raw_fish" ], "hunger": 0.5, "saturation": 0.6 }, @@ -35,25 +31,21 @@ "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 0.9, "saturation": 0.9 } ], "effects": [ { - "tag": "unicopia:food_types/cooked_fish", + "tags": [ "unicopia:food_types/cooked_fish" ], "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/raw_fish", + "tags": [ "unicopia:food_types/raw_fish" ], "ailment": { - "toxicity": "mild", "effects": [ { "effect": "unicopia:food_poisoning", diff --git a/src/main/resources/data/unicopia/diets/races/seapony.json b/src/main/resources/data/unicopia/diets/races/seapony.json index ac2e8858..4bf9a4cb 100644 --- a/src/main/resources/data/unicopia/diets/races/seapony.json +++ b/src/main/resources/data/unicopia/diets/races/seapony.json @@ -3,9 +3,7 @@ "foraging_multiplier": 0.7, "multipliers": [ { - "tags": [ - "unicopia:food_types/raw_sea_vegitable" - ], + "tags": [ "unicopia:food_types/raw_sea_vegitable" ], "hunger": 1, "saturation": 1 }, @@ -19,7 +17,6 @@ } ], "default_effects": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", @@ -30,30 +27,27 @@ }, "effects": [ { - "tag": "unicopia:food_types/cooked_fish", + "tags": [ "unicopia:food_types/cooked_fish" ], "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/raw_fish", + "tags": [ "unicopia:food_types/raw_fish" ], "ailment": { - "toxicity": "safe", "effects": [ ] } }, { "tags": [ "unicopia:food_types/forage_edible", - "unicopia:food_types/forage_edible_filling", + "unicopia:food_types/forage_edible_filling" ], "food_component": { "hunger": 18, "saturation": 9 }, "ailment": { - "toxicity": "fair", "effects": [ { "effect": "unicopia:food_poisoning", @@ -64,46 +58,42 @@ } }, { - "tag": "unicopia:food_types/raw_sea_vegitable", + "tags": [ "unicopia:food_types/raw_sea_vegitable" ], "food_component": { "hunger": 2, "saturation": 1 }, "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/cooked_sea_vegitable", + "tags": [ "unicopia:food_types/cooked_sea_vegitable" ], "food_component": { "hunger": 6, "saturation": 2 }, "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/shells", + "tags": [ "unicopia:food_types/shells" ], "food_component": { "hunger": 3, "saturation": 5 }, "ailment": { - "toxicity": "safe", "effects": [ ] } }, { - "tag": "unicopia:food_types/shelly", + "tags": [ "unicopia:food_types/shelly" ], "food_component": { "hunger": 6, "saturation": 7 }, "ailment": { - "toxicity": "safe", "effects": [ ] } } diff --git a/src/main/resources/data/unicopia/diets/races/unicorn.json b/src/main/resources/data/unicopia/diets/races/unicorn.json index 670dcd4e..866ba9e2 100644 --- a/src/main/resources/data/unicopia/diets/races/unicorn.json +++ b/src/main/resources/data/unicopia/diets/races/unicorn.json @@ -23,11 +23,10 @@ "saturation": 0 }, { - "tags": [ - "unicopia:food_types/pinecone" - ], + "tags": [ "unicopia:food_types/pinecone" ], "hunger": 0.9, "saturation": 0.9 } - ] + ], + "effects": [] } diff --git a/src/main/resources/data/unicopia/tags/items/food_types/candy.json b/src/main/resources/data/unicopia/tags/items/food_types/candy.json new file mode 100644 index 00000000..8a152f67 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/food_types/candy.json @@ -0,0 +1,10 @@ +{ + "replace": false, + "values": [ + "unicopia:rock_candy", + "unicopia:candied_apple", + "minecraft:sugar", + { "id": "bakersdelight:sweet_berry_cheesecake_slice", "required": false }, + { "id": "bakersdelight:cake_slice", "required": false } + ] +} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/desserts.json b/src/main/resources/data/unicopia/tags/items/food_types/desserts.json new file mode 100644 index 00000000..0e14adc0 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/food_types/desserts.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "minecraft:cake", + "#unicopia:pies", + { "id": "bakersdelight:sweet_berry_cheesecake", "required": false } + ] +} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/rocks.json b/src/main/resources/data/unicopia/tags/items/food_types/rocks.json new file mode 100644 index 00000000..229f317a --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/food_types/rocks.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "unicopia:rock_stew" + ] +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index b6e5e32b..d8654fc3 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -69,8 +69,8 @@ "client.MixinHeldItemRenderer", "client.MixinInGameHud", "client.MixinInGameHud$HeartType", - "client.MixinItem", "client.MixinItemModels", + "client.MixinItemStack", "client.MixinKeyboardInput", "client.MixinLivingEntityRenderer", "client.MixinModelPart",