From c3e854fdd1f8a32cdafd39c3a3d77b9f38453c9f Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 25 Aug 2021 00:32:39 +0200 Subject: [PATCH] Added a transformation spell --- .../com/minelittlepony/unicopia/UTags.java | 7 ++ .../ability/magic/spell/SpellType.java | 1 + .../magic/spell/TransformationSpell.java | 72 +++++++++++++++++++ .../projectile/MagicProjectileEntity.java | 33 +++++---- .../resources/assets/unicopia/lang/en_us.json | 3 + .../tags/entity_types/transformable.json | 48 +++++++++++++ 6 files changed, 151 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java create mode 100644 src/main/resources/data/unicopia/tags/entity_types/transformable.json diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 2d27721e..83aaf938 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.item.toxin.Toxics; import net.fabricmc.fabric.api.tag.TagRegistry; import net.minecraft.block.Block; +import net.minecraft.entity.EntityType; import net.minecraft.item.Item; import net.minecraft.tag.Tag; import net.minecraft.util.Identifier; @@ -24,6 +25,8 @@ public interface UTags { Tag CRYSTAL_HEART_BASE = block("crystal_heart_base"); Tag CRYSTAL_HEART_ORNAMENT = block("crystal_heart_ornament"); + Tag> TRANSFORMABLE_ENTITIES = entity("transformable"); + static Tag item(String name) { return TagRegistry.item(new Identifier("unicopia", name)); } @@ -32,6 +35,10 @@ public interface UTags { return TagRegistry.block(new Identifier("unicopia", name)); } + static Tag> entity(String name) { + return TagRegistry.entityType(new Identifier("unicopia", name)); + } + static void bootstrap() { Toxics.bootstrap(); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java index 713922b5..f43107e0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java @@ -44,6 +44,7 @@ public final class SpellType implements Affine, SpellPredicate< public static final SpellType REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new); public static final SpellType JOUSTING = register("joust", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new); public static final SpellType AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new); + public static final SpellType TRANSFORMATION = register("transformation", Affinity.NEUTRAL, 0x3A59AA, true, TransformationSpell::new); private final Identifier id; private final Affinity affinity; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java new file mode 100644 index 00000000..aa83e939 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/TransformationSpell.java @@ -0,0 +1,72 @@ +package com.minelittlepony.unicopia.ability.magic.spell; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Optional; +import java.util.Random; +import java.util.Set; + +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.ability.magic.Thrown; +import com.minelittlepony.unicopia.entity.UEntities; +import com.minelittlepony.unicopia.particle.ParticleUtils; +import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Util; + +public class TransformationSpell extends AbstractSpell implements Thrown { + + protected TransformationSpell(SpellType type) { + super(type); + } + + @Override + public boolean onThrownTick(MagicProjectileEntity source) { + return true; + } + + @Override + public void onImpact(MagicProjectileEntity projectile, Entity entity) { + if (projectile.world.isClient) { + return; + } + pickType(entity.getType(), entity.world.random).flatMap(type -> convert(entity, type)).ifPresentOrElse(e -> { + entity.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 1, 1); + }, () -> { + ParticleUtils.spawnParticles(ParticleTypes.SMOKE, entity, 20); + entity.playSound(SoundEvents.BLOCK_NOTE_BLOCK_DIDGERIDOO, 1, 1); + }); + } + + private Optional convert(Entity entity, EntityType type) { + if (entity instanceof MobEntity) { + MobEntity mob = (MobEntity)entity; + try { + return Optional.ofNullable(mob.convertTo(type, true)); + } catch (Exception e) { + return Optional.ofNullable(mob.convertTo(UEntities.BUTTERFLY, true)); + } + } + + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + private Optional> pickType(EntityType except, Random random) { + Set> options = new HashSet<>(UTags.TRANSFORMABLE_ENTITIES.values()); + if (except.getSpawnGroup() == SpawnGroup.MONSTER) { + options.removeIf(t -> t.getSpawnGroup() == SpawnGroup.MONSTER); + } else { + options.remove(except); + } + if (options.size() <= 1) { + return options.stream().findFirst().map(t -> (EntityType)t); + } + return Optional.ofNullable((EntityType)Util.getRandom(new ArrayList<>(options), random)); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java index a0e6fab5..40b4dd84 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java @@ -1,5 +1,7 @@ package com.minelittlepony.unicopia.projectile; +import java.util.function.Consumer; + import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Caster; @@ -145,7 +147,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster
  • spell.onThrownTick(this)).isPresent()) { - remove(RemovalReason.DISCARDED); + discard(); } } @@ -229,25 +231,21 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster
  • { - effect.onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos())); - }); + super.onBlockHit(hit); - if (getItem().getItem() instanceof ProjectileDelegate) { - ((ProjectileDelegate)getItem().getItem()).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos())); - } + forEachDelegates(effect -> effect.onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()))); } @Override @@ -259,11 +257,20 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster
  • 0) { + entity.damage(DamageSource.thrownProjectile(this, getOwner()), getThrowDamage()); + } + + forEachDelegates(effect -> effect.onImpact(this, entity)); + } + } + + protected void forEachDelegates(Consumer consumer) { + getSpellSlot().get(SpellPredicate.IS_THROWN, true).ifPresent(consumer); if (getItem().getItem() instanceof ProjectileDelegate) { - ((ProjectileDelegate)getItem().getItem()).onImpact(this, entity); + consumer.accept(((ProjectileDelegate)getItem().getItem())); } } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 574024cf..4babe047 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -156,6 +156,9 @@ "spell.unicopia.awkward": "Unstable", "spell.unicopia.awkward.lore": "Chaos I", + + "spell.unicopia.transformation": "Transformation", + "spell.unicopia.transformation.lore": "Chaos II", "toxicity.safe.name": "Safe", "toxicity.mild.name": "Mildly Toxic", diff --git a/src/main/resources/data/unicopia/tags/entity_types/transformable.json b/src/main/resources/data/unicopia/tags/entity_types/transformable.json new file mode 100644 index 00000000..978ad1bf --- /dev/null +++ b/src/main/resources/data/unicopia/tags/entity_types/transformable.json @@ -0,0 +1,48 @@ +{ + "replace": false, + "values": [ + "minecraft:skeleton", + "minecraft:wither_skeleton", + "minecraft:zombie", + "minecraft:drowned", + "minecraft:husk", + "minecraft:creeper", + "minecraft:villager", + "minecraft:wandering_trader", + "minecraft:wither_skeleton", + "minecraft:witch", + "minecraft:turtle", + "minecraft:zombie_villager", + "minecraft:blaze", + "minecraft:sheep", + "minecraft:salmon", + "minecraft:rabbit", + "minecraft:pufferfish", + "minecraft:pillager", + "minecraft:polar_bear", + "minecraft:pig", + "minecraft:llama", + "minecraft:goat", + "minecraft:illusioner", + "minecraft:donkey", + "minecraft:cow", + "minecraft:cod", + "minecraft:mooshroom", + "minecraft:panda", + "minecraft:parrot", + "minecraft:chicken", + "minecraft:spider", + "minecraft:cave_spider", + "minecraft:mule", + "minecraft:magma_cube", + "minecraft:cat", + "minecraft:ocelot", + "minecraft:bee", + "minecraft:squid", + "minecraft:glow_squid", + "minecraft:fox", + "minecraft:wolf", + "minecraft:horse", + "unicopia:butterfly" + ] +}