diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java index 4c841b1a..64fabfa4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java @@ -76,9 +76,9 @@ public class ChangeFormAbility implements Ability { targets.forEach(target -> { Race supressed = target.getSuppressedRace(); if (target == player || supressed.isUnset() == isTransforming) { - Race actualRace = target.getSpecies(); + Race actualRace = isTransforming ? target.getSpecies() : Race.UNSET; target.setSpecies(supressed.or(player.getCompositeRace().potential())); - target.setSuppressedRace(isTransforming ? actualRace : Race.UNSET); + target.setSuppressedRace(actualRace); } }); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/effect/MetamorphosisStatusEffect.java b/src/main/java/com/minelittlepony/unicopia/entity/effect/MetamorphosisStatusEffect.java new file mode 100644 index 00000000..56accf6f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/MetamorphosisStatusEffect.java @@ -0,0 +1,60 @@ +package com.minelittlepony.unicopia.entity.effect; + +import java.util.HashMap; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.Race; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.entity.effect.StatusEffectCategory; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +public class MetamorphosisStatusEffect extends StatusEffect { + public static final int MAX_DURATION = 20 * 60; + + private static final Map REGISTRY = new HashMap<>(); + + public static final StatusEffect EARTH = register(0x886F0F, Race.EARTH); + public static final StatusEffect UNICORN = register(0x88FFFF, Race.UNICORN); + public static final StatusEffect PEGASUS = register(0x00C0ff, Race.PEGASUS); + public static final StatusEffect BAT = register(0x152F13, Race.BAT); + public static final StatusEffect CHANGELING = register(0xFFFF00, Race.CHANGELING); + public static final StatusEffect KIRIN = register(0xFF8800, Race.KIRIN); + public static final StatusEffect HIPPOGRIFF = register(0xE04F77, Race.HIPPOGRIFF); + + @Nullable + public static StatusEffect forRace(Race race) { + return REGISTRY.get(race); + } + + public static StatusEffect register(int color, Race race) { + Identifier id = Race.REGISTRY.getId(race); + StatusEffect effect = new MetamorphosisStatusEffect(color, race); + REGISTRY.put(race, effect); + return Registry.register(Registries.STATUS_EFFECT, + id.withPath(p -> "morph_race_" + p), + effect + ); + } + + public static Race getEffectiveRace(LivingEntity entity, Race fallback) { + return entity.getStatusEffects().stream().filter(effect -> effect.getEffectType() instanceof MetamorphosisStatusEffect).map(effect -> { + return ((MetamorphosisStatusEffect)effect.getEffectType()).getRace(); + }).findFirst().orElse(fallback); + } + + private final Race race; + + private MetamorphosisStatusEffect(int color, Race race) { + super(StatusEffectCategory.NEUTRAL, color); + this.race = race; + } + + public Race getRace() { + return race; + } +} 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 462936ad..210395b9 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/effect/RaceChangeStatusEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/RaceChangeStatusEffect.java @@ -1,5 +1,8 @@ package com.minelittlepony.unicopia.entity.effect; +import java.util.HashMap; +import java.util.Map; + import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.Race; @@ -28,25 +31,31 @@ public class RaceChangeStatusEffect extends StatusEffect { public static final int STAGE_DURATION = 200; public static final int MAX_DURATION = Stage.VALUES.length * STAGE_DURATION + 1; - public static final StatusEffect CHANGE_RACE_EARTH = register(0x886F0F, Race.EARTH); - public static final StatusEffect CHANGE_RACE_UNICORN = register(0x88FFFF, Race.UNICORN); - public static final StatusEffect CHANGE_RACE_PEGASUS = register(0x00FFFF, Race.PEGASUS); - public static final StatusEffect CHANGE_RACE_BAT = register(0x0FFF00, Race.BAT); - public static final StatusEffect CHANGE_RACE_CHANGELING = register(0xFFFF00, Race.CHANGELING); - public static final StatusEffect CHANGE_RACE_KIRIN = register(0xFF8800, Race.KIRIN); - public static final StatusEffect CHANGE_RACE_HIPPOGRIFF = register(0x00FFFF, Race.HIPPOGRIFF); + private static final Map REGISTRY = new HashMap<>(); + + @Nullable + public static StatusEffect forRace(Race race) { + return REGISTRY.get(race); + } + + public static final StatusEffect EARTH = register(0x886F0F, Race.EARTH); + public static final StatusEffect UNICORN = register(0x88FFFF, Race.UNICORN); + public static final StatusEffect PEGASUS = register(0x00C0ff, Race.PEGASUS); + public static final StatusEffect BAT = register(0x152F13, Race.BAT); + public static final StatusEffect CHANGELING = register(0xFFFF00, Race.CHANGELING); + public static final StatusEffect KIRIN = register(0xFF8800, Race.KIRIN); + public static final StatusEffect HIPPOGRIFF = register(0xE04F77, Race.HIPPOGRIFF); private final Race race; public static StatusEffect register(int color, Race race) { - Identifier id = Race.REGISTRY.getId(race); - return Registry.register(Registries.STATUS_EFFECT, - new Identifier(id.getNamespace(), "change_race_" + id.getPath().toLowerCase()), - new RaceChangeStatusEffect(color, race) - ); + Identifier id = race.getId(); + StatusEffect effect = new RaceChangeStatusEffect(color, race); + REGISTRY.put(race, effect); + return Registry.register(Registries.STATUS_EFFECT, id.withPath(p -> "change_race_" + id.getPath()), effect); } - public RaceChangeStatusEffect(int color, Race race) { + private RaceChangeStatusEffect(int color, Race race) { super(StatusEffectCategory.NEUTRAL, color); this.race = race; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/effect/UPotions.java b/src/main/java/com/minelittlepony/unicopia/entity/effect/UPotions.java index 82f5a0b3..2fb07320 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/effect/UPotions.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/UPotions.java @@ -1,29 +1,70 @@ package com.minelittlepony.unicopia.entity.effect; -import java.util.ArrayList; -import java.util.List; +import java.util.Objects; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.item.UItems; +import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.item.Item; +import net.minecraft.item.Items; import net.minecraft.potion.Potion; +import net.minecraft.potion.Potions; +import net.minecraft.recipe.BrewingRecipeRegistry; import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; import net.minecraft.registry.Registries; public interface UPotions { - List REGISTRY = new ArrayList<>(); - - Potion TRIBE_SWAP_EARTH_PONY = register("tribe_swap_earth", new Potion("unicopia.tribe_swap_earth", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_EARTH, RaceChangeStatusEffect.MAX_DURATION))); - Potion TRIBE_SWAP_UNICORN = register("tribe_swap_unicorn", new Potion("unicopia.tribe_swap_unicorn", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_UNICORN, RaceChangeStatusEffect.MAX_DURATION))); - Potion TRIBE_SWAP_PEGASUS = register("tribe_swap_pegasus", new Potion("unicopia.tribe_swap_pegasus", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_PEGASUS, RaceChangeStatusEffect.MAX_DURATION))); - Potion TRIBE_SWAP_BAT = register("tribe_swap_bat", new Potion("unicopia.tribe_swap_bat", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_BAT, RaceChangeStatusEffect.MAX_DURATION))); - Potion TRIBE_SWAP_CHANGELING = register("tribe_swap_changeling", new Potion("unicopia.tribe_swap_changeling", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_CHANGELING, RaceChangeStatusEffect.MAX_DURATION))); - Potion TRIBE_SWAP_KIRIN = register("tribe_swap_kirin", new Potion("unicopia.tribe_swap_kirin", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_KIRIN, RaceChangeStatusEffect.MAX_DURATION))); - Potion TRIBE_SWAP_HIPPOGRIFF = register("tribe_swap_hippogriff", new Potion("unicopia.tribe_swap_hippogriff", new StatusEffectInstance(RaceChangeStatusEffect.CHANGE_RACE_HIPPOGRIFF, RaceChangeStatusEffect.MAX_DURATION))); + MorphingPotion MORPH_EARTH_PONY = new MorphingPotion(Race.EARTH).registerBaseRecipes(Potions.STRENGTH, UItems.CURING_JOKE); + MorphingPotion MORPH_UNICORN = new MorphingPotion(Race.UNICORN).registerBaseRecipes(Potions.REGENERATION, UItems.BOTCHED_GEM); + MorphingPotion MORPH_PEGASUS = new MorphingPotion(Race.PEGASUS).registerBaseRecipes(Potions.SWIFTNESS, UItems.PEGASUS_FEATHER, UItems.HIPPOGRIFF_BADGE, Items.FEATHER); + MorphingPotion MORPH_BAT = new MorphingPotion(Race.BAT).registerBaseRecipes(Potions.NIGHT_VISION, UItems.BUTTERFLY); + MorphingPotion MORPH_CHANGELING = new MorphingPotion(Race.CHANGELING).registerBaseRecipes(Potions.HARMING, UItems.CARAPACE); + MorphingPotion MORPH_KIRIN = new MorphingPotion(Race.KIRIN).registerBaseRecipes(Potions.FIRE_RESISTANCE, Items.MAGMA_CREAM); + MorphingPotion MORPH_HIPPOGRIFF = new MorphingPotion(Race.HIPPOGRIFF).registerBaseRecipes(Potions.WATER_BREATHING, UItems.CLAM_SHELL, UItems.TURRET_SHELL, UItems.SCALLOP_SHELL); static Potion register(String name, Potion potion) { - REGISTRY.add(potion); - return Registry.register(Registries.POTION, Unicopia.id(name), potion); + return register(Unicopia.id(name), potion); + } + + static Potion register(Identifier id, Potion potion) { + return Registry.register(Registries.POTION, id, potion); + } + + static void addRecipe(Potion result, Potion basePotion, Item...items) { + Preconditions.checkArgument(BrewingRecipeRegistry.isBrewable(basePotion), "Base potion is not craftable. " + Registries.POTION.getId(basePotion) + " required for crafting " + Registries.POTION.getId(result)); + for (Item item : items) { + BrewingRecipeRegistry.registerPotionRecipe(basePotion, item, result); + } + } + + record MorphingPotion(Identifier id, Potion shortEffect, Potion longEffect, Potion permanentEffect) { + public MorphingPotion(Race race) { + this(race.getId(), + Objects.requireNonNull(MetamorphosisStatusEffect.forRace(race), "No metamorphosis status effect registered for " + race.getId()), + Objects.requireNonNull(RaceChangeStatusEffect.forRace(race), "No race change status effect registered for " + race.getId()) + ); + } + + public MorphingPotion(Identifier id, StatusEffect morphEffect, StatusEffect permanentEffect) { + this(id, + register(id.withPath(p -> "short_morph_" + p), new Potion(id.getNamespace() + ".short_morph_" + id.getPath(), new StatusEffectInstance(morphEffect, MetamorphosisStatusEffect.MAX_DURATION))), + register(id.withPath(p -> "long_morph_" + p), new Potion(id.getNamespace() + ".long_morph_" + id.getPath(), new StatusEffectInstance(morphEffect, MetamorphosisStatusEffect.MAX_DURATION * 10))), + register(id, new Potion(id.getNamespace() + ".tribe_swap_" + id.getPath(), new StatusEffectInstance(permanentEffect, RaceChangeStatusEffect.MAX_DURATION))) + ); + } + + public MorphingPotion registerBaseRecipes(Potion basePotion, Item...items) { + addRecipe(shortEffect, basePotion, items); + addRecipe(longEffect, shortEffect, Items.REDSTONE); + addRecipe(permanentEffect, longEffect, UItems.CURING_JOKE); + return this; + } } static void bootstrap() { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java index cedc1064..ff73a2f8 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java @@ -4,7 +4,6 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; -import com.minelittlepony.unicopia.entity.effect.UPotions; import com.minelittlepony.unicopia.item.EnchantableItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.util.RegistryUtils; @@ -14,7 +13,6 @@ import net.minecraft.entity.Entity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.potion.PotionUtil; import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Util; @@ -22,7 +20,6 @@ import net.minecraft.util.math.random.Random; import net.minecraft.village.TradeOffer; import net.minecraft.village.TradeOffers; import net.minecraft.village.VillagerProfession; -import net.minecraft.village.TradeOffers.Factory; public interface UTradeOffers { static void bootstrap() { @@ -59,10 +56,6 @@ public interface UTradeOffers { factories.add(buy(UItems.CRYSTAL_HEART, 1, UItems.MUSIC_DISC_CRUSADE, 1, 10, 6, 0.08F)); factories.add(buy(UItems.PEGASUS_AMULET, 1, UItems.ALICORN_AMULET, 1, 2, 6, 0.05F)); factories.add(buyForEmeralds(UItems.FRIENDSHIP_BRACELET, 2, 1, 10, 7, 0.17F)); - factories.add(new SellPotionHoldingItemFactory( - new Item[] { Items.ARROW, Items.GLASS_BOTTLE, Items.GLASS_BOTTLE }, - new Item[] { Items.TIPPED_ARROW, Items.POTION, Items.SPLASH_POTION }, - 5, 5, 2, 12, 30)); }); } @@ -105,17 +98,4 @@ public interface UTradeOffers { return new TradeOffer(offer.getOriginalFirstBuyItem(), offer.getSecondBuyItem(), UItems.FILLED_JAR.withContents(offer.getSellItem()), offer.getUses(), offer.getMaxUses(), offer.getMerchantExperience(), offer.getPriceMultiplier(), offer.getDemandBonus()); } } - - record SellPotionHoldingItemFactory (Item[] secondBuy, Item[] tippedArrow, int secondCount, int sellCount, int price, int maxUses, int experience) implements Factory { - @Override - public TradeOffer create(Entity entity, Random random) { - int index = random.nextInt(tippedArrow.length); - return new TradeOffer( - new ItemStack(Items.EMERALD, price), - new ItemStack(secondBuy[index], secondCount), - PotionUtil.setPotion(new ItemStack(tippedArrow[index], sellCount), UPotions.REGISTRY.get(random.nextInt(UPotions.REGISTRY.size()))), - maxUses, experience, 0.05f - ); - } - } } 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 7b1f6ccf..fab87347 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -21,6 +21,7 @@ import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.*; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; +import com.minelittlepony.unicopia.entity.effect.MetamorphosisStatusEffect; import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect; import com.minelittlepony.unicopia.entity.effect.UEffects; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; @@ -476,13 +477,13 @@ public class Pony extends Living implements Copyable, Update private void recalculateCompositeRace() { Race intrinsicRace = getSpecies(); Race suppressedRace = getSuppressedRace(); - compositeRace = getSpellSlot() + compositeRace = MetamorphosisStatusEffect.getEffectiveRace(entity, getSpellSlot() .get(SpellPredicate.IS_MIMIC, true) .map(AbstractDisguiseSpell::getDisguise) .map(EntityAppearance::getAppearance) .flatMap(Pony::of) .map(Pony::getSpecies) - .orElse(intrinsicRace).composite( + .orElse(intrinsicRace)).composite( AmuletSelectors.UNICORN_AMULET.test(entity) ? Race.UNICORN : AmuletSelectors.ALICORN_AMULET.test(entity) ? Race.ALICORN : null, diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index d516f4d9..39d28398 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -352,6 +352,19 @@ "effect.unicopia.butter_fingers": "Butterfingers", "effect.unicopia.change_race_earth": "Earth Pony Metamorphosis", + "effect.unicopia.change_race_pegasus": "Pegasus Metamorphosis", + "effect.unicopia.change_race_changeling": "Changeling Metamorphosis", + "effect.unicopia.change_race_bat": "Bat Pony Metamorphosis", + "effect.unicopia.change_race_kirin": "Kirin Metamorphosis", + "effect.unicopia.change_race_hippogriff": "Hippogriff Metamorphosis", + + "effect.unicopia.morph_race_earth": "Earth Pony Transformation", + "effect.unicopia.morph_race_pegasus": "Pegasus Transformation", + "effect.unicopia.morph_race_changeling": "Changeling Transformation", + "effect.unicopia.morph_race_bat": "Bat Pony Transformation", + "effect.unicopia.morph_race_kirin": "Kirin Transformation", + "effect.unicopia.morph_race_hippogriff": "Hippogriff Transformation", + "item.minecraft.potion.effect.unicopia.tribe_swap_earth": "Potion of Earth Pony Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_earth": "Splash Potion of Earth Pony Metamorphosis", "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_earth": "Lingering Potion of Earth Pony Metamorphosis", @@ -363,36 +376,101 @@ "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_unicorn": "Lingering Potion of Unicorn Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_unicorn": "Arrow of Unicorn Metamorphosis", - "effect.unicopia.change_race_pegasus": "Pegasus Metamorphosis", "item.minecraft.potion.effect.unicopia.tribe_swap_pegasus": "Potion of Pegasus Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_pegasus": "Splash Potion of Pegasus Metamorphosis", "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_pegasus": "Lingering Potion of Pegasus Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_pegasus": "Arrow of Pegasus Metamorphosis", - "effect.unicopia.change_race_changeling": "Changeling Metamorphosis", "item.minecraft.potion.effect.unicopia.tribe_swap_changeling": "Potion of Changeling Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_changeling": "Splash Potion of Changeling Metamorphosis", "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_changeling": "Lingering Potion of Changeling Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_changeling": "Arrow of Changeling Metamorphosis", - "effect.unicopia.change_race_bat": "Bat Pony Metamorphosis", "item.minecraft.potion.effect.unicopia.tribe_swap_bat": "Potion of Bat Pony Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_bat": "Splash Potion of Bat Pony Metamorphosis", "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_bat": "Lingering Potion of Bat Pony Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_bat": "Arrow of Bat Pony Metamorphosis", - "effect.unicopia.change_race_kirin": "Kirin Metamorphosis", "item.minecraft.potion.effect.unicopia.tribe_swap_kirin": "Potion of Kirin Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_kirin": "Splash Potion of Kirin Metamorphosis", "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_kirin": "Lingering Potion of Kirin Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_kirin": "Arrow of Kirin Metamorphosis", - "effect.unicopia.change_race_hippogriff": "Hippogriff Metamorphosis", "item.minecraft.potion.effect.unicopia.tribe_swap_hippogriff": "Potion of Hippogriff Metamorphosis", "item.minecraft.splash_potion.effect.unicopia.tribe_swap_hippogriff": "Splash Potion of Hippogriff Metamorphosis", "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_hippogriff": "Lingering Potion of Hippogriff Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_hippogriff": "Arrow of Hippogriff Metamorphosis", + "item.minecraft.potion.effect.unicopia.short_morph_earth": "Potion of Earth Pony Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_earth": "Splash Potion of Earth Pony Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_earth": "Lingering Potion of Earth Pony Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_earth": "Arrow of Earth Pony Short Transformation", + + "item.minecraft.potion.effect.unicopia.short_morph_unicorn": "Potion of Unicorn Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_unicorn": "Splash Potion of Unicorn Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_unicorn": "Lingering Potion of Unicorn Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_unicorn": "Arrow of Unicorn Short Transformation", + + "item.minecraft.potion.effect.unicopia.short_morph_pegasus": "Potion of Pegasus Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_pegasus": "Splash Potion of Pegasus Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_pegasus": "Lingering Potion of Pegasus Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_pegasus": "Arrow of Pegasus Short Transformation", + + "item.minecraft.potion.effect.unicopia.short_morph_changeling": "Potion of Changeling Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_changeling": "Splash Potion of Changeling Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_changeling": "Lingering Potion of Changeling Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_changeling": "Arrow of Changeling Short Transformation", + + "item.minecraft.potion.effect.unicopia.short_morph_bat": "Potion of Bat Pony Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_bat": "Splash Potion of Bat Pony Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_bat": "Lingering Potion of Bat Pony Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_bat": "Arrow of Bat Pony Short Transformation", + + "item.minecraft.potion.effect.unicopia.short_morph_kirin": "Potion of Kirin Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_kirin": "Splash Potion of Kirin Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_kirin": "Lingering Potion of Kirin Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_kirin": "Arrow of Kirin Short Transformation", + + "item.minecraft.potion.effect.unicopia.short_morph_hippogriff": "Potion of Hippogriff Short Transformation", + "item.minecraft.splash_potion.effect.unicopia.short_morph_hippogriff": "Splash Potion of Hippogriff Short Transformation", + "item.minecraft.lingering_potion.effect.unicopia.short_morph_hippogriff": "Lingering Potion of Hippogriff Short Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.short_morph_hippogriff": "Arrow of Hippogriff Short Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_earth": "Potion of Earth Pony Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_earth": "Splash Potion of Earth Pony Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_earth": "Lingering Potion of Earth Pony Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_earth": "Arrow of Earth Pony Long Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_unicorn": "Potion of Unicorn Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_unicorn": "Splash Potion of Unicorn Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_unicorn": "Lingering Potion of Unicorn Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_unicorn": "Arrow of Unicorn Long Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_pegasus": "Potion of Pegasus Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_pegasus": "Splash Potion of Pegasus Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_pegasus": "Lingering Potion of Pegasus Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_pegasus": "Arrow of Pegasus Long Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_changeling": "Potion of Changeling Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_changeling": "Splash Potion of Changeling Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_changeling": "Lingering Potion of Changeling Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_changeling": "Arrow of Changeling Long Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_bat": "Potion of Bat Pony Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_bat": "Splash Potion of Bat Pony Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_bat": "Lingering Potion of Bat Pony Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_bat": "Arrow of Bat Pony Long Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_kirin": "Potion of Kirin Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_kirin": "Splash Potion of Kirin Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_kirin": "Lingering Potion of Kirin Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_kirin": "Arrow of Kirin Long Transformation", + + "item.minecraft.potion.effect.unicopia.long_morph_hippogriff": "Potion of Hippogriff Long Transformation", + "item.minecraft.splash_potion.effect.unicopia.long_morph_hippogriff": "Splash Potion of Hippogriff Long Transformation", + "item.minecraft.lingering_potion.effect.unicopia.long_morph_hippogriff": "Lingering Potion of Hippogriff Long Transformation", + "item.minecraft.tipped_arrow.effect.unicopia.long_morph_hippogriff": "Arrow of Hippogriff Long Transformation", + "potion.withChance": "1 in %s chance of %s", "potion.potency.6": "VII", diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/change_race_hippogriff.png b/src/main/resources/assets/unicopia/textures/mob_effect/change_race_hippogriff.png new file mode 100644 index 00000000..057c2240 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/change_race_hippogriff.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/change_race_kirin.png b/src/main/resources/assets/unicopia/textures/mob_effect/change_race_kirin.png new file mode 100644 index 00000000..33be07ce Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/change_race_kirin.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_bat.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_bat.png new file mode 100644 index 00000000..77ef99b8 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_bat.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_changeling.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_changeling.png new file mode 100644 index 00000000..c29bf471 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_changeling.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_earth.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_earth.png new file mode 100644 index 00000000..c0d08791 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_earth.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_hippogriff.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_hippogriff.png new file mode 100644 index 00000000..f52bfd19 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_hippogriff.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_kirin.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_kirin.png new file mode 100644 index 00000000..ef61eebd Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_kirin.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_pegasus.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_pegasus.png new file mode 100644 index 00000000..56b4c3e0 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_pegasus.png differ diff --git a/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_unicorn.png b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_unicorn.png new file mode 100644 index 00000000..b8151af3 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/mob_effect/morph_race_unicorn.png differ