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.sprite.TextureSprite;
import com.minelittlepony.common.client.gui.style.Style; import com.minelittlepony.common.client.gui.style.Style;
import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.item.toxin.FoodType;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -46,6 +47,19 @@ public enum Race implements Affine {
return this == CHANGELING ? Affinity.BAD : Affinity.NEUTRAL; 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() { public boolean hasIronGut() {
return isUsable() && this != CHANGELING; 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.PonyContainer;
import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.Trap; 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.Toxicity;
import com.minelittlepony.unicopia.item.toxin.Toxin; import com.minelittlepony.unicopia.item.toxin.Toxin;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
@ -393,7 +394,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
public void onEat(ItemStack stack) { public void onEat(ItemStack stack) {
if (getSpecies() == Race.CHANGELING) { 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; package com.minelittlepony.unicopia.item.toxin;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.entity.player.Pony; 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.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
import net.minecraft.util.UseAction; import net.minecraft.util.UseAction;
import net.minecraft.world.World; import net.minecraft.world.World;
public class Toxic { public class Toxic {
private final UseAction action; private final UseAction action;
private final Function<ItemStack, Toxicity> toxicity;
private final Toxin toxin;
Toxic(UseAction action, Toxin toxin, Toxicity toxicity) { private final Ailment lowerBound;
this(action, toxin, stack -> toxicity); 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.action = action;
this.toxin = toxin; this.type = type;
this.toxicity = toxicity; this.lowerBound = lowerBound;
this.upperBound = upperBound;
} }
public UseAction getUseAction(ItemStack stack) { public UseAction getUseAction(ItemStack stack) {
return action; return action;
} }
@Environment(EnvType.CLIENT)
public Text getTooltip(ItemStack stack) { 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) { public ItemStack finishUsing(ItemStack stack, World world, LivingEntity entity) {
if (entity instanceof PlayerEntity) { if (entity instanceof PlayerEntity) {
Race race = Pony.of((PlayerEntity)entity).getSpecies(); 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; return stack;
} }
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand, Supplier<TypedActionResult<ItemStack>> sup) { public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand, Supplier<TypedActionResult<ItemStack>> sup) {
Race race = Pony.of(player).getSpecies();
if (race.hasIronGut()) { if (!Pony.of(player).getSpecies().hasIronGut()) {
return sup.get(); 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.function.Function;
import java.util.stream.Collectors; 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.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
public enum Toxicity implements Toxin { public enum Toxicity {
SAFE(0, 0), SAFE(0, 0),
MILD(1, 160), MILD(1, 160),
FAIR(1, 30), FAIR(1, 30),
@ -31,6 +26,14 @@ public enum Toxicity implements Toxin {
this.duration = duration; this.duration = duration;
} }
public int getLevel() {
return level;
}
public int getDuration() {
return duration;
}
public boolean isMild() { public boolean isMild() {
return this == MILD; return this == MILD;
} }
@ -57,34 +60,6 @@ public enum Toxicity implements Toxin {
.withColor(toxicWhenCooked() ? Formatting.RED : toxicWhenRaw() ? Formatting.DARK_PURPLE : Formatting.GRAY)); .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) { public static Toxicity byName(String name) {
return REGISTRY.get(name.toUpperCase()); return REGISTRY.get(name.toUpperCase());
} }

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.item.toxin; package com.minelittlepony.unicopia.item.toxin;
import java.util.Objects;
import net.minecraft.item.FoodComponent; import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.Items; import net.minecraft.item.Items;
@ -7,34 +9,56 @@ import net.minecraft.util.UseAction;
public interface Toxics { public interface Toxics {
Toxic GRASS = register(Items.GRASS, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, 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, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.STRENGTH)); 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, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.NAUSEA)); 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 DANDELION = register(Items.DANDELION, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic POPPY = register(Items.POPPY, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD); Toxic POPPY = register(Items.POPPY, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SEVERE);
Toxic BLUE_ORCHID = register(Items.BLUE_ORCHID, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); Toxic BLUE_ORCHID = register(Items.BLUE_ORCHID, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic ALLIUM = register(Items.ALLIUM, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.FAIR, Toxin.FOOD); Toxic ALLIUM = register(Items.ALLIUM, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.FAIR);
Toxic AZUER_BLUET = register(Items.AZURE_BLUET, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD.and(Toxin.RADIOACTIVITY)); 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, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); 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, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); 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, UseAction.EAT, Toxicity.FAIR, Toxin.FOOD); 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, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); 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, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.BLINDNESS)); 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, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); 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 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, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); Toxic PEONY = register(Items.PEONY, UFoodComponents.RANDOM_FOLIAGE, FoodType.VEGAN, UseAction.EAT, Toxicity.SAFE);
Toxic TALL_GRASS = register(Items.TALL_GRASS, UFoodComponents.RANDOM_FOLIAGE, UseAction.EAT, Toxicity.SAFE, Toxin.FOOD); 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, UseAction.EAT, Toxicity.SEVERE, Toxin.FOOD.and(Toxin.DAMAGE)); 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 void bootstrap() {}
static Toxic register(Item target, FoodComponent food, UseAction action, Toxicity toxicity, Toxin toxin) { static Toxic register(Item target, FoodComponent food, FoodType type, UseAction action, Toxicity toxicity) {
Toxic toxic = new Toxic(action, toxin, 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; ToxicHolder holder = (ToxicHolder)target;
holder.setFood(food);
holder.setToxic(toxic); 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; return toxic;
} }
} }

View file

@ -10,16 +10,16 @@ import net.minecraft.world.Difficulty;
@FunctionalInterface @FunctionalInterface
public interface Toxin { 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 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 RADIOACTIVITY = ONE_EVERY_30_TICKS.then(of(StatusEffects.GLOWING, 10, 1));
Toxin NAUSEA = of(StatusEffects.NAUSEA, 30, 1); Toxin NAUSEA = of(StatusEffects.NAUSEA, 30, 1);
Toxin WEAK_NAUSEA = of(StatusEffects.NAUSEA, 3, 1); Toxin WEAK_NAUSEA = of(StatusEffects.NAUSEA, 3, 1);
Toxin STRENGTH = of(StatusEffects.STRENGTH, 30, 1); Toxin STRENGTH = of(StatusEffects.STRENGTH, 30, 1);
Toxin BLINDNESS = of(StatusEffects.BLINDNESS, 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(); FoodComponent food = stack.getItem().getFoodComponent();
player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2); player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2);
@ -31,19 +31,30 @@ public interface Toxin {
afflict(player, StatusEffects.WEAKNESS, 2000, 20); 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) { default Toxin and(Toxin other) {
Toxin self = this; Toxin self = this;
return (player, toxicity, stack) -> { return (player, type, toxicity, stack) -> {
self.afflict(player, toxicity, stack); self.afflict(player, type, toxicity, stack);
other.afflict(player, toxicity, stack); other.afflict(player, type, toxicity, stack);
}; };
} }
static Toxin of(StatusEffect effect, int duration, int amplifier) { 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) { static void afflict(PlayerEntity player, StatusEffect effect, int duration, int amplifier) {
@ -51,11 +62,11 @@ public interface Toxin {
} }
interface Predicate { 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) { default Toxin then(Toxin toxin) {
return (player, toxicity, stack) -> { return (player, type, toxicity, stack) -> {
if (test(player, toxicity, stack)) { if (test(player, type, toxicity, stack)) {
toxin.afflict(player, toxicity, stack); toxin.afflict(player, type, toxicity, stack);
} }
}; };
} }

View file

@ -1,25 +1,12 @@
package com.minelittlepony.unicopia.mixin; 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.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 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.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
import net.minecraft.util.UseAction; import net.minecraft.util.UseAction;
@ -29,47 +16,19 @@ import net.minecraft.world.World;
abstract class MixinBlockItem extends Item implements ToxicHolder { abstract class MixinBlockItem extends Item implements ToxicHolder {
public MixinBlockItem() {super(null); } 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 @Override
public UseAction getUseAction(ItemStack stack) { public UseAction getUseAction(ItemStack stack) {
if (toxic.isPresent()) { if (getToxic().isPresent()) {
return toxic.get().getUseAction(stack); return getToxic().get().getUseAction(stack);
} }
return super.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 @Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) { public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
if (!toxic.isPresent()) { if (getToxic().isPresent()) {
return super.use(world, player, hand); 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; 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.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; 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 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.FoodComponent;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.world.World;
@Mixin(Item.class) @Mixin(Item.class)
abstract class MixinItem implements ToxicHolder { abstract class MixinItem implements ToxicHolder {
private Optional<Toxic> toxic = Optional.empty();
@Override @Override
@Accessor("foodComponent") @Accessor("foodComponent")
public abstract void setFood(FoodComponent food); 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);
}
}
} }