Foods will have different effects on different tribes

This commit is contained in:
Sollace 2020-10-08 13:16:16 +02:00
parent d153df78fb
commit 05dc1aa132
10 changed files with 207 additions and 132 deletions

View file

@ -12,6 +12,7 @@ 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.util.Identifier;
@ -46,6 +47,19 @@ public enum Race implements Affine {
return this == CHANGELING ? Affinity.BAD : Affinity.NEUTRAL;
}
public boolean canConsume(FoodType type) {
if (!isUsable()) {
return type != FoodType.VEGAN;
}
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;
}

View file

@ -18,6 +18,7 @@ import com.minelittlepony.unicopia.entity.Physics;
import com.minelittlepony.unicopia.entity.PonyContainer;
import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.Trap;
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;
@ -393,7 +394,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
public void onEat(ItemStack stack) {
if (getSpecies() == Race.CHANGELING) {
Toxin.POISON.afflict(getOwner(), Toxicity.SAFE, stack);
Toxin.POISON.afflict(getOwner(), FoodType.RAW_MEAT, Toxicity.SAFE, stack);
}
}

View file

@ -0,0 +1,29 @@
package com.minelittlepony.unicopia.item.toxin;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
public class Ailment {
public static final Ailment INNERT = new Ailment(Toxicity.SAFE, Toxin.INNERT);
private final Toxicity toxicity;
private final Toxin toxin;
public Ailment(Toxicity toxicity, Toxin toxin) {
this.toxicity = toxicity;
this.toxin = toxin;
}
public Toxicity getToxicity() {
return toxicity;
}
public void afflict(PlayerEntity player, FoodType type, ItemStack stack) {
this.toxin.afflict(player, type, toxicity, stack);
}
public static Ailment of(Toxicity toxicity) {
return new Ailment(toxicity, Toxin.FOOD);
}
}

View file

@ -0,0 +1,19 @@
package com.minelittlepony.unicopia.item.toxin;
public enum FoodType {
RAW_MEAT, COOKED_MEAT,
RAW_FISH, COOKED_FISH,
VEGAN;
public boolean isRaw() {
return this == RAW_MEAT || this == RAW_FISH || this == VEGAN;
}
public boolean isMeat() {
return this == RAW_MEAT || this == COOKED_MEAT;
}
public boolean isFish() {
return this == RAW_FISH || this == COOKED_FISH;
}
}

View file

