diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index e6fbe11a..8fb0d326 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -13,7 +13,6 @@ import com.google.common.base.Strings; import com.minelittlepony.common.client.gui.sprite.TextureSprite; import com.minelittlepony.common.client.gui.style.Style; import com.minelittlepony.unicopia.ability.magic.Affine; -import com.minelittlepony.unicopia.item.toxin.FoodType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.text.Text; @@ -50,19 +49,6 @@ public enum Race implements Affine { return this == CHANGELING ? Affinity.BAD : Affinity.NEUTRAL; } - public boolean canConsume(FoodType type) { - if (!isUsable()) { - return type != FoodType.FORAGE; - } - if (type.isMeat()) { - return this == BAT || this == CHANGELING || this == HUMAN; - } - if (type.isFish()) { - return this == PEGASUS || this == ALICORN; - } - return hasIronGut(); - } - public boolean hasIronGut() { return isUsable() && this != CHANGELING; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index 5f9d01ee..396160c7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -24,8 +24,6 @@ import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.Trap; import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect; import com.minelittlepony.unicopia.item.UItems; -import com.minelittlepony.unicopia.item.toxin.FoodType; -import com.minelittlepony.unicopia.item.toxin.Toxicity; import com.minelittlepony.unicopia.item.toxin.Toxin; import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities; @@ -420,7 +418,7 @@ public class Pony extends Living implements Transmittable, Copieab public void onEat(ItemStack stack) { if (getSpecies() == Race.CHANGELING) { - Toxin.POISON.afflict(getMaster(), FoodType.RAW_MEAT, Toxicity.SAFE, stack); + Toxin.LOVE_SICKNESS.afflict(getMaster(), stack); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 8ce6c7b1..0dfad5ee 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -62,7 +62,7 @@ public interface UItems { Item DAFFODIL_DAISY_SANDWICH = register("daffodil_daisy_sandwich", new Item(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.DAFODIL_DAISY_SANDWICH))); Item HAY_BURGER = register("hay_burger", new Item(new Item.Settings().group(ItemGroup.FOOD).maxCount(1).food(UFoodComponents.HAY_BURGER))); Item HAY_FRIES = register("hay_fries", new Item(new Item.Settings().group(ItemGroup.FOOD).maxCount(16).food(UFoodComponents.HAY_FRIES))); - Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().group(ItemGroup.MISC).maxCount(16).food(UFoodComponents.WORMS))); + Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().group(ItemGroup.MISC).maxCount(16).food(UFoodComponents.INSECTS))); Item MUG = register("mug", new Item(new Settings().group(ItemGroup.MATERIALS).maxCount(16))); Item CIDER = register("cider", new DrinkableItem(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.CIDER).maxCount(1).recipeRemainder(MUG))); diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Affliction.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Affliction.java new file mode 100644 index 00000000..f2350be5 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Affliction.java @@ -0,0 +1,12 @@ +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 index d817414e..64f8a47a 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java @@ -1,29 +1,40 @@ package com.minelittlepony.unicopia.item.toxin; +import java.util.List; + +import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.text.Text; -public class Ailment { - - public static final Ailment INNERT = new Ailment(Toxicity.SAFE, Toxin.INNERT); +public class Ailment implements Affliction { + public static final Ailment INNERT = of(Toxicity.SAFE, Toxin.INNERT); private final Toxicity toxicity; - private final Toxin toxin; + private final Toxin effect; - public Ailment(Toxicity toxicity, Toxin toxin) { + Ailment(Toxicity toxicity, Toxin effect) { this.toxicity = toxicity; - this.toxin = toxin; + this.effect = effect; } public Toxicity getToxicity() { return toxicity; } - public void afflict(PlayerEntity player, FoodType type, ItemStack stack) { - this.toxin.afflict(player, type, toxicity, stack); + public void appendTooltip(List tooltip, TooltipContext context) { + tooltip.add(getToxicity().getTooltip()); + if (context.isAdvanced()) { + effect.appendTooltip(tooltip); + } } - public static Ailment of(Toxicity toxicity) { - return new Ailment(toxicity, Toxin.FOOD); + @Override + public void afflict(PlayerEntity player, ItemStack stack) { + effect.afflict(player, stack); + } + + public static Ailment of(Toxicity toxicity, Toxin effect) { + return new Ailment(toxicity, effect); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/FoodType.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/FoodType.java deleted file mode 100644 index f840c450..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/FoodType.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.minelittlepony.unicopia.item.toxin; - -public enum FoodType { - RAW_MEAT, COOKED_MEAT, - RAW_FISH, COOKED_FISH, - FORAGE; - - public boolean isRaw() { - return this == RAW_MEAT || this == RAW_FISH || this == FORAGE; - } - - public boolean isMeat() { - return this == RAW_MEAT || this == COOKED_MEAT; - } - - public boolean isFish() { - return this == RAW_FISH || this == COOKED_FISH; - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java index a4e7ee41..6c2d0e08 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java @@ -1,7 +1,11 @@ package com.minelittlepony.unicopia.item.toxin; +import java.util.EnumMap; +import java.util.Map; import java.util.Optional; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.LivingEntity; @@ -18,22 +22,19 @@ import net.minecraft.world.World; public class Toxic { private final UseAction action; - private final Ailment lowerBound; - private final Ailment upperBound; - - private final FoodType type; - private final Optional component; + private final Ailment defaultAilment; + private final Map ailments; + private final Tag tag; - Toxic(UseAction action, FoodType type, Optional component, Tag tag, Ailment lowerBound, Ailment upperBound) { + Toxic(UseAction action, Optional component, Tag tag, Ailment defaultAilment, Map ailments) { this.action = action; - this.type = type; this.component = component; this.tag = tag; - this.lowerBound = lowerBound; - this.upperBound = upperBound; + this.defaultAilment = defaultAilment; + this.ailments = ailments; } public boolean matches(Item item) { @@ -49,16 +50,15 @@ public class Toxic { } public Ailment getAilmentFor(PlayerEntity player) { - Pony pony = Pony.of(player); - if (pony != null && !pony.getSpecies().canConsume(type)) { - return upperBound; + if (player == null) { + return defaultAilment; } - return lowerBound; + return ailments.getOrDefault(Pony.of(player).getSpecies(), defaultAilment); } public ItemStack finishUsing(ItemStack stack, World world, LivingEntity entity) { if (entity instanceof PlayerEntity) { - getAilmentFor((PlayerEntity)entity).afflict((PlayerEntity)entity, type, stack); + getAilmentFor((PlayerEntity)entity).afflict((PlayerEntity)entity, stack); } return stack; @@ -70,4 +70,34 @@ public class Toxic { } return null; } + + public static class Builder { + private final Ailment def; + private final Map ailments = new EnumMap<>(Race.class); + private UseAction action = UseAction.EAT; + private Optional component = Optional.empty(); + + public Builder(Ailment def) { + this.def = def; + } + + public Builder action(UseAction action) { + this.action = action; + return this; + } + + public Builder food(FoodComponent food) { + component = Optional.ofNullable(food); + return this; + } + + public Builder with(Race race, Ailment ailment) { + ailments.put(race, ailment); + return this; + } + + public Toxic build(String name) { + return new Toxic(action, component, UTags.item(name), def, ailments); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java index a010a7da..af8dd7db 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxicity.java @@ -10,44 +10,18 @@ import net.minecraft.text.TranslatableText; import net.minecraft.util.Formatting; public enum Toxicity { - SAFE(0, 0), - MILD(1, 160), - FAIR(1, 30), - SEVERE(5, 160), - LETHAL(10, 900); - - private final int level; - private final int duration; + 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())); - Toxicity(int level, int duration) { - this.level = level; - this.duration = duration; - } + private final Formatting color; - public int getLevel() { - return level; - } - - public int getDuration() { - return duration; - } - - public boolean isMild() { - return this == MILD; - } - - public boolean toxicWhenRaw() { - return isLethal() || this != SAFE; - } - - public boolean toxicWhenCooked() { - return isLethal() || this == SEVERE; - } - - public boolean isLethal() { - return this == LETHAL; + Toxicity(Formatting color) { + this.color = color; } public String getTranslationKey() { @@ -55,9 +29,7 @@ public enum Toxicity { } public Text getTooltip() { - return new TranslatableText(getTranslationKey()) - .styled(s -> s - .withColor(toxicWhenCooked() ? Formatting.RED : toxicWhenRaw() ? Formatting.DARK_PURPLE : Formatting.GRAY)); + return new TranslatableText(getTranslationKey()).formatted(color); } public static Toxicity byName(String 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 index 20e4913c..8f766013 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java @@ -1,13 +1,9 @@ package com.minelittlepony.unicopia.item.toxin; -import java.util.Optional; - -import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.util.Registries; -import net.minecraft.item.FoodComponent; import net.minecraft.util.Identifier; -import net.minecraft.util.UseAction; import net.minecraft.util.registry.Registry; import static com.minelittlepony.unicopia.item.toxin.Toxicity.*; @@ -16,46 +12,87 @@ import static com.minelittlepony.unicopia.item.toxin.Toxin.*; public interface Toxics { Registry REGISTRY = Registries.createSimple(new Identifier("unicopia:toxic")); - Toxic EDIBLE = forage("edible", SAFE, FOOD); - Toxic RISKY = forage("risky", FAIR, FOOD); - Toxic MODERATE = forage("moderate", MILD, FOOD); - Toxic DANGEROUS = forage("dangerous", SEVERE, FOOD); - Toxic NAUSEATING = forage("nauseating", SAFE, NAUSEA); - Toxic RADIOACTIVE = forage("radioactive", SAFE, RADIOACTIVITY); - Toxic PRICKLY = forage("prickly", SAFE, DAMAGE); - Toxic STRENGHTENING = forage("strengthening", SEVERE, STRENGTH); - Toxic SEVERELY_NAUSEATING = forage("severely_nauseating", SEVERE, NAUSEA); - Toxic BLINDING = forage("blinding", SEVERE, BLINDNESS); - Toxic SEVERELY_PRICKLY = forage("severely_prickly", SEVERE, DAMAGE); + Toxic EDIBLE = register("forage_edible", new Toxic.Builder(Ailment.of(SAFE, INNERT)) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING)) + ); + Toxic RISKY = register("forage_risky", new Toxic.Builder(Ailment.of(FAIR, WEAK_NAUSEA.withChance(20))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING)) + ); + Toxic MODERATE = register("forage_moderate", new Toxic.Builder(Ailment.of(MILD, POISON.and(WEAK_NAUSEA))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING)) + ); + Toxic DANGEROUS = register("forage_dangerous", new Toxic.Builder(Ailment.of(SEVERE, FOOD_POISONING)) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING.and(NAUSEA))) + ); + Toxic NAUSEATING = register("forage_nauseating", new Toxic.Builder(Ailment.of(SAFE, NAUSEA.and(WEAKNESS.withChance(30)))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING.and(NAUSEA))) + ); + Toxic RADIOACTIVE = register("forage_radioactive", new Toxic.Builder(Ailment.of(SAFE, NAUSEA.and(RADIOACTIVITY.withChance(30)))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING.and(NAUSEA))) + ); + Toxic PRICKLY = register("forage_prickly", new Toxic.Builder(Ailment.of(SAFE, PRICKLING.withChance(30))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING.and(NAUSEA))) + ); + Toxic STRENGHTENING = register("forage_strengthening", new Toxic.Builder(Ailment.of(SEVERE, STRENGTH.and(WEAK_NAUSEA))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING.and(WEAKNESS))) + ); + Toxic SEVERELY_NAUSEATING = register("forage_severely_nauseating", new Toxic.Builder(Ailment.of(SEVERE, STRONG_NAUSEA.and(WEAKNESS))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING.and(WEAKNESS))) + ); + Toxic BLINDING = register("forage_blinding", new Toxic.Builder(Ailment.of(SEVERE, BLINDNESS.and(WEAK_NAUSEA))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING)) + ); + Toxic SEVERELY_PRICKLY = register("forage_severely_prickly", new Toxic.Builder(Ailment.of(SEVERE, PRICKLING.and(NAUSEA))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, Ailment.of(LETHAL, FOOD_POISONING)) + ); + Toxic RAW_MEAT = register("raw_meat", new Toxic.Builder(Ailment.of(SEVERE, FOOD_POISONING.withChance(5).and(POISON.withChance(20)))) + .with(Race.HUMAN, Ailment.INNERT) + .with(Race.BAT, Ailment.of(MILD, WEAK_NAUSEA)) + ); + Toxic ROTTEN_MEAT = register("rotten_meat", new Toxic.Builder(Ailment.of(SEVERE, FOOD_POISONING.and(POISON))) + .with(Race.HUMAN, Ailment.INNERT) + .with(Race.BAT, Ailment.of(MILD, STRONG_NAUSEA)) + ); + Toxic COOKED_MEAT = register("cooked_meat", new Toxic.Builder(Ailment.of(FAIR, FOOD_POISONING)) + .with(Race.HUMAN, Ailment.INNERT) + .with(Race.BAT, Ailment.INNERT) + ); - Toxic RAW_MEAT = meat(FoodType.RAW_MEAT, MILD); - Toxic COOKED_MEAT = meat(FoodType.COOKED_MEAT, MILD); + Toxic RAW_FISH = register("raw_fish", new Toxic.Builder(Ailment.of(FAIR, FOOD_POISONING.and(POISON))) + .with(Race.HUMAN, Ailment.INNERT) + .with(Race.PEGASUS, Ailment.of(MILD, POISON.and(WEAK_NAUSEA))) + .with(Race.ALICORN, Ailment.INNERT) + ); + Toxic COOKED_FISH = register("cooked_fish", new Toxic.Builder(Ailment.of(MILD, FOOD_POISONING)) + .with(Race.HUMAN, Ailment.INNERT) + .with(Race.PEGASUS, Ailment.INNERT) + .with(Race.ALICORN, Ailment.INNERT) + ); - Toxic RAW_FISH = meat(FoodType.RAW_FISH, FAIR); - Toxic COOKED_FISH = meat(FoodType.COOKED_FISH, FAIR); + Toxic RAW_INSECT = register("raw_insect", new Toxic.Builder(Ailment.of(LETHAL, FOOD_POISONING)) + .with(Race.BAT, Ailment.of(MILD, WEAK_NAUSEA)) + ); + + Toxic COOKED_INSECT = register("cooked_insect", new Toxic.Builder(Ailment.of(LETHAL, FOOD_POISONING)) + .food(UFoodComponents.INSECTS) + .with(Race.BAT, Ailment.INNERT) + ); static void bootstrap() {} - static Toxic forage(String name, Toxicity toxicity, Toxin toxin) { - if (toxin != FOOD) { - toxin = FOOD.and(toxin); - } - return register("forage_" + name, UseAction.EAT, FoodType.FORAGE, - Optional.of(UFoodComponents.RANDOM_FOLIAGE), - new Ailment(toxicity, toxin), - new Ailment(Toxicity.LETHAL, toxin)); - } - - static Toxic meat(FoodType type, Toxicity toxicity) { - return register(type.name().toLowerCase(), UseAction.EAT, type, - Optional.empty(), - Ailment.INNERT, - Ailment.of(toxicity)); - } - - static Toxic register(String name, UseAction action, FoodType type, Optional component, - Ailment lower, - Ailment upper) { - return Registry.register(REGISTRY, name, new Toxic(action, type, component, UTags.item(name), lower, upper)); + static Toxic register(String name, Toxic.Builder builder) { + name = "food_types/" + name; + return Registry.register(REGISTRY, name, builder.build(name)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java index 71d8a5de..bfbcde93 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java @@ -1,72 +1,137 @@ package com.minelittlepony.unicopia.item.toxin; +import java.util.List; + 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.text.TranslatableText; +import net.minecraft.util.ChatUtil; import net.minecraft.world.Difficulty; -@FunctionalInterface -public interface Toxin { - Predicate ONE_EVERY_30_TICKS = (player, type, toxicity, stack) -> player.world.random.nextInt(30) == 0; +public interface Toxin extends Affliction { + Predicate IF_NOT_PEACEFUL = Predicate.of(Text.of("when not in peaceful "), (player, stack) -> player.world.getDifficulty() != Difficulty.PEACEFUL); - Toxin INNERT = (player, type, toxicity, stack) -> {}; - Toxin DAMAGE = ONE_EVERY_30_TICKS.then(of(StatusEffects.INSTANT_DAMAGE, 1, 1)); - Toxin RADIOACTIVITY = ONE_EVERY_30_TICKS.then(of(StatusEffects.GLOWING, 10, 1)); - Toxin NAUSEA = of(StatusEffects.NAUSEA, 30, 1); - Toxin WEAK_NAUSEA = of(StatusEffects.NAUSEA, 3, 1); - Toxin STRENGTH = of(StatusEffects.STRENGTH, 30, 1); - Toxin BLINDNESS = of(StatusEffects.BLINDNESS, 30, 1); - Toxin POISON = (player, type, toxicity, stack) -> { + Toxin INNERT = of(Text.of("No Effect"), (player, stack) -> {}); + + Toxin PRICKLING = of(StatusEffects.INSTANT_DAMAGE, 1, 0); + Toxin RADIOACTIVITY = of(StatusEffects.GLOWING, 15, 0); + + Toxin WEAKNESS = of(StatusEffects.WEAKNESS, 200, 1); + + Toxin WEAK_NAUSEA = of(StatusEffects.NAUSEA, 17, 0); + Toxin NAUSEA = of(StatusEffects.NAUSEA, 20, 1); + Toxin STRONG_NAUSEA = of(StatusEffects.NAUSEA, 30, 1); + + Toxin STRENGTH = of(StatusEffects.STRENGTH, 30, 0); + Toxin BLINDNESS = of(StatusEffects.BLINDNESS, 30, 0); + Toxin POISON = of(StatusEffects.POISON, 45, 2); + Toxin FOOD_POISONING = of(UEffects.FOOD_POISONING, 300, 2); + Toxin WEAK_FOOD_POISONING = of(UEffects.FOOD_POISONING, 150, 1); + + Toxin LOVE_SICKNESS = of(Text.of("Love Sickness "), (player, stack) -> { FoodComponent food = stack.getItem().getFoodComponent(); - player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2); - afflict(player, StatusEffects.NAUSEA, 1700, 10); + }).and(STRONG_NAUSEA).and(IF_NOT_PEACEFUL.then(WEAK_FOOD_POISONING.withChance(20))).and(WEAKNESS); - if (player.world.getDifficulty() != Difficulty.PEACEFUL && player.world.random.nextInt(20) == 0) { - afflict(player, UEffects.FOOD_POISONING, 150, 2); - } + default void appendTooltip(List tooltip) { + tooltip.add(getName()); + } - afflict(player, StatusEffects.WEAKNESS, 2000, 20); - }; - Toxin FOOD = (player, type, toxicity, stack) -> { - if (toxicity.toxicWhenRaw() && type.isRaw()) { - player.addStatusEffect(new StatusEffectInstance(toxicity.isMild() ? StatusEffects.NAUSEA : StatusEffects.POISON, toxicity.getDuration(), toxicity.getLevel())); - } + default Toxin withChance(int max) { + return Predicate.of(Text.of("1 in " + max + " chance of "), (player, stack) -> player.world.random.nextInt(max) == 0).then(this); + } - if (toxicity.isLethal()) { - player.addStatusEffect(new StatusEffectInstance(UEffects.FOOD_POISONING, 300, 7, false, false)); - } else if (toxicity.toxicWhenCooked()) { - WEAK_NAUSEA.afflict(player, type, toxicity, stack); - } - }; - - void afflict(PlayerEntity player, FoodType type, Toxicity toxicity, ItemStack stack); + Text getName(); default Toxin and(Toxin other) { Toxin self = this; - return (player, type, toxicity, stack) -> { - self.afflict(player, type, toxicity, stack); - other.afflict(player, type, toxicity, stack); + 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().shallowCopy().append(" + ").append(other.getName()); + } }; } - static Toxin of(StatusEffect effect, int duration, int amplifier) { - return (player, type, toxicity, stack) -> afflict(player, effect, duration, amplifier); + 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; + } + }; } - static void afflict(PlayerEntity player, StatusEffect effect, int duration, int amplifier) { - player.addStatusEffect(new StatusEffectInstance(effect, duration, amplifier, false, false)); + static Toxin of(StatusEffect effect, int seconds, int amplifier) { + int ticks = seconds * 20; + + MutableText text = effect.getName().shallowCopy(); + + if (amplifier > 0) { + text = new TranslatableText("potion.withAmplifier", text, new TranslatableText("potion.potency." + amplifier)); + } + + text = new TranslatableText("potion.withDuration", text, ChatUtil.ticksToString(ticks)); + + return of(text, (player, stack) -> { + player.addStatusEffect(new StatusEffectInstance(effect, ticks, amplifier, false, false, false)); + }); } interface Predicate { - boolean test(PlayerEntity player, FoodType type, Toxicity toxicity, ItemStack stack); + 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 (player, type, toxicity, stack) -> { - if (test(player, type, toxicity, stack)) { - toxin.afflict(player, type, toxicity, stack); + 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().shallowCopy().append(toxin.getName()); } }; } diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/UEffects.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/UEffects.java index de5b30f4..c3f6f88b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/UEffects.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/UEffects.java @@ -11,17 +11,20 @@ import net.minecraft.util.Identifier; public interface UEffects { - StatusEffect FOOD_POISONING = new CustomStatusEffect(new Identifier("unicopia", "food_poisoning"), StatusEffectType.BENEFICIAL, 3484199) - .setSilent() - .direct((p, e, i) -> { - StatusEffectInstance nausea = e.getStatusEffect(StatusEffects.NAUSEA); - if (nausea == null) { - StatusEffectInstance foodEffect = e.getStatusEffect(p); - nausea = new StatusEffectInstance(StatusEffects.NAUSEA, foodEffect.getDuration(), foodEffect.getAmplifier(), foodEffect.isAmbient(), foodEffect.shouldShowParticles()); + StatusEffect FOOD_POISONING = new CustomStatusEffect.Builder(new Identifier("unicopia", "food_poisoning"), StatusEffectType.HARMFUL, 3484199).direct((p, e, i) -> { + StatusEffectInstance nausea = e.getStatusEffect(StatusEffects.NAUSEA); + if (nausea == null) { + StatusEffectInstance foodEffect = e.getStatusEffect(p); + nausea = new StatusEffectInstance(StatusEffects.NAUSEA, foodEffect.getDuration(), + foodEffect.getAmplifier(), + true, + foodEffect.shouldShowParticles(), + false + ); - e.addStatusEffect(nausea); - } + e.addStatusEffect(nausea); + } - e.damage(MagicalDamageSource.FOOD_POISONING, i); - }); + e.damage(MagicalDamageSource.FOOD_POISONING, i); + }).build(); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java index 2aaf6279..393911e2 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/UFoodComponents.java @@ -15,10 +15,12 @@ public interface UFoodComponents { FoodComponent HAY_FRIES = builder(1, 5).build(); FoodComponent SALAD = builder(4, 2).build(); FoodComponent CIDER = builder(4, 2).alwaysEdible().build(); - FoodComponent RANDOM_FOLIAGE = builder(2, 1).build(); + FoodComponent JUICE = builder(2, 2).alwaysEdible().build(); FoodComponent BURNED_JUICE = builder(3, 1).build(); - FoodComponent WORMS = builder(1, 0).alwaysEdible().build(); + + FoodComponent RANDOM_FOLIAGE = builder(2, 1).build(); + FoodComponent INSECTS = builder(1, 0).alwaysEdible().build(); FoodComponent CEREAL = builder(9, 0.8F).build(); FoodComponent SUGAR = builder(20, -2).build(); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java index a43b6671..54cb373c 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinItem.java @@ -20,6 +20,6 @@ import net.minecraft.world.World; 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().ifPresent(t -> tooltip.add(t.getAilmentFor(MinecraftClient.getInstance().player).getToxicity().getTooltip())); + getToxic().ifPresent(t -> t.getAilmentFor(MinecraftClient.getInstance().player).appendTooltip(tooltip, context)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/util/CustomStatusEffect.java b/src/main/java/com/minelittlepony/unicopia/util/CustomStatusEffect.java index a7c3c02c..5cbb15dc 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/CustomStatusEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/util/CustomStatusEffect.java @@ -11,47 +11,17 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; public class CustomStatusEffect extends StatusEffect { + private final boolean instant; + private final int rate; + private final Direct direct; + private final Indirect indirect; - private int tickDelay = 40; - - @NotNull - private DirectEffect direct = DirectEffect.NONE; - - @NotNull - private IndirectEffect indirect = IndirectEffect.NONE; - - public CustomStatusEffect(Identifier id, StatusEffectType type, int color) { + public CustomStatusEffect(StatusEffectType type, int color, int rate, boolean instant, Direct direct, Indirect indirect) { super(type, color); - - Registry.register(Registry.STATUS_EFFECT, id, this); - } - - public CustomStatusEffect setSilent() { - return this; - } - - public CustomStatusEffect direct(@NotNull DirectEffect applicator) { - this.direct = applicator; - - return this; - } - - public CustomStatusEffect indirect(@NotNull IndirectEffect applicator) { - this.indirect = applicator; - - return this; - } - - - public CustomStatusEffect setTickDelay(int delay) { - tickDelay = delay; - - return this; - } - - public CustomStatusEffect setEffectiveness(double effectiveness) { - - return this; + this.direct = direct; + this.rate = rate; + this.indirect = indirect; + this.instant = instant; } @Override @@ -66,32 +36,74 @@ public class CustomStatusEffect extends StatusEffect { @Override public boolean isInstant() { - return tickDelay > 0; + return instant; } @Override public boolean canApplyUpdateEffect(int duration, int amplifier) { - if (!isInstant()) { - int i = tickDelay >> amplifier; - - if (i > 0) { - return duration % i == 0; - } + if (isInstant()) { + return duration > 0; } - return duration > 0; + int i = rate >> amplifier; + return i <= 0 || duration % i == 0; + } + + public static class Builder { + private final Identifier id; + private final StatusEffectType type; + private final int color; + + private boolean instant; + private int rate = 40; + + @NotNull + private Direct direct = Direct.NONE; + + @NotNull + private Indirect indirect = Indirect.NONE; + + public Builder(Identifier id, StatusEffectType type, int color) { + this.id = id; + this.type = type; + this.color = color; + } + + public Builder instant() { + instant = true; + return this; + } + + public Builder rate(int rate) { + this.rate = rate; + return this; + } + + public Builder direct(@NotNull Direct applicator) { + this.direct = applicator; + return this; + } + + public Builder indirect(@NotNull Indirect applicator) { + this.indirect = applicator; + return this; + } + + public StatusEffect build() { + return Registry.register(Registry.STATUS_EFFECT, id, new CustomStatusEffect(type, color, rate, instant, direct, indirect)); + } } @FunctionalInterface - public interface DirectEffect { - DirectEffect NONE = (p, e, i) -> {}; + public interface Direct { + Direct NONE = (p, e, i) -> {}; void perform(StatusEffect effect, LivingEntity target, int amplifier); } @FunctionalInterface - public interface IndirectEffect { - IndirectEffect NONE = (p, s, a, t, A, d) -> {}; + public interface Indirect { + Indirect NONE = (p, s, a, t, A, d) -> {}; void perform(StatusEffect effect, @Nullable Entity source, @Nullable Entity attacker, LivingEntity target, int amplifier, double distance); } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index dc3f075c..ee724e07 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -74,7 +74,7 @@ "unicopia.effect.tribe.stage.determination": "As your bones realign you are filled by determination.", "unicopia.effect.tribe.stage.resurection": "Knowing you will return to this world as a %s", - "effect.food_poisoning": "Food Poisoning", + "effect.unicopia.food_poisoning": "Food Poisoning", "player.reachDistance": "Reach Distance", "player.miningSpeed": "Mining Speed", @@ -112,6 +112,8 @@ "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_bat": "Lingering Potion of Bat Pony Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_bat": "Arrow of Bat Pony Metamorphosis", + "potion.potency.6": "VII", + "spell.unicopia.frost": "Frost", "spell.unicopia.frost.lore": "Ice I", diff --git a/src/main/resources/data/unicopia/tags/items/cooked_fish.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_fish.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/cooked_fish.json rename to src/main/resources/data/unicopia/tags/items/food_types/cooked_fish.json diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json new file mode 100644 index 00000000..98efdfb9 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:fermented_spider_eye" + ] +} diff --git a/src/main/resources/data/unicopia/tags/items/cooked_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/cooked_meat.json rename to src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_blinding.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_blinding.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_blinding.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_blinding.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_dangerous.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_dangerous.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_dangerous.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_dangerous.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_edible.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_edible.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_edible.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_edible.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_nauseating.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_nauseating.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_nauseating.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_nauseating.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_prickly.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_prickly.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_prickly.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_prickly.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_radioactive.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_radioactive.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_radioactive.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_radioactive.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_risky.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_risky.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_risky.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_risky.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_severely_nauseating.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_nauseating.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_severely_nauseating.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_severely_nauseating.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_severely_prickly.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_prickly.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_severely_prickly.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_severely_prickly.json diff --git a/src/main/resources/data/unicopia/tags/items/forage_strengthening.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_strengthening.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/forage_strengthening.json rename to src/main/resources/data/unicopia/tags/items/food_types/forage_strengthening.json diff --git a/src/main/resources/data/unicopia/tags/items/raw_fish.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_fish.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/raw_fish.json rename to src/main/resources/data/unicopia/tags/items/food_types/raw_fish.json diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json new file mode 100644 index 00000000..be6db0b2 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:spider_eye", + "unicopia:wheat_worms" + ] +} diff --git a/src/main/resources/data/unicopia/tags/items/raw_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json similarity index 100% rename from src/main/resources/data/unicopia/tags/items/raw_meat.json rename to src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json diff --git a/src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json new file mode 100644 index 00000000..3f3bc662 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:rotten_flesh" + ] +}