From f9182f851fd5b0f57777b18250e2fbc1f21291b4 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 3 Sep 2023 15:51:05 +0100 Subject: [PATCH] Reimplement food poisoning to be more like the BTW food poisoning and use it instead of nausea/poison --- .../unicopia/client/gui/UHud.java | 15 ++++ .../unicopia/entity/Living.java | 6 ++ .../unicopia/entity/damage/UDamageTypes.java | 1 - .../unicopia/entity/effect/EffectUtils.java | 18 +++++ .../effect/FoodPoisoningStatusEffect.java | 47 +++++++---- .../entity/effect/RaceChangeStatusEffect.java | 9 --- .../unicopia/item/toxin/ToxicHolder.java | 2 +- .../unicopia/item/toxin/Toxics.java | 74 ++++++++---------- .../unicopia/item/toxin/Toxin.java | 23 +++--- .../unicopia/mixin/MixinItem.java | 15 +++- .../unicopia/mixin/client/MixinInGameHud.java | 37 +++++++-- .../mixin/client/MixinKeyboardInput.java | 28 ++++--- .../textures/mob_effect/paralysis.png | Bin 0 -> 4621 bytes src/main/resources/unicopia.aw | 1 + 14 files changed, 183 insertions(+), 93 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/effect/EffectUtils.java create mode 100644 src/main/resources/assets/unicopia/textures/mob_effect/paralysis.png diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java index 3ed8da67..bc8c5e76 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellTyp import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.client.sound.*; import com.minelittlepony.unicopia.entity.ItemTracker; +import com.minelittlepony.unicopia.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect; import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.player.Pony; @@ -304,4 +305,18 @@ public class UHud { context.drawTexture(ability.getIcon(Pony.of(client.player)), x, y, 0, 0, frameWidth, frameHeight, u, v); }); } + + + @Nullable + public static InGameHud.HeartType getHeartsType(PlayerEntity player) { + if (UItems.ALICORN_AMULET.isApplicable(player) || EffectUtils.isChangingRace(player)) { + return InGameHud.HeartType.WITHERED; + } + + if (EffectUtils.isPoisoned(player)) { + return InGameHud.HeartType.POISONED; + } + + return null; + } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index cf082513..2a473654 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -20,6 +20,7 @@ import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; +import com.minelittlepony.unicopia.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.input.Heuristic; @@ -256,6 +257,11 @@ public abstract class Living implements Equine, Caste @Override public boolean beforeUpdate() { + if (EffectUtils.getAmplifier(entity, UEffects.PARALYSIS) > 1 && entity.getVelocity().horizontalLengthSquared() > 0) { + entity.setVelocity(entity.getVelocity().multiply(0, 1, 0)); + updateVelocity(); + } + updateSupportingEntity(); return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java b/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java index faeb083b..51b6a882 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java @@ -16,7 +16,6 @@ public interface UDamageTypes { RegistryKey EXHAUSTION = register("magical_exhaustion"); RegistryKey ALICORN_AMULET = register("alicorn_amulet"); - RegistryKey FOOD_POISONING = register("food_poisoning"); RegistryKey TRIBE_SWAP = register("tribe_swap"); RegistryKey ZAP_APPLE = register("zap"); RegistryKey KICK = register("kick"); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/effect/EffectUtils.java b/src/main/java/com/minelittlepony/unicopia/entity/effect/EffectUtils.java new file mode 100644 index 00000000..14372955 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/EffectUtils.java @@ -0,0 +1,18 @@ +package com.minelittlepony.unicopia.entity.effect; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffect; + +public interface EffectUtils { + static boolean isPoisoned(LivingEntity entity) { + return getAmplifier(entity, UEffects.FOOD_POISONING) > 2; + } + + static int getAmplifier(LivingEntity entity, StatusEffect effect) { + return entity.hasStatusEffect(effect) ? entity.getStatusEffect(effect).getAmplifier() : 0; + } + + static boolean isChangingRace(LivingEntity entity) { + return entity.getStatusEffects().stream().anyMatch(effect -> effect.getEffectType() instanceof RaceChangeStatusEffect); + } +} 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 c0b6a276..e8bd62a7 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/effect/FoodPoisoningStatusEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/FoodPoisoningStatusEffect.java @@ -2,8 +2,7 @@ package com.minelittlepony.unicopia.entity.effect; import org.jetbrains.annotations.Nullable; -import com.minelittlepony.unicopia.entity.Living; -import com.minelittlepony.unicopia.entity.damage.UDamageTypes; +import com.minelittlepony.unicopia.USounds; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; @@ -11,6 +10,13 @@ import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; 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 { @@ -21,21 +27,19 @@ public class FoodPoisoningStatusEffect extends StatusEffect { @Override public void applyUpdateEffect(LivingEntity entity, int amplifier) { - StatusEffectInstance nausea = entity.getStatusEffect(StatusEffects.NAUSEA); - if (nausea == null) { - StatusEffectInstance foodEffect = entity.getStatusEffect(this); - nausea = new StatusEffectInstance(StatusEffects.NAUSEA, foodEffect.getDuration(), - foodEffect.getAmplifier(), - true, - foodEffect.shouldShowParticles(), - false - ); + boolean showParticles = entity.getStatusEffect(this).shouldShowParticles(); - entity.addStatusEffect(nausea); + if (!entity.hasStatusEffect(StatusEffects.NAUSEA) && entity.getRandom().nextInt(12) == 0) { + + entity.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 100, 1, true, showParticles, false)); } - if (entity.getHealth() > amplifier) { - entity.damage(Living.living(entity).damageOf(UDamageTypes.FOOD_POISONING), amplifier); + if (entity instanceof PlayerEntity) { + ((PlayerEntity)entity).getHungerManager().addExhaustion(0.5F); + } + + if (EffectUtils.isPoisoned(entity) && entity.getRandom().nextInt(12) == 0 && !entity.hasStatusEffect(StatusEffects.POISON)) { + StatusEffects.POISON.applyUpdateEffect(entity, 1); } } @@ -49,4 +53,19 @@ public class FoodPoisoningStatusEffect extends StatusEffect { int i = 40 >> amplifier; return i <= 0 || duration % i == 0; } + + public static TypedActionResult apply(ItemConvertible sender, PlayerEntity user, Hand hand) { + @Nullable + FoodComponent food = sender.asItem().getFoodComponent(); + + if (food == null || !user.canConsume(food.isAlwaysEdible()) || !user.hasStatusEffect(UEffects.FOOD_POISONING)) { + return TypedActionResult.pass(user.getStackInHand(hand)); + } + + 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)); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/effect/RaceChangeStatusEffect.java b/src/main/java/com/minelittlepony/unicopia/entity/effect/RaceChangeStatusEffect.java index 463d0f27..575b3c3c 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/effect/RaceChangeStatusEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/RaceChangeStatusEffect.java @@ -9,8 +9,6 @@ import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.player.MagicReserves; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.item.UItems; - import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.effect.*; @@ -41,13 +39,6 @@ public class RaceChangeStatusEffect extends StatusEffect { ); } - public static boolean hasEffect(PlayerEntity player) { - if (UItems.ALICORN_AMULET.isApplicable(player)) { - return true; - } - return player.getStatusEffects().stream().anyMatch(effect -> effect.getEffectType() instanceof RaceChangeStatusEffect); - } - public RaceChangeStatusEffect(int color, Race race) { super(StatusEffectCategory.NEUTRAL, color); this.race = race; diff --git a/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java b/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java index e8c888b2..73690016 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/ToxicHolder.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable; import net.minecraft.item.*; -public interface ToxicHolder { +public interface ToxicHolder extends ItemConvertible { @Nullable default FoodComponent getOriginalFoodComponent() { return null; 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 68907ea5..5d445f84 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxics.java @@ -3,7 +3,6 @@ package com.minelittlepony.unicopia.item.toxin; import com.minelittlepony.unicopia.*; import com.minelittlepony.unicopia.util.RegistryUtils; -import net.minecraft.entity.effect.StatusEffects; import net.minecraft.registry.Registry; import static com.minelittlepony.unicopia.item.toxin.Toxicity.*; @@ -31,54 +30,54 @@ public interface Toxics { .with(Race.CHANGELING, of(FAIR, LOVE_SICKNESS)) ); - Toxic FORAGE_RISKY = register("forage_risky", new Toxic.Builder(of(FAIR, WEAK_NAUSEA.withChance(20))) + Toxic FORAGE_RISKY = register("forage_risky", new Toxic.Builder(of(FAIR, FOOD_POISONING.withChance(20))) .food(UFoodComponents.RANDOM_FOLIAGE) .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) ); - Toxic FORAGE_MODERATE = register("forage_moderate", new Toxic.Builder(of(MILD, POISON.and(WEAK_NAUSEA))) + Toxic FORAGE_MODERATE = register("forage_moderate", new Toxic.Builder(of(MILD, FOOD_POISONING)) .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) + .with(Race.HUMAN, of(LETHAL, STRONG_FOOD_POISONING)) ); Toxic FORAGE_DANGEROUS = register("forage_dangerous", new Toxic.Builder(of(SEVERE, FOOD_POISONING)) .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(NAUSEA))) + .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) ); - Toxic FORAGE_NAUSEATING = register("forage_nauseating", new Toxic.Builder(of(SAFE, NAUSEA.and(WEAKNESS.withChance(30)))) - .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(NAUSEA))) - ); - Toxic FORAGE_RADIOACTIVE = register("forage_radioactive", new Toxic.Builder(of(SAFE, NAUSEA.and(RADIOACTIVITY.withChance(30)))) - .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(NAUSEA))) - ); - Toxic FORAGE_PRICKLY = register("forage_prickly", new Toxic.Builder(of(SAFE, PRICKLING.withChance(30))) - .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(NAUSEA))) - ); - Toxic FORAGE_STRENGHTENING = register("forage_strengthening", new Toxic.Builder(of(SEVERE, STRENGTH.and(WEAK_NAUSEA))) - .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(WEAKNESS))) - ); - Toxic FORAGE_SEVERELY_NAUSEATING = register("forage_severely_nauseating", new Toxic.Builder(of(SEVERE, STRONG_NAUSEA.and(WEAKNESS))) - .food(UFoodComponents.RANDOM_FOLIAGE) - .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(WEAKNESS))) - ); - Toxic FORAGE_BLINDING = register("forage_blinding", new Toxic.Builder(of(SEVERE, BLINDNESS.and(WEAK_NAUSEA))) + Toxic FORAGE_NAUSEATING = register("forage_nauseating", new Toxic.Builder(of(SAFE, FOOD_POISONING.and(WEAKNESS.withChance(30)))) .food(UFoodComponents.RANDOM_FOLIAGE) .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) ); - Toxic FORAGE_SEVERELY_PRICKLY = register("forage_severely_prickly", new Toxic.Builder(of(SEVERE, PRICKLING.and(NAUSEA))) + Toxic FORAGE_RADIOACTIVE = register("forage_radioactive", new Toxic.Builder(of(SAFE, FOOD_POISONING.and(GLOWING.withChance(30)))) .food(UFoodComponents.RANDOM_FOLIAGE) .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) ); - Toxic RAW_MEAT = register("raw_meat", new Toxic.Builder(of(SEVERE, FOOD_POISONING.withChance(5).and(POISON.withChance(20)))) + Toxic FORAGE_PRICKLY = register("forage_prickly", new Toxic.Builder(of(SAFE, INSTANT_DAMAGE.withChance(30))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) + ); + Toxic FORAGE_STRENGHTENING = register("forage_strengthening", new Toxic.Builder(of(SEVERE, STRENGTH.and(FOOD_POISONING))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(WEAKNESS))) + ); + Toxic FORAGE_SEVERELY_NAUSEATING = register("forage_severely_nauseating", new Toxic.Builder(of(SEVERE, FOOD_POISONING.and(WEAKNESS))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, of(LETHAL, FOOD_POISONING.and(WEAKNESS))) + ); + Toxic FORAGE_BLINDING = register("forage_blinding", new Toxic.Builder(of(SEVERE, BLINDNESS.and(FOOD_POISONING))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) + ); + Toxic FORAGE_SEVERELY_PRICKLY = register("forage_severely_prickly", new Toxic.Builder(of(SEVERE, FOOD_POISONING.and(INSTANT_DAMAGE))) + .food(UFoodComponents.RANDOM_FOLIAGE) + .with(Race.HUMAN, of(LETHAL, FOOD_POISONING)) + ); + Toxic RAW_MEAT = register("raw_meat", new Toxic.Builder(of(SEVERE, FOOD_POISONING.withChance(5).and(CHANCE_OF_POISON))) .with(Race.HUMAN, Ailment.INNERT) .with(Race.CHANGELING, Ailment.INNERT) - .with(Race.BAT, of(MILD, WEAK_NAUSEA)) + .with(Race.BAT, of(MILD, FOOD_POISONING)) ); - Toxic ROTTEN_MEAT = register("rotten_meat", new Toxic.Builder(of(SEVERE, FOOD_POISONING.and(POISON))) + Toxic ROTTEN_MEAT = register("rotten_meat", new Toxic.Builder(of(SEVERE, STRONG_FOOD_POISONING)) .with(Race.HUMAN, Ailment.INNERT) - .with(Race.BAT, of(MILD, STRONG_NAUSEA)) + .with(Race.BAT, of(MILD, FOOD_POISONING)) .with(Race.CHANGELING, Ailment.INNERT) ); Toxic COOKED_MEAT = register("cooked_meat", new Toxic.Builder(of(FAIR, FOOD_POISONING)) @@ -87,9 +86,9 @@ public interface Toxics { .with(Race.BAT, Ailment.INNERT) ); - Toxic RAW_FISH = register("raw_fish", new Toxic.Builder(of(FAIR, FOOD_POISONING.and(POISON))) + Toxic RAW_FISH = register("raw_fish", new Toxic.Builder(of(FAIR, FOOD_POISONING.and(CHANCE_OF_POISON))) .with(Race.HUMAN, Ailment.INNERT) - .with(Race.PEGASUS, of(MILD, POISON.and(WEAK_NAUSEA))) + .with(Race.PEGASUS, of(MILD, FOOD_POISONING)) .with(Race.ALICORN, Ailment.INNERT) .with(Race.CHANGELING, of(FAIR, LOVE_SICKNESS)) ); @@ -101,7 +100,7 @@ public interface Toxics { ); Toxic RAW_INSECT = register("raw_insect", new Toxic.Builder(of(LETHAL, FOOD_POISONING)) - .with(Race.BAT, of(MILD, WEAK_NAUSEA)) + .with(Race.BAT, of(MILD, WEAK_FOOD_POISONING)) .with(Race.CHANGELING, Ailment.INNERT) ); @@ -120,12 +119,7 @@ public interface Toxics { ); Toxic BAT_PONYS_DELIGHT = register("bat_ponys_delight", new Toxic.Builder(Ailment.INNERT) - .with(Race.BAT, Ailment.of(Toxicity.SAFE, - Toxin.of(StatusEffects.HEALTH_BOOST, 30, 60, 2, 6) - .and(Toxin.of(StatusEffects.JUMP_BOOST, 30, 60, 1, 6)) - .and(Toxin.of(StatusEffects.SPEED, 30, 30, 1, 6)) - .and(Toxin.of(StatusEffects.REGENERATION, 3, 30, 3, 6)) - )) + .with(Race.BAT, of(Toxicity.SAFE, Toxin.BAT_PONY_INTOXICATION)) ); static void bootstrap() {} 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 50776c0c..660116b7 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java +++ b/src/main/java/com/minelittlepony/unicopia/item/toxin/Toxin.java @@ -22,33 +22,32 @@ public interface Toxin extends Affliction { 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 INSTANT_DAMAGE = of(StatusEffects.INSTANT_DAMAGE, 1, 0); + Toxin GLOWING = 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 CHANCE_OF_POISON = of(StatusEffects.POISON, 45, 2).withChance(80); Toxin FOOD_POISONING = of(UEffects.FOOD_POISONING, 100, 2); Toxin WEAK_FOOD_POISONING = of(UEffects.FOOD_POISONING, 50, 1); + Toxin STRONG_FOOD_POISONING = of(UEffects.FOOD_POISONING, 400, 3); Toxin LOVE_SICKNESS = of(Text.of("Love Sickness "), (player, stack) -> { FoodComponent food = stack.getItem().getFoodComponent(); player.getHungerManager().add(-food.getHunger()/2, -food.getSaturationModifier()/2); - }).and(STRONG_NAUSEA).and(IF_NOT_PEACEFUL.then(WEAK_FOOD_POISONING.withChance(20))).and(WEAKNESS); + }).and(FOOD_POISONING).and(IF_NOT_PEACEFUL.then(WEAK_FOOD_POISONING.withChance(20))).and(WEAKNESS); Toxin LOVE_CONSUMPTION = of(Text.literal("Love"), (player, stack) -> { player.heal(stack.isFood() ? stack.getItem().getFoodComponent().getHunger() : 1); player.removeStatusEffect(StatusEffects.NAUSEA); - if (player.getWorld().random.nextInt(10) == 0) { - player.removeStatusEffect(UEffects.FOOD_POISONING); - } + player.removeStatusEffect(UEffects.FOOD_POISONING); }); + Toxin BAT_PONY_INTOXICATION = Toxin.of(StatusEffects.HEALTH_BOOST, 30, 60, 2, 6) + .and(Toxin.of(StatusEffects.JUMP_BOOST, 30, 60, 1, 6)) + .and(Toxin.of(StatusEffects.SPEED, 30, 30, 1, 6)) + .and(Toxin.of(StatusEffects.REGENERATION, 3, 30, 3, 6)); static Toxin healing(int hearts) { return of(Text.literal("Healing " + hearts + " Hearts"), (player, stack) -> player.heal(hearts)); @@ -121,7 +120,7 @@ public interface Toxin extends Affliction { StatusEffectInstance current = player.getStatusEffect(effect); int t = applyLimit(ticks + (current == null ? 0 : current.getDuration()), maxTicks); int a = applyLimit(amplifier + (current == null ? 0 : current.getAmplifier()), maxAmplifier); - player.addStatusEffect(new StatusEffectInstance(effect, t, a, false, false, false)); + player.addStatusEffect(new StatusEffectInstance(effect, t, a)); // keep original health if (effect.getAttributeModifiers().containsKey(EntityAttributes.GENERIC_MAX_HEALTH)) { player.setHealth(MathHelper.clamp(health, 0, player.getMaxHealth())); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java index e0ceb963..4ee6570b 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItem.java @@ -15,12 +15,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 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) @@ -56,7 +61,7 @@ abstract class MixinItem implements ToxicHolder, ItemImpl.TickableItem { public FoodComponent getOriginalFoodComponent() { if (!foodLoaded) { foodLoaded = true; - originalFoodComponent = ((Item)(Object)this).getFoodComponent(); + originalFoodComponent = asItem().getFoodComponent(); } return originalFoodComponent; } @@ -65,4 +70,12 @@ abstract class MixinItem implements ToxicHolder, ItemImpl.TickableItem { private void finishUsing(ItemStack stack, World world, LivingEntity entity, CallbackInfoReturnable info) { getToxic(stack).finishUsing(stack, world, entity); } + + @Inject(method = "use", at = @At("HEAD"), cancellable = true) + private void use(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> info) { + 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/client/MixinInGameHud.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinInGameHud.java index 58faae77..fa02c81d 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinInGameHud.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinInGameHud.java @@ -7,30 +7,55 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.client.gui.UHud; -import com.minelittlepony.unicopia.entity.effect.RaceChangeStatusEffect; +import com.minelittlepony.unicopia.entity.effect.EffectUtils; +import com.minelittlepony.unicopia.entity.effect.UEffects; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.player.PlayerEntity; @Mixin(InGameHud.class) abstract class MixinInGameHud { + + private boolean addedHunger; + + @Shadow + abstract PlayerEntity getCameraPlayer(); + @Inject(method = "render(Lnet/minecraft/client/gui/DrawContext;F)V", at = @At("HEAD")) private void onRender(DrawContext context, float tickDelta, CallbackInfo info) { + PlayerEntity player = getCameraPlayer(); + if (player != null && !player.hasStatusEffect(StatusEffects.HUNGER) && EffectUtils.getAmplifier(player, UEffects.FOOD_POISONING) > 0) { + addedHunger = true; + player.addStatusEffect(new StatusEffectInstance(StatusEffects.HUNGER, 1, 1, false, false)); + } UHud.INSTANCE.render((InGameHud)(Object)this, context, tickDelta); } + + @Inject(method = "render(Lnet/minecraft/client/gui/DrawContext;F)V", at = @At("RETURN")) + private void afterRender(DrawContext context, float tickDelta, CallbackInfo info) { + if (addedHunger) { + addedHunger = false; + PlayerEntity player = getCameraPlayer(); + if (player != null) { + player.removeStatusEffect(StatusEffects.HUNGER); + } + } + } } -@Mixin(targets = "net.minecraft.client.gui.hud.InGameHud$HeartType") +@Mixin(InGameHud.HeartType.class) abstract class MixinInGameHud$HeartType { - @SuppressWarnings({"unchecked", "rawtypes"}) @Inject( method = "fromPlayerState(Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/client/gui/hud/InGameHud$HeartType;", at = @At("RETURN"), cancellable = true) - private static void onFromPlayerState(PlayerEntity player, CallbackInfoReturnable cbi) { - if (RaceChangeStatusEffect.hasEffect(player)) { - cbi.setReturnValue(Enum.valueOf(cbi.getReturnValue().getClass(), "WITHERED")); + private static void onFromPlayerState(PlayerEntity player, CallbackInfoReturnable cbi) { + InGameHud.HeartType heartsType = UHud.getHeartsType(player); + if (heartsType != null) { + cbi.setReturnValue(heartsType); } } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java index 9afd4557..c0fd45da 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java @@ -5,6 +5,8 @@ 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.entity.effect.EffectUtils; +import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.client.MinecraftClient; @@ -17,18 +19,26 @@ abstract class MixinKeyboardInput extends Input { private void onTick(boolean a, float b, CallbackInfo info) { Pony player = Pony.of(MinecraftClient.getInstance().player); - if (player != null && player.getPhysics().isGravityNegative()) { - boolean tmp = pressingLeft; + if (player != null) { + if (player.getPhysics().isGravityNegative()) { + boolean tmp = pressingLeft; - pressingLeft = pressingRight; - pressingRight = tmp; + pressingLeft = pressingRight; + pressingRight = tmp; - movementSideways = -movementSideways; + movementSideways = -movementSideways; - if (player.asEntity().getAbilities().flying && !player.getPhysics().isFlying()) { - tmp = jumping; - jumping = sneaking; - sneaking = tmp; + if (player.asEntity().getAbilities().flying && !player.getPhysics().isFlying()) { + tmp = jumping; + jumping = sneaking; + sneaking = tmp; + } + } + + if (EffectUtils.getAmplifier(MinecraftClient.getInstance().player, UEffects.PARALYSIS) > 1) { + movementSideways = 0; + movementForward = 0; + jumping = false; } } } diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/paralysis.png b/src/main/resources/assets/unicopia/textures/mob_effect/paralysis.png new file mode 100644 index 0000000000000000000000000000000000000000..5a98f25a30cb0aeb8b23f74b0b65dcc383b42a29 GIT binary patch literal 4621 zcmeHLdsGzH86OZ~g^1565)6|yF<>)0yR);)?#OBk3$oUgw_91}mp238KBT%d^cnJ)G10$8zr8 zZ@&Bce)rzr{q6_DUfrhkb3J`MAqbkQ30Fsfem>s>?%>;h@EHlZE+$@M&}ddc0`LHk zE^d$uj{(hPlI`j;3z`LdyFptBY#zfmUzgdAem}5Z7`4lR9WaV<1-8V+6`BkBD$p=s zF9v-bXl$W#uG7HgKLW>3IIwu;v3|WqtAjC-L@bixAYP0~39*t8OJRwOz+?n20ce-% zi52lo346ER04%%MkPw|FBm}lt%?37=fgpR;j#5?lC$IZ;Bu014tMfL@Py0-_yj`^F zPJF#?m*>&A?9h36Uls02EBNAG)oZVIWxRcJ#o22u zf{WX8zqxqnSB%l!?d3ZGQl!wHZ#Q&Hlmm;38mg1q@3${n^45W&(*C-O=BmLLy@I1Z zjQTuFUmAb@55K*Bu3_7Q_U?948x)WjKHQMjcc-CZRYO|D({s9>_&4tnoeSEV_Pp}h zf$C#pz^B(;)L41&V~?%hKp_#e`oP1B zYXa|D&kir!5$*2NIy?K?lRn>J#SSRyO6(nXg~IKRkIPT>-Me}7*QZ8uYA@ZIm(gQA z{z25>0+54tHYT2n*KQ;zvr$CSW<4Xa8!h~SLBVV77LrO~I9Sglu_l#ppyiAZW@(jh zvrH@2T0)p)Hay$PL}zb`p|VpbB`sXL#xvMX00JY!k+9vEYO)b_mC(UU0GoHCLf8S} zQdGitkVheAD+A*qTqH(9?Q8}nT;mA`TWJFkr4AdV08c7mGRIj66wS=c6lF?9W@{2E zQ7V^XU@!z{qy|J8q>v*roWe~PYJ&8(VvT>w|Vt6V*E@A|bd2!FLV(QxVM#tu0fEC0_CkbM8Im(wW6b7Mm2kZ3jt^_W zb)rd*RFfP7NXP4N%vc@%iC992oy+Ixv}T$$Wc@ERe|g|wfCon&&f38ISq_);MnyAe z&L`(%D(kpPFzmP#1W7r!U?Vda=XnDz=Ma@lnvxh$Jx0@Y%+LNnDoAjJOr~H+L?M^T z5Zs`YBYFy4b0uwHXqqt?aGA`Z!Z^FlY~V6UE3+;M=m@j|>FM|l1qV0|DsU<~GnwH} z0SJbOm55mSpMs&I8%Ft>F}CAi^uII-b^s<784&06f#L;fAv#_RM>PZM{V_kIXYpfB z0mCzsOiSMxxn|^=mIBiP&t%t(T+>ouTHu-N`oGELIq^Ehn805_nc!uqaI=36c+qm# z|8%_?vO(9N8-3r-*$X^#Ea7k3AjoSG-&~-BRX)J!!D+Oi9{1{hyE^M{WZBOB-S0~L$#OL1VC~-qVI(g4`PQM;I|c?GJ!(bYepC{9?EH7v>-<_P z2jrH7Q@W?Vmham_maXmmG~Mq+hj7bBZ=|G@<=?+3e5vV3k@%~w-oD!JzW?Rpzdks4 zc_3p>a0!V0b7Deyu3OE1%|4qgq%z?*g}L_dp|pwzgG=B0s0nwC%=NpF&?0(R>`@SW zKW_VpSKNAHiaYmp-jB$kBi8EiIs>5SP68!y_mx`ZreW^Kpc;(?&=Qpl?5xU)QCKB3kwaEI9ub*ET75F4$ tcxmOWrv>XCUo8l)?CHrVc((Euw4kzn*J~R|{+~FICUld!@r`YH{|2i1Zejoc literal 0 HcmV?d00001 diff --git a/src/main/resources/unicopia.aw b/src/main/resources/unicopia.aw index 7b0a6fab..70f16be3 100644 --- a/src/main/resources/unicopia.aw +++ b/src/main/resources/unicopia.aw @@ -4,6 +4,7 @@ accessible class net/minecraft/client/render/RenderPhase$TextureBase accessible method net/minecraft/client/render/RenderLayer of (Ljava/lang/String;Lnet/minecraft/client/render/VertexFormat;Lnet/minecraft/client/render/VertexFormat$DrawMode;IZZLnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase; accessible class net/minecraft/client/render/item/HeldItemRenderer$HandRenderType accessible class net/minecraft/client/render/VertexConsumers$Union +accessible class net/minecraft/client/gui/hud/InGameHud$HeartType accessible method net/minecraft/world/GameRules register (Ljava/lang/String;Lnet/minecraft/world/GameRules$Category;Lnet/minecraft/world/GameRules$Type;)Lnet/minecraft/world/GameRules$Key; accessible method net/minecraft/world/GameRules$BooleanRule create (Z)Lnet/minecraft/world/GameRules$Type;