diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java index 5fea4509..39809964 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlaceableSpell.java @@ -83,7 +83,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell { } if (situation == Situation.GROUND_ENTITY) { - particlEffect.ifAbsent(getUuid(), source, spawner -> { + particlEffect.update(getUuid(), source, spawner -> { spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), source.getOriginVector(), Vec3d.ZERO); }).ifPresent(p -> { p.setAttribute(1, spell.getType().getColor()); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java index 40c57bad..5ea7eeb3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java @@ -54,10 +54,10 @@ public class RainboomAbilitySpell extends AbstractSpell { } if (source.isClient()) { - particlEffect.ifAbsent(getUuid(), source, spawner -> { + particlEffect.update(getUuid(), source, spawner -> { spawner.addParticle(UParticles.RAINBOOM_TRAIL, source.getOriginVector(), Vec3d.ZERO); - spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, source.getPhysics().getMotionAngle()), source.getOriginVector(), Vec3d.ZERO); }); + source.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, source.getPhysics().getMotionAngle()), source.getOriginVector(), Vec3d.ZERO); } LivingEntity owner = source.getMaster(); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java index ac0aa3e6..179c9724 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java @@ -5,22 +5,31 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.Situation; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; -import com.minelittlepony.unicopia.particle.DiskParticleEffect; import com.minelittlepony.unicopia.particle.SphereParticleEffect; +import com.minelittlepony.unicopia.particle.UParticles; +import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; +import com.minelittlepony.unicopia.projectile.ProjectileDelegate; import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.PosHelper; import com.minelittlepony.unicopia.util.shape.Sphere; import net.minecraft.entity.Entity; +import net.minecraft.entity.FallingBlockEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.projectile.PersistentProjectileEntity; +import net.minecraft.item.Item; import net.minecraft.nbt.NbtCompound; import net.minecraft.particle.ParticleTypes; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.Vec3f; /** - * More powerful version of the vortex spell which creates a black hole + * More powerful version of the vortex spell which creates a black hole. + * + * TODO: Possible uses + * - Garbage bin + * - Link with a teleportation spell to create a wormhole */ public class DarkVortexSpell extends AttractiveSpell { public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder() @@ -55,15 +64,17 @@ public class DarkVortexSpell extends AttractiveSpell { setDirty(); if (age % 20 == 0) { - source.getWorld().playSound(null, source.getOrigin(), SoundEvents.AMBIENT_SOUL_SAND_VALLEY_MOOD, SoundCategory.AMBIENT, 1, 1); + source.getWorld().playSound(null, source.getOrigin(), SoundEvents.AMBIENT_SOUL_SAND_VALLEY_ADDITIONS, SoundCategory.AMBIENT, 1, 1); } + source.subtractEnergyCost(-accumulatedMass); + return super.tick(source, situation); } @Override public boolean isFriendlyTogether(Affine other) { - return accumulatedMass < 150 && super.isFriendlyTogether(other); + return accumulatedMass < 4; } @Override @@ -77,16 +88,27 @@ public class DarkVortexSpell extends AttractiveSpell { float radius = (float)getEventHorizonRadius(); - particlEffect.ifAbsent(getUuid(), source, spawner -> { - spawner.addParticle(new SphereParticleEffect(getType().getColor(), 0.99F, radius, SPHERE_OFFSET), source.getOriginVector(), Vec3d.ZERO); + particlEffect.update(getUuid(), source, spawner -> { + spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, getType().getColor(), 0.99F, radius, SPHERE_OFFSET), source.getOriginVector(), Vec3d.ZERO); }).ifPresent(p -> { p.setAttribute(0, radius); }); + particlEffect.update(getUuid(), "_ring", source, spawner -> { + spawner.addParticle(new SphereParticleEffect(UParticles.DISK, 0xFFFFFFFF, 0.4F, radius + 1, SPHERE_OFFSET), getOrigin(source), Vec3d.ZERO); + }).ifPresent(p -> { + p.setAttribute(0, radius * 2F); + p.setAttribute(1, 0xAAAAAA); + }); + + double angle = age % 260; source.spawnParticles(ParticleTypes.SMOKE, 3); - if (age % 11 == 0) { - source.addParticle(new DiskParticleEffect(Vec3f.ZERO, 1, radius + 1), getOrigin(source), Vec3d.ZERO); + if (radius > 2) { + source.addParticle(new SphereParticleEffect(UParticles.DISK, 0xFF0000, 1, radius), + getOrigin(source).add(0, 0.2, 0), new Vec3d(0, angle, 10)); + source.addParticle(new SphereParticleEffect(UParticles.DISK, 0xFF0000, 1, radius), + getOrigin(source).add(0, -0.2, 0), new Vec3d(0, angle, 10)); } } @@ -106,12 +128,19 @@ public class DarkVortexSpell extends AttractiveSpell { double radius = getEventHorizonRadius(); - if (radius > 3) { + if (radius > 5) { Vec3d origin = getOrigin(source); PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius)).forEach(i -> { - CatapultSpell.createBlockEntity(source.getWorld(), i, e -> { - applyRadialEffect(source, e, e.getPos().distanceTo(origin), radius); - }); + if (!source.getWorld().getFluidState(i).isEmpty()) { + return; + } + if (source.getOrigin().isWithinDistance(i, getEventHorizonRadius())) { + source.getWorld().breakBlock(i, false); + } else { + CatapultSpell.createBlockEntity(source.getWorld(), i, e -> { + applyRadialEffect(source, e, e.getPos().distanceTo(origin), radius); + }); + } setDirty(); }); } @@ -125,7 +154,7 @@ public class DarkVortexSpell extends AttractiveSpell { // 3. force reaches 0 at distance of drawDropOffRange private double getEventHorizonRadius() { - return Math.sqrt(Math.max(0.001, getMass() - 10)); + return Math.sqrt(Math.max(0.001, getMass() - 12)); } private double getAttractiveForce(Caster source, Entity target) { @@ -133,8 +162,8 @@ public class DarkVortexSpell extends AttractiveSpell { } private double getMass() { - float pulse = (float)Math.sin(age * 6) / 8F; - return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + pulse + accumulatedMass / 10F); + float pulse = (float)Math.sin(age * 8) / 1F; + return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse; } private double getMass(Entity entity) { @@ -144,15 +173,38 @@ public class DarkVortexSpell extends AttractiveSpell { @Override protected void applyRadialEffect(Caster source, Entity target, double distance, double radius) { + if (target instanceof FallingBlockEntity && source.isClient()) { + return; + } + if (distance <= getEventHorizonRadius()) { + + if (target instanceof MagicProjectileEntity) { + Item item = ((MagicProjectileEntity)target).getStack().getItem(); + if (item instanceof ProjectileDelegate) { + ((ProjectileDelegate) item).onImpact(((MagicProjectileEntity)target), source.getMaster()); + } + } else if (target instanceof PersistentProjectileEntity) { + source.getMaster().damage(DamageSource.thrownProjectile(target, ((PersistentProjectileEntity)target).getOwner()), 4); + target.discard(); + return; + } + accumulatedMass += getMass(target); + setDirty(); target.damage(MagicalDamageSource.create("black_hole"), Integer.MAX_VALUE); - target.discard(); + + source.subtractEnergyCost(-getMass(target) * 10); + + source.getWorld().playSound(null, source.getOrigin(), SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD, SoundCategory.AMBIENT, 2, 0.02F); + } else { double force = getAttractiveForce(source, target); target.setVelocity(target.getVelocity().multiply(Math.min(1, 1 - force))); applyForce(getOrigin(source), target, -force, 0); + + source.subtractEnergyCost(-2); } } @@ -170,3 +222,9 @@ public class DarkVortexSpell extends AttractiveSpell { accumulatedMass = compound.getFloat("accumulatedMass"); } } + + + + + + diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java index acef1d68..a97b9d2d 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ShieldSpell.java @@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.ParticleHandle; import com.minelittlepony.unicopia.particle.SphereParticleEffect; +import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.projectile.ProjectileUtil; import com.minelittlepony.unicopia.util.shape.Sphere; @@ -63,8 +64,8 @@ public class ShieldSpell extends AbstractSpell { source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO); }); - particlEffect.ifAbsent(getUuid(), source, spawner -> { - spawner.addParticle(new SphereParticleEffect(getType().getColor(), 0.3F, radius), origin, Vec3d.ZERO); + particlEffect.update(getUuid(), source, spawner -> { + spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, getType().getColor(), 0.3F, radius), origin, Vec3d.ZERO); }).ifPresent(p -> { p.setAttribute(0, radius); p.setAttribute(1, getType().getColor()); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java index ca463ccc..7c45adeb 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TargetSelecter.java @@ -29,14 +29,19 @@ public class TargetSelecter { Entity owner = source.getMaster(); - boolean ownerIsValid = spell.isFriendlyTogether(source) && (EquinePredicates.PLAYER_UNICORN.test(owner) && owner.isSneaking()); + boolean ownerIsValid = spell.isFriendlyTogether(source) && (EquinePredicates.PLAYER_UNICORN.test(owner)); return source.findAllEntitiesInRange(radius) .filter(entity -> !entity.isRemoved()) .filter(entity -> { - return !FriendshipBraceletItem.isComrade(source, entity) - && !SpellPredicate.IS_SHIELD_LIKE.isOn(entity) - && !(ownerIsValid && (Pony.equal(entity, owner) || owner.isConnectedThroughVehicle(entity))); + boolean hasShield = SpellPredicate.IS_SHIELD_LIKE.isOn(entity); + boolean isOwnerOrFriend = Pony.equal(entity, owner) || owner.isConnectedThroughVehicle(entity) || FriendshipBraceletItem.isComrade(source, entity); + + if (!ownerIsValid && isOwnerOrFriend) { + return true; + } + + return !hasShield && (!ownerIsValid || !isOwnerOrFriend); }) .filter(e -> filter.test(source, e)) .map(i -> { diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java index cf70cb64..ce1c812a 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java @@ -19,7 +19,7 @@ public class DiskParticle extends SphereParticle { @Override protected void renderModel(MatrixStack matrices, VertexConsumer buffer, float scale, float tickDelta, int light) { matrices.multiply(rotation); - SphereModel.DISK.render(matrices, buffer, 1, light, scale, 1, 1, 1, 1); + SphereModel.DISK.render(matrices, buffer, light, 1, scale, 1, 1, 1, 1); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java index ed85412f..7d571b4c 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java @@ -85,6 +85,9 @@ public class SphereParticle extends Particle implements Attachment { colorGreen = Color.g(tint); colorBlue = Color.b(tint); } + if (key == 2) { + colorAlpha = (float)value; + } } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/particle/DiskParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/DiskParticleEffect.java deleted file mode 100644 index 4ee4d992..00000000 --- a/src/main/java/com/minelittlepony/unicopia/particle/DiskParticleEffect.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.minelittlepony.unicopia.particle; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; - -import net.minecraft.network.PacketByteBuf; -import net.minecraft.particle.ParticleType; -import net.minecraft.util.math.Vec3f; - -public class DiskParticleEffect extends SphereParticleEffect { - @SuppressWarnings("deprecation") - public static final Factory FACTORY = ParticleFactoryHelper.of(DiskParticleEffect::new, DiskParticleEffect::new); - - protected DiskParticleEffect(ParticleType type, StringReader reader) throws CommandSyntaxException { - super(type, reader); - } - - protected DiskParticleEffect(ParticleType type, PacketByteBuf buf) { - super(type, buf); - } - - public DiskParticleEffect(Vec3f color, float alpha, float rad) { - super(color, alpha, rad); - } - - @Override - public ParticleType getType() { - return UParticles.DISK; - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java b/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java index 45bf37fd..69ef6eec 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/ParticleHandle.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia.particle; import java.lang.ref.WeakReference; +import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -13,53 +14,71 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.particle.Particle; -import net.minecraft.particle.ParticleEffect; -import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; /** * A connection class for updating and persisting an attached particle effect. */ public class ParticleHandle { - private Optional> particleEffect = Optional.empty(); + private final Map loadedEffects = new WeakHashMap<>(); - public Optional ifAbsent(UUID id, ParticleSource source, Consumer constructor) { - return get().or(() -> { + public Optional update(UUID id, ParticleSource source, Consumer constructor) { + return update(id, "prime", source, constructor); + } + + public Optional update(UUID id, String partName, ParticleSource source, Consumer constructor) { + return get(partName).or(() -> { if (source.getWorld().isClient) { - constructor.accept((effect, pos, vel) -> new ClientHandle().addParticle(id, source, effect, pos, vel)); + new ClientHandle().addParticle(id, partName, source, constructor); } - return get(); + return get(partName); }); } public void destroy() { - get().ifPresent(Attachment::detach); + loadedEffects.values().forEach(Attachment::detach); + loadedEffects.clear(); } - private Optional get() { - return particleEffect.map(WeakReference::get).filter(Attachment::isStillAlive); + private Optional get(String partName) { + return Optional.ofNullable(loadedEffects.get(partName)).filter(Attachment::isStillAlive); } private final class ClientHandle { - private static final Map SPAWNED_PARTICLES = new WeakHashMap<>(); + private static final Map> SPAWNED_PARTICLES = new HashMap<>(); + + private Particle pp; @Environment(EnvType.CLIENT) - private void addParticle(UUID id, ParticleSource source, ParticleEffect effect, Vec3d pos, Vec3d vel) { - Particle p = SPAWNED_PARTICLES.computeIfAbsent(id, i -> { - Particle pp = MinecraftClient.getInstance().particleManager.addParticle(effect, pos.x, pos.y, pos.z, vel.x, vel.y, vel.z); - if (pp instanceof Attachment && source instanceof Caster) { - ((Attachment) pp).attach(new Link(id, (Caster)source)); - } - return pp; + private void addParticle(UUID id, String partName, ParticleSource source, Consumer constructor) { + SPAWNED_PARTICLES.values().removeIf(set -> { + set.values().removeIf(particle -> particle.get() == null); + return set.isEmpty(); }); - if (p instanceof Attachment) { - particleEffect = Optional.of(new WeakReference<>((Attachment)p)); + Entry p = SPAWNED_PARTICLES.computeIfAbsent(id, i -> new HashMap<>()).computeIfAbsent(partName, i -> { + constructor.accept((effect, pos, vel) -> { + pp = MinecraftClient.getInstance().particleManager.addParticle(effect, pos.x, pos.y, pos.z, vel.x, vel.y, vel.z); + if (pp instanceof Attachment && source instanceof Caster) { + ((Attachment) pp).attach(new Link(id, (Caster)source)); + } + }); + return new Entry(new WeakReference<>(MinecraftClient.getInstance().world), new WeakReference<>(pp)); + }); + + if (p.get() instanceof Attachment) { + loadedEffects.put(partName, (Attachment)p.get()); + } + } + + record Entry (WeakReference world, WeakReference particle) { + public Particle get() { + return world.get() == null || world.get() != MinecraftClient.getInstance().world ? null : particle.get(); } } } public interface Attachment { - boolean isStillAlive(); void attach(Link link); diff --git a/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java b/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java index 7a1246da..768f18fe 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/ParticleSource.java @@ -43,5 +43,4 @@ public interface ParticleSource extends ParticleSpawner { default void addParticle(ParticleEffect effect, Vec3d position, Vec3d velocity) { getWorld().addParticle(effect, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z); } - } diff --git a/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java index 4de0defa..2a6e7645 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java @@ -26,27 +26,30 @@ public class SphereParticleEffect implements ParticleEffect { private Vec3d offset = Vec3d.ZERO; + private final ParticleType type; + protected SphereParticleEffect(ParticleType type, StringReader reader) throws CommandSyntaxException { - this(AbstractDustParticleEffect.readColor(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readVector(reader)); + this(type, AbstractDustParticleEffect.readColor(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readVector(reader)); } protected SphereParticleEffect(ParticleType type, PacketByteBuf buf) { - this(AbstractDustParticleEffect.readColor(buf), buf.readFloat(), buf.readFloat()); + this(type, AbstractDustParticleEffect.readColor(buf), buf.readFloat(), buf.readFloat()); } - public SphereParticleEffect(int tint, float alpha, float rad) { - this(tint, alpha, rad, DEFAULT_OFFSET); + public SphereParticleEffect(ParticleType type, int tint, float alpha, float rad) { + this(type, tint, alpha, rad, DEFAULT_OFFSET); } - public SphereParticleEffect(Vec3f color, float alpha, float rad) { - this(color, alpha, rad, DEFAULT_OFFSET); + public SphereParticleEffect(ParticleType type, Vec3f color, float alpha, float rad) { + this(type, color, alpha, rad, DEFAULT_OFFSET); } - public SphereParticleEffect(int tint, float alpha, float rad, Vec3d offset) { - this(new Vec3f(Color.r(tint), Color.g(tint), Color.b(tint)), alpha, rad, offset); + public SphereParticleEffect(ParticleType type, int tint, float alpha, float rad, Vec3d offset) { + this(type, new Vec3f(Color.r(tint), Color.g(tint), Color.b(tint)), alpha, rad, offset); } - public SphereParticleEffect(Vec3f color, float alpha, float rad, Vec3d offset) { + public SphereParticleEffect(ParticleType type, Vec3f color, float alpha, float rad, Vec3d offset) { + this.type = type; this.color = color; this.offset = offset; this.alpha = alpha; @@ -71,7 +74,7 @@ public class SphereParticleEffect implements ParticleEffect { @Override public ParticleType getType() { - return UParticles.SPHERE; + return type; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java index 2af541f3..be954443 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java @@ -19,7 +19,7 @@ public interface UParticles { DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple()); ParticleType SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY)); - ParticleType DISK = register("disk", FabricParticleTypes.complex(true, DiskParticleEffect.FACTORY)); + ParticleType DISK = register("disk", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY)); ParticleType HEALTH_DRAIN = register("health_drain", FabricParticleTypes.complex(true, FollowingParticleEffect.FACTORY)); diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java index 7bb9e320..975863df 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java @@ -159,9 +159,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster
  • spell.tick(this, Situation.PROJECTILE)).isPresent()) { - discard(); - } + getSpellSlot().get(true).filter(spell -> spell.tick(this, Situation.PROJECTILE)); if (getHydrophobic()) { if (world.getBlockState(getBlockPos()).getMaterial().isLiquid()) { diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 66b3686e..62e8cb0f 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -430,6 +430,8 @@ "death.attack.paradox": "%1$s imploded", "death.attack.food_poisoning": "%1$s died of food poisoning", "death.attack.food_poisoning.attacker": "%2$s poisoned %1$s to death", + "death.attach.back_hole": "%1$s was sucked into a black hole", + "death.attach.back_hole": "%1$s got sucked into %2$s's black hole", "unicopia.subtitle.flap_wings": "Wing Flaps", "unicopia.subtitle.wind_rush": "Wind Gust",