@ -1,63 +1,66 @@
package com.minelittlepony.unicopia.item.toxin;
import java.util.function.Function;
import java.util.function.Supplier;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
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.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.UseAction;
import net.minecraft.world.World;
public class Toxic {
private final UseAction action;
private final Function<ItemStack, Toxicity> toxicity;
private final Toxin toxin;
Toxic(UseAction action, Toxin toxin, Toxicity toxicity) {
this(action, toxin, stack -> toxicity);
}
private final Ailment lowerBound;
private final Ailment upperBound;
Toxic(UseAction action, Toxin toxin, Function<ItemStack, Toxicity> toxicity) {
private final FoodType type;
Toxic(UseAction action, FoodType type, Ailment lowerBound, Ailment upperBound) {
this.action = action;
this.toxin = toxin;
this.toxicity = toxicity;
this.type = type;
this.lowerBound = lowerBound;
this.upperBound = upperBound;
}
public UseAction getUseAction(ItemStack stack) {
return action;
}
@Environment(EnvType.CLIENT)
public Text getTooltip(ItemStack stack) {
return toxicity.apply(stack).getTooltip();
Pony pony = Pony.of(MinecraftClient.getInstance().player);
if (pony != null && !pony.getSpecies().canConsume(type)) {
return upperBound.getToxicity().getTooltip();
}
return lowerBound.getToxicity().getTooltip();
}
public ItemStack finishUsing(ItemStack stack, World world, LivingEntity entity) {
if (entity instanceof PlayerEntity) {
Race race = Pony.of((PlayerEntity)entity).getSpecies();
Toxicity t = race.hasIronGut() ? toxicity.apply(stack) : Toxicity.LETHAL;
toxin.afflict((PlayerEntity)entity, t, stack);
(race.canConsume(type) ? lowerBound : upperBound).afflict((PlayerEntity)entity, type, stack);
}
return stack;
}
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand, Supplier<TypedActionResult<ItemStack>> sup) {
Race race = Pony.of(player).getSpecies();
if (race.hasIronGut()) {
return sup.get();
if (!Pony.of(player).getSpecies().hasIronGut()) {
return TypedActionResult.fail(player.getStackInHand(hand));
}
return new TypedActionResult<>(ActionResult.FAIL, player.getStackInHand(hand));
return sup.get();
}
}

View file

@ -5,16 +5,11 @@ import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.Tag;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
public enum Toxicity implements Toxin {
public enum Toxicity {
SAFE(0, 0),
MILD(1, 160),
FAIR(1, 30),
@ -31,6 +26,14 @@ public enum Toxicity implements Toxin {
this.duration = duration;
}
public int getLevel() {
return level;
}
public int getDuration() {
return duration;
}
public boolean isMild() {
return this == MILD;
}
@ -57,34 +60,6 @@ public enum Toxicity implements Toxin {
.withColor(toxicWhenCooked() ? Formatting.RED : toxicWhenRaw() ? Formatting.DARK_PURPLE : Formatting.GRAY));
}
public ItemStack ontoStack(ItemStack stack) {
stack.getOrCreateTag().putString("toxicity", name());
return stack;
}
@Override
public void afflict(PlayerEntity player, Toxicity toxicity, ItemStack stack) {
if (toxicWhenRaw()) {
player.addStatusEffect(new StatusEffectInstance(isMild() ? StatusEffects.NAUSEA : StatusEffects.POISON, duration, level));
}
if (isLethal()) {
player.addStatusEffect(new StatusEffectInstance(UEffects.FOOD_POISONING, 300, 7, false, false));
} else if (toxicWhenCooked()) {
WEAK_NAUSEA.afflict(player, toxicity, stack);
}
}
public static Toxicity fromStack(ItemStack stack) {
if (stack.hasTag()) {
Tag tag = stack.getTag().get("toxicity");
if (tag != null) {
return REGISTRY.getOrDefault(tag.asString(), SAFE);
}
}
return SAFE;
}
public static Toxicity byName(String name) {
return REGISTRY.get(name.toUpperCase());
}

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.item.toxin;
import java.util.Objects;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
@ -7,34 +9,56 @@ import net.minecraft.util.UseAction;
public interface Toxics {
Toxic GRASS = register(Items.GRASS, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD.and(Toxin.NAUSEA));
Toxic FERN = register(Items.FERN, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.STRENGTH));
Toxic DEAD_BUSH = register(Items.DEAD_BUSH, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.NAUSEA));
Toxic GRASS = register(Items.GRASS, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE, Toxin.NAUSEA);
Toxic FERN = register(Items.FERN, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SEVERE, Toxin.STRENGTH);
Toxic DEAD_BUSH = register(Items.DEAD_BUSH, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SEVERE, Toxin.NAUSEA);
Toxic DANDELION = register(Items.DANDELION, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic POPPY = register(Items.POPPY, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD);
Toxic BLUE_ORCHID = register(Items.BLUE_ORCHID, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic ALLIUM = register(Items.ALLIUM, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.FAIR, Toxin.FOOD);
Toxic AZUER_BLUET = register(Items.AZURE_BLUET, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD.and(Toxin.RADIOACTIVITY));
Toxic RED_TULIP = register(Items.RED_TULIP, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic ORANGE_TULIP = register(Items.ORANGE_TULIP, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic WHITE_TULIP = register(Items.WHITE_TULIP, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.FAIR, Toxin.FOOD);
Toxic PINK_TULIP = register(Items.PINK_TULIP, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic OXEYE_DAISY = register(Items.OXEYE_DAISY, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.BLINDNESS));
Toxic CORNFLOWER = register(Items.CORNFLOWER, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic DANDELION = register(Items.DANDELION, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic POPPY = register(Items.POPPY, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SEVERE);
Toxic BLUE_ORCHID = register(Items.BLUE_ORCHID, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic ALLIUM = register(Items.ALLIUM, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.FAIR);
Toxic AZUER_BLUET = register(Items.AZURE_BLUET, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE, Toxin.RADIOACTIVITY);
Toxic RED_TULIP = register(Items.RED_TULIP, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic ORANGE_TULIP = register(Items.ORANGE_TULIP, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic WHITE_TULIP = register(Items.WHITE_TULIP, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.FAIR);
Toxic PINK_TULIP = register(Items.PINK_TULIP, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic OXEYE_DAISY = register(Items.OXEYE_DAISY, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SEVERE, Toxin.BLINDNESS);
Toxic CORNFLOWER = register(Items.CORNFLOWER, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic ROSE_BUSH = register(Items.ROSE_BUSH, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD.and(Toxin.DAMAGE));
Toxic PEONY = register(Items.PEONY, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic TALL_GRASS = register(Items.TALL_GRASS, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD);
Toxic LARGE_FERN = register(Items.LARGE_FERN, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.DAMAGE));
Toxic ROSE_BUSH = register(Items.ROSE_BUSH, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE, Toxin.DAMAGE);
Toxic PEONY = register(Items.PEONY, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic TALL_GRASS = register(Items.TALL_GRASS, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic LARGE_FERN = register(Items.LARGE_FERN, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SEVERE, Toxin.DAMAGE);
Toxic RAW_MEAT = register(new Toxic(UseAction.EAT, FoodType.RAW_MEAT, Ailment.INNERT, Ailment.of(Toxicity.MILD)), Items.PORKCHOP, Items.BEEF, Items.MUTTON, Items.RABBIT);
Toxic COOKED_MEAT = register(new Toxic(UseAction.EAT, FoodType.COOKED_MEAT, Ailment.INNERT, Ailment.of(Toxicity.MILD)), Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.COOKED_MUTTON, Items.COOKED_RABBIT);
Toxic RAW_FISH = register(new Toxic(UseAction.EAT, FoodType.RAW_FISH, Ailment.INNERT, Ailment.of(Toxicity.FAIR)), Items.PUFFERFISH, Items.COD, Items.SALMON);
Toxic COOKED_FISH = register(new Toxic(UseAction.EAT, FoodType.COOKED_FISH, Ailment.INNERT, Ailment.of(Toxicity.FAIR)), Items.COOKED_COD, Items.COOKED_SALMON);
static void bootstrap() {}
static Toxic register(Item target, FoodComponent food, UseAction action, Toxicity toxicity, Toxin toxin) {
Toxic toxic = new Toxic(action, toxin, toxicity);
static Toxic register(Item target, FoodComponent food, FoodType type, UseAction action, Toxicity toxicity) {
return register(target, food, type, action, Ailment.of(toxicity), Ailment.of(Toxicity.LETHAL));
}
static Toxic register(Item target, FoodComponent food, FoodType type, UseAction action, Toxicity toxicity, Toxin toxin) {
toxin = Toxin.FOOD.and(toxin);
return register(target, food, type, action, new Ailment(toxicity, toxin), new Ailment(Toxicity.LETHAL, toxin));
}
static Toxic register(Item target, FoodComponent food, FoodType type, UseAction action, Ailment lowerBound, Ailment upperbound) {
Toxic toxic = new Toxic(action, type, lowerBound, upperbound);
ToxicHolder holder = (ToxicHolder)target;
holder.setFood(food);
holder.setToxic(toxic);
holder.setFood(Objects.requireNonNull(food, target.getName().toString() + " food"));
return toxic;
}
static Toxic register(Toxic toxic, Item... items) {
for (Item i : items) {
((ToxicHolder)i).setToxic(toxic);
}
return toxic;
}
}

View file

@ -10,16 +10,16 @@ import net.minecraft.world.Difficulty;
@FunctionalInterface
public interface Toxin {
Predicate ONE_EVERY_30_TICKS = (player, toxicity, stack) -> player.world.random.nextInt(30) == 0;
Predicate ONE_EVERY_30_TICKS = (player, type, toxicity, stack) -> player.world.random.nextInt(30) == 0;
Toxin FOOD = (player, toxicity, stack) -> toxicity.afflict(player, toxicity, stack);
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, toxicity, stack) -> {
Toxin POISON = (player, type, toxicity, stack) -> {
FoodComponent food = stack.getItem().getFoodComponent();
player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2);
@ -31,19 +31,30 @@ public interface Toxin {
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()));
}
void afflict(PlayerEntity player, Toxicity toxicity, ItemStack stack);
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);
default Toxin and(Toxin other) {
Toxin self = this;
return (player, toxicity, stack) -> {
self.afflict(player, toxicity, stack);
other.afflict(player, toxicity, stack);
return (player, type, toxicity, stack) -> {
self.afflict(player, type, toxicity, stack);
other.afflict(player, type, toxicity, stack);
};
}
static Toxin of(StatusEffect effect, int duration, int amplifier) {
return (player, toxicity, stack) -> afflict(player, effect, duration, amplifier);
return (player, type, toxicity, stack) -> afflict(player, effect, duration, amplifier);
}
static void afflict(PlayerEntity player, StatusEffect effect, int duration, int amplifier) {
@ -51,11 +62,11 @@ public interface Toxin {
}
interface Predicate {
boolean test(PlayerEntity player, Toxicity toxicity, ItemStack stack);
boolean test(PlayerEntity player, FoodType type, Toxicity toxicity, ItemStack stack);
default Toxin then(Toxin toxin) {
return (player, toxicity, stack) -> {
if (test(player, toxicity, stack)) {
toxin.afflict(player, toxicity, stack);
return (player, type, toxicity, stack) -> {
if (test(player, type, toxicity, stack)) {
toxin.afflict(player, type, toxicity, stack);
}
};
}

View file

@ -1,25 +1,12 @@
package com.minelittlepony.unicopia.mixin;
import java.util.List;
import java.util.Optional;
import javax.annotation.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.Toxic;
import com.minelittlepony.unicopia.item.toxin.ToxicHolder;
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.Item;
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;
@ -29,47 +16,19 @@ import net.minecraft.world.World;
abstract class MixinBlockItem extends Item implements ToxicHolder {
public MixinBlockItem() {super(null); }
private Optional<Toxic> toxic = Optional.empty();
@Override
public void setToxic(Toxic toxic) {
this.toxic = Optional.of(toxic);
}
@Override
public Optional<Toxic> getToxic() {
return toxic;
}
@Override
public UseAction getUseAction(ItemStack stack) {
if (toxic.isPresent()) {
return toxic.get().getUseAction(stack);
if (getToxic().isPresent()) {
return getToxic().get().getUseAction(stack);
}
return super.getUseAction(stack);
}
@Inject(method = "appendTooltip", at = @At("RETURN"))
private void onAppendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context, CallbackInfo into) {
if (toxic.isPresent()) {
tooltip.add(toxic.get().getTooltip(stack));
}
}
@Override
public ItemStack finishUsing(ItemStack stack, World world, LivingEntity entity) {
ItemStack result = super.finishUsing(stack, world, entity);
if (toxic.isPresent()) {
return toxic.get().finishUsing(stack, world, entity);
}
return result;
}
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
if (!toxic.isPresent()) {
return super.use(world, player, hand);
if (getToxic().isPresent()) {
return getToxic().get().use(world, player, hand, () -> super.use(world, player, hand));
}
return toxic.get().use(world, player, hand, () -> super.use(world, player, hand));
return super.use(world, player, hand);
}
}

View file

@ -1,16 +1,56 @@
package com.minelittlepony.unicopia.mixin;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.item.toxin.Toxic;
import com.minelittlepony.unicopia.item.toxin.ToxicHolder;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.FoodComponent;
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 {
private Optional<Toxic> toxic = Optional.empty();
@Override
@Accessor("foodComponent")
public abstract void setFood(FoodComponent food);
@Override
public void setToxic(Toxic toxic) {
this.toxic = Optional.of(toxic);
}
@Override
public Optional<Toxic> getToxic() {
return toxic;
}
@Inject(method = "appendTooltip", at = @At("RETURN"))
private void onAppendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context, CallbackInfo into) {
toxic.ifPresent(t -> tooltip.add(t.getTooltip(stack)));
}
@Inject(method = "finishUsing", at = @At("HEAD"), cancellable = true)
private void finishUsing(ItemStack stack, World world, LivingEntity entity, CallbackInfoReturnable<ItemStack> info) {
if (getToxic().isPresent()) {
getToxic().get().finishUsing(stack, world, entity);
}
}
}