diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index c6ba480c..7eb7649b 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -27,6 +27,7 @@ public interface UTags { TagKey SPOOKED_MOB_DROPS = item("spooked_mob_drops"); TagKey IS_DELIVERED_AGGRESSIVELY = item("is_delivered_aggressively"); TagKey FLOATS_ON_CLOUDS = item("floats_on_clouds"); + TagKey COOLS_OFF_KIRINS = item("cools_off_kirins"); TagKey POLEARMS = item("polearms"); TagKey HORSE_SHOES = item("horse_shoes"); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RageAbilitySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RageAbilitySpell.java index f12938b0..1f3e2ada 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RageAbilitySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RageAbilitySpell.java @@ -30,11 +30,17 @@ public class RageAbilitySpell extends AbstractSpell { private int age; private int ticksExtenguishing; + private int ticksToExtenguish; + public RageAbilitySpell(CustomisedSpellType type) { super(type); setHidden(true); } + public void setExtenguishing() { + ticksToExtenguish += 15; + } + @Override public boolean tick(Caster source, Situation situation) { @@ -42,7 +48,7 @@ public class RageAbilitySpell extends AbstractSpell { return false; } - if (source.asEntity().isInsideWaterOrBubbleColumn()) { + if (source.asEntity().isInsideWaterOrBubbleColumn() || source.asEntity().isFrozen() || ticksToExtenguish > 0) { ticksExtenguishing++; source.playSound(SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, 1); source.spawnParticles(ParticleTypes.CLOUD, 12); @@ -51,6 +57,10 @@ public class RageAbilitySpell extends AbstractSpell { ticksExtenguishing = 0; } + if (ticksToExtenguish > 0) { + ticksToExtenguish--; + } + if (ticksExtenguishing > 10) { return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/effect/FoodPoisoningStatusEffect.java b/src/main/java/com/minelittlepony/unicopia/entity/effect/FoodPoisoningStatusEffect.java index e8bd62a7..f216cc67 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/effect/FoodPoisoningStatusEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/FoodPoisoningStatusEffect.java @@ -12,10 +12,8 @@ import net.minecraft.entity.effect.StatusEffectCategory; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FoodComponent; -import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.sound.SoundCategory; -import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; public class FoodPoisoningStatusEffect extends StatusEffect { @@ -54,18 +52,18 @@ public class FoodPoisoningStatusEffect extends StatusEffect { return i <= 0 || duration % i == 0; } - public static TypedActionResult apply(ItemConvertible sender, PlayerEntity user, Hand hand) { + public static TypedActionResult apply(ItemStack stack, PlayerEntity user) { @Nullable - FoodComponent food = sender.asItem().getFoodComponent(); + FoodComponent food = stack.getItem().getFoodComponent(); if (food == null || !user.canConsume(food.isAlwaysEdible()) || !user.hasStatusEffect(UEffects.FOOD_POISONING)) { - return TypedActionResult.pass(user.getStackInHand(hand)); + return TypedActionResult.pass(stack); } user.getWorld().playSound(null, user.getX(), user.getY(), user.getZ(), USounds.Vanilla.ENTITY_PLAYER_BURP, SoundCategory.NEUTRAL, 1, 1 + (user.getWorld().random.nextFloat() - user.getWorld().random.nextFloat()) * 0.4f); user.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 100, 1, true, false, false)); - return TypedActionResult.fail(user.getStackInHand(hand)); + return TypedActionResult.fail(stack); } } 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 538dd8d6..6a12cabe 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.ability.*; import com.minelittlepony.unicopia.ability.magic.*; import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod; +import com.minelittlepony.unicopia.ability.magic.spell.RageAbilitySpell; import com.minelittlepony.unicopia.ability.magic.spell.Spell; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.TraitDiscovery; @@ -53,6 +54,8 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.particle.ParticleTypes; +import net.minecraft.potion.PotionUtil; +import net.minecraft.potion.Potions; import net.minecraft.registry.tag.DamageTypeTags; import net.minecraft.registry.tag.FluidTags; import net.minecraft.server.network.ServerPlayerEntity; @@ -428,7 +431,7 @@ public class Pony extends Living implements Copyable, Update if (getObservedSpecies() == Race.KIRIN) { var charge = getMagicalReserves().getCharge(); - if (entity.isTouchingWater()) { + if (entity.isTouchingWater() || entity.isFrozen()) { charge.multiply(0.5F); } @@ -734,6 +737,18 @@ public class Pony extends Living implements Copyable, Update return Optional.empty(); } + public void onEat(ItemStack stack) { + if (isClient()) { + return; + } + + if (getObservedSpecies() == Race.KIRIN + && (stack.isIn(UTags.COOLS_OFF_KIRINS) || PotionUtil.getPotion(stack) == Potions.WATER)) { + getMagicalReserves().getCharge().multiply(0.5F); + getSpellSlot().get(SpellType.RAGE, false).ifPresent(RageAbilitySpell::setExtenguishing); + } + } + @SuppressWarnings("deprecation") @Override protected void handleFall(float distance, float damageMultiplier, DamageSource cause) { 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 8da95eff..0fa02187 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Ailment.java @@ -7,11 +7,7 @@ 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.ItemStack; import net.minecraft.text.Text; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.world.World; public record Ailment ( Toxicity toxicity, @@ -31,13 +27,6 @@ public record Ailment ( } } - public TypedActionResult use(World world, PlayerEntity player, Hand hand) { - if (!Pony.of(player).getObservedSpecies().hasIronGut()) { - return TypedActionResult.fail(player.getStackInHand(hand)); - } - return null; - } - public interface Set { Set EMPTY = e -> Optional.empty(); 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 9ae67b13..d2810839 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxic.java @@ -6,13 +6,17 @@ 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; @@ -37,11 +41,20 @@ public record Toxic ( ailment.get(player).ifPresent(ailment -> ailment.appendTooltip(tooltip, context)); } - public ItemStack finishUsing(ItemStack stack, World world, LivingEntity entity) { + 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)); } - return stack; + if (stack.isFood() || stack.getUseAction() == UseAction.DRINK) { + Pony.of(entity).ifPresent(pony -> pony.onEat(stack)); + } } @Deprecated diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java index 63e33c3a..5cb06970 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBlockItem.java @@ -9,15 +9,11 @@ import com.minelittlepony.unicopia.item.toxin.ToxicHolder; import com.minelittlepony.unicopia.server.world.WaterLoggingManager; import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; import net.minecraft.util.UseAction; -import net.minecraft.world.World; @Mixin(BlockItem.class) abstract class MixinBlockItem extends Item implements ToxicHolder { @@ -28,15 +24,6 @@ abstract class MixinBlockItem extends Item implements ToxicHolder { return getToxic(stack, null).useAction().orElseGet(() -> super.getUseAction(stack)); } - @Override - public TypedActionResult use(World world, PlayerEntity player, Hand hand) { - return getToxic(player.getStackInHand(hand), player) - .ailment() - .get(player) - .map(t -> t.use(world, player, hand)) - .orElseGet(() -> super.use(world, player, hand)); - } - @Inject(method = "getPlacementState", at = @At("RETURN"), cancellable = true) private void onGetPlacementState(ItemPlacementContext context, CallbackInfoReturnable info) { WaterLoggingManager.getInstance().getPlacementState(context, info); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java index 7dfb69ab..5670dbbe 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java @@ -8,25 +8,15 @@ 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 org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - import com.google.common.base.Suppliers; import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.entity.ItemImpl.GroundTickCallback; -import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect; import com.minelittlepony.unicopia.item.toxin.*; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FoodComponent; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.world.World; @Mixin(Item.class) abstract class MixinItem implements ItemDuck { @@ -50,19 +40,4 @@ abstract class MixinItem implements ItemDuck { } return Toxics.lookup(this, entity); } - - @Inject(method = "finishUsing", at = @At("HEAD")) - private void finishUsing(ItemStack stack, World world, LivingEntity entity, CallbackInfoReturnable info) { - getToxic(stack, entity).finishUsing(stack, world, entity); - } - - @Inject(method = "use", at = @At("HEAD"), cancellable = true) - private void use(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> info) { - // ensure the food component is updated before attempting to use - getToxic(user.getStackInHand(hand), user); - TypedActionResult result = FoodPoisoningStatusEffect.apply(this, user, hand); - if (result.getResult() != ActionResult.PASS) { - info.setReturnValue(result); - } - } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java new file mode 100644 index 00000000..118f1b4c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java @@ -0,0 +1,34 @@ +package com.minelittlepony.unicopia.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.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.item.toxin.ToxicHolder; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; + +@Mixin(ItemStack.class) +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); + if (result.getResult() != ActionResult.PASS) { + info.setReturnValue(result); + } + } + + @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); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java index 71d0907c..d61ad769 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java @@ -29,6 +29,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.stat.Stats; import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; @Mixin(PlayerEntity.class) abstract class MixinPlayerEntity extends LivingEntity implements Equine.Container, PlayerEntityDuck { @@ -42,6 +43,11 @@ abstract class MixinPlayerEntity extends LivingEntity implements Equine.Containe return new Pony((PlayerEntity)(Object)this); } + @Inject(method = "createPlayerAttributes()Lnet/minecraft/entity/attribute/DefaultAttributeContainer$Builder;", at = @At("RETURN")) + private static void onCreateAttributes(CallbackInfoReturnable info) { + Pony.registerAttributes(info.getReturnValue()); + } + @ModifyVariable(method = "applyDamage(Lnet/minecraft/entity/damage/DamageSource;F)V", at = @At("HEAD"), ordinal = 0) protected float modifyDamageAmount(float amount, DamageSource source) { return get().modifyDamage(source, amount).orElse(amount); @@ -60,9 +66,9 @@ abstract class MixinPlayerEntity extends LivingEntity implements Equine.Containe }); } - @Inject(method = "createPlayerAttributes()Lnet/minecraft/entity/attribute/DefaultAttributeContainer$Builder;", at = @At("RETURN")) - private static void onCreateAttributes(CallbackInfoReturnable info) { - Pony.registerAttributes(info.getReturnValue()); + @Inject(method = "eatFood(Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;", at = @At("HEAD")) + private void onEatFood(World world, ItemStack stack, CallbackInfoReturnable info) { + get().onEat(stack); } @Inject(method = "trySleep(Lnet/minecraft/util/math/BlockPos;)Lcom/mojang/datafixers/util/Either;", diff --git a/src/main/resources/data/unicopia/tags/items/cools_off_kirins.json b/src/main/resources/data/unicopia/tags/items/cools_off_kirins.json new file mode 100644 index 00000000..15e752ad --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/cools_off_kirins.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + "minecraft:melon_slice", + "unicopia:juice", + { "id": "farmersdelight:melon_popsicle", "required": false }, + { "id": "farmersdelight:melon_juice", "required": false } + ] +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 5acbbf09..b6e5e32b 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -27,6 +27,7 @@ "MixinGuardianTargetPredicate", "MixinItem", "MixinItemEntity", + "MixinItemStack", "MixinLivingEntity", "MixinMilkBucketItem", "MixinMobEntity",