Fixed jars, fixed particles not respawning correctly when reloading a world, fixed some behaviours with black holes

This commit is contained in:
Sollace 2021-12-26 20:13:28 +02:00
parent 76506665bc
commit bb29d97ff3
14 changed files with 151 additions and 93 deletions

View file

@ -83,7 +83,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell {
} }
if (situation == Situation.GROUND_ENTITY) { 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); spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), source.getOriginVector(), Vec3d.ZERO);
}).ifPresent(p -> { }).ifPresent(p -> {
p.setAttribute(1, spell.getType().getColor()); p.setAttribute(1, spell.getType().getColor());

View file

@ -54,10 +54,10 @@ public class RainboomAbilitySpell extends AbstractSpell {
} }
if (source.isClient()) { if (source.isClient()) {
particlEffect.ifAbsent(getUuid(), source, spawner -> { particlEffect.update(getUuid(), source, spawner -> {
spawner.addParticle(UParticles.RAINBOOM_TRAIL, source.getOriginVector(), Vec3d.ZERO); 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(); LivingEntity owner = source.getMaster();

View file

@ -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.Situation;
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; 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.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.MagicalDamageSource;
import com.minelittlepony.unicopia.util.PosHelper; import com.minelittlepony.unicopia.util.PosHelper;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.entity.Entity; 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.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.Vec3d; 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 class DarkVortexSpell extends AttractiveSpell {
public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder() public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder()
@ -55,15 +64,17 @@ public class DarkVortexSpell extends AttractiveSpell {
setDirty(); setDirty();
if (age % 20 == 0) { 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); return super.tick(source, situation);
} }
@Override @Override
public boolean isFriendlyTogether(Affine other) { public boolean isFriendlyTogether(Affine other) {
return accumulatedMass < 150 && super.isFriendlyTogether(other); return accumulatedMass < 4;
} }
@Override @Override
@ -77,16 +88,27 @@ public class DarkVortexSpell extends AttractiveSpell {
float radius = (float)getEventHorizonRadius(); float radius = (float)getEventHorizonRadius();
particlEffect.ifAbsent(getUuid(), source, spawner -> { particlEffect.update(getUuid(), source, spawner -> {
spawner.addParticle(new SphereParticleEffect(getType().getColor(), 0.99F, radius, SPHERE_OFFSET), source.getOriginVector(), Vec3d.ZERO); spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, getType().getColor(), 0.99F, radius, SPHERE_OFFSET), source.getOriginVector(), Vec3d.ZERO);
}).ifPresent(p -> { }).ifPresent(p -> {
p.setAttribute(0, radius); 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); source.spawnParticles(ParticleTypes.SMOKE, 3);
if (age % 11 == 0) { if (radius > 2) {
source.addParticle(new DiskParticleEffect(Vec3f.ZERO, 1, radius + 1), getOrigin(source), Vec3d.ZERO); 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(); double radius = getEventHorizonRadius();
if (radius > 3) { if (radius > 5) {
Vec3d origin = getOrigin(source); Vec3d origin = getOrigin(source);
PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius)).forEach(i -> { PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius)).forEach(i -> {
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 -> { CatapultSpell.createBlockEntity(source.getWorld(), i, e -> {
applyRadialEffect(source, e, e.getPos().distanceTo(origin), radius); applyRadialEffect(source, e, e.getPos().distanceTo(origin), radius);
}); });
}
setDirty(); setDirty();
}); });
} }
@ -125,7 +154,7 @@ public class DarkVortexSpell extends AttractiveSpell {
// 3. force reaches 0 at distance of drawDropOffRange // 3. force reaches 0 at distance of drawDropOffRange
private double getEventHorizonRadius() { 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) { private double getAttractiveForce(Caster<?> source, Entity target) {
@ -133,8 +162,8 @@ public class DarkVortexSpell extends AttractiveSpell {
} }
private double getMass() { private double getMass() {
float pulse = (float)Math.sin(age * 6) / 8F; float pulse = (float)Math.sin(age * 8) / 1F;
return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + pulse + accumulatedMass / 10F); return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse;
} }
private double getMass(Entity entity) { private double getMass(Entity entity) {
@ -144,15 +173,38 @@ public class DarkVortexSpell extends AttractiveSpell {
@Override @Override
protected void applyRadialEffect(Caster<?> source, Entity target, double distance, double radius) { protected void applyRadialEffect(Caster<?> source, Entity target, double distance, double radius) {
if (target instanceof FallingBlockEntity && source.isClient()) {
return;
}
if (distance <= getEventHorizonRadius()) { if (distance <= getEventHorizonRadius()) {
accumulatedMass += getMass(target);
target.damage(MagicalDamageSource.create("black_hole"), Integer.MAX_VALUE); 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(); target.discard();
return;
}
accumulatedMass += getMass(target);
setDirty();
target.damage(MagicalDamageSource.create("black_hole"), Integer.MAX_VALUE);
source.subtractEnergyCost(-getMass(target) * 10);
source.getWorld().playSound(null, source.getOrigin(), SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD, SoundCategory.AMBIENT, 2, 0.02F);
} else { } else {
double force = getAttractiveForce(source, target); double force = getAttractiveForce(source, target);
target.setVelocity(target.getVelocity().multiply(Math.min(1, 1 - force))); target.setVelocity(target.getVelocity().multiply(Math.min(1, 1 - force)));
applyForce(getOrigin(source), target, -force, 0); applyForce(getOrigin(source), target, -force, 0);
source.subtractEnergyCost(-2);
} }
} }
@ -170,3 +222,9 @@ public class DarkVortexSpell extends AttractiveSpell {
accumulatedMass = compound.getFloat("accumulatedMass"); accumulatedMass = compound.getFloat("accumulatedMass");
} }
} }

View file

@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.particle.ParticleHandle; import com.minelittlepony.unicopia.particle.ParticleHandle;
import com.minelittlepony.unicopia.particle.SphereParticleEffect; import com.minelittlepony.unicopia.particle.SphereParticleEffect;
import com.minelittlepony.unicopia.particle.UParticles;
import com.minelittlepony.unicopia.projectile.ProjectileUtil; import com.minelittlepony.unicopia.projectile.ProjectileUtil;
import com.minelittlepony.unicopia.util.shape.Sphere; 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); source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO);
}); });
particlEffect.ifAbsent(getUuid(), source, spawner -> { particlEffect.update(getUuid(), source, spawner -> {
spawner.addParticle(new SphereParticleEffect(getType().getColor(), 0.3F, radius), origin, Vec3d.ZERO); spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, getType().getColor(), 0.3F, radius), origin, Vec3d.ZERO);
}).ifPresent(p -> { }).ifPresent(p -> {
p.setAttribute(0, radius); p.setAttribute(0, radius);
p.setAttribute(1, getType().getColor()); p.setAttribute(1, getType().getColor());

View file

@ -29,14 +29,19 @@ public class TargetSelecter {
Entity owner = source.getMaster(); 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) return source.findAllEntitiesInRange(radius)
.filter(entity -> !entity.isRemoved()) .filter(entity -> !entity.isRemoved())
.filter(entity -> { .filter(entity -> {
return !FriendshipBraceletItem.isComrade(source, entity) boolean hasShield = SpellPredicate.IS_SHIELD_LIKE.isOn(entity);
&& !SpellPredicate.IS_SHIELD_LIKE.isOn(entity) boolean isOwnerOrFriend = Pony.equal(entity, owner) || owner.isConnectedThroughVehicle(entity) || FriendshipBraceletItem.isComrade(source, entity);
&& !(ownerIsValid && (Pony.equal(entity, owner) || owner.isConnectedThroughVehicle(entity)));
if (!ownerIsValid && isOwnerOrFriend) {
return true;
}
return !hasShield && (!ownerIsValid || !isOwnerOrFriend);
}) })
.filter(e -> filter.test(source, e)) .filter(e -> filter.test(source, e))
.map(i -> { .map(i -> {

View file

@ -19,7 +19,7 @@ public class DiskParticle extends SphereParticle {
@Override @Override
protected void renderModel(MatrixStack matrices, VertexConsumer buffer, float scale, float tickDelta, int light) { protected void renderModel(MatrixStack matrices, VertexConsumer buffer, float scale, float tickDelta, int light) {
matrices.multiply(rotation); 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);
} }
} }

View file

@ -85,6 +85,9 @@ public class SphereParticle extends Particle implements Attachment {
colorGreen = Color.g(tint); colorGreen = Color.g(tint);
colorBlue = Color.b(tint); colorBlue = Color.b(tint);
} }
if (key == 2) {
colorAlpha = (float)value;
}
} }
@Override @Override

View file

@ -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<DiskParticleEffect> FACTORY = ParticleFactoryHelper.of(DiskParticleEffect::new, DiskParticleEffect::new);
protected DiskParticleEffect(ParticleType<DiskParticleEffect> type, StringReader reader) throws CommandSyntaxException {
super(type, reader);
}
protected DiskParticleEffect(ParticleType<DiskParticleEffect> 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;
}
}

View file

@ -1,6 +1,7 @@
package com.minelittlepony.unicopia.particle; package com.minelittlepony.unicopia.particle;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -13,53 +14,71 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.Particle;
import net.minecraft.particle.ParticleEffect; import net.minecraft.world.World;
import net.minecraft.util.math.Vec3d;
/** /**
* A connection class for updating and persisting an attached particle effect. * A connection class for updating and persisting an attached particle effect.
*/ */
public class ParticleHandle { public class ParticleHandle {
private Optional<WeakReference<Attachment>> particleEffect = Optional.empty(); private final Map<String, Attachment> loadedEffects = new WeakHashMap<>();
public Optional<Attachment> ifAbsent(UUID id, ParticleSource source, Consumer<ParticleSpawner> constructor) { public Optional<Attachment> update(UUID id, ParticleSource source, Consumer<ParticleSpawner> constructor) {
return get().or(() -> { return update(id, "prime", source, constructor);
if (source.getWorld().isClient) {
constructor.accept((effect, pos, vel) -> new ClientHandle().addParticle(id, source, effect, pos, vel));
} }
return get();
public Optional<Attachment> update(UUID id, String partName, ParticleSource source, Consumer<ParticleSpawner> constructor) {
return get(partName).or(() -> {
if (source.getWorld().isClient) {
new ClientHandle().addParticle(id, partName, source, constructor);
}
return get(partName);
}); });
} }
public void destroy() { public void destroy() {
get().ifPresent(Attachment::detach); loadedEffects.values().forEach(Attachment::detach);
loadedEffects.clear();
} }
private Optional<Attachment> get() { private Optional<Attachment> get(String partName) {
return particleEffect.map(WeakReference::get).filter(Attachment::isStillAlive); return Optional.ofNullable(loadedEffects.get(partName)).filter(Attachment::isStillAlive);
} }
private final class ClientHandle { private final class ClientHandle {
private static final Map<UUID, Particle> SPAWNED_PARTICLES = new WeakHashMap<>(); private static final Map<UUID, Map<String, Entry>> SPAWNED_PARTICLES = new HashMap<>();
private Particle pp;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
private void addParticle(UUID id, ParticleSource source, ParticleEffect effect, Vec3d pos, Vec3d vel) { private void addParticle(UUID id, String partName, ParticleSource source, Consumer<ParticleSpawner> constructor) {
Particle p = SPAWNED_PARTICLES.computeIfAbsent(id, i -> { SPAWNED_PARTICLES.values().removeIf(set -> {
Particle pp = MinecraftClient.getInstance().particleManager.addParticle(effect, pos.x, pos.y, pos.z, vel.x, vel.y, vel.z); set.values().removeIf(particle -> particle.get() == null);
return set.isEmpty();
});
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<?>) { if (pp instanceof Attachment && source instanceof Caster<?>) {
((Attachment) pp).attach(new Link(id, (Caster<?>)source)); ((Attachment) pp).attach(new Link(id, (Caster<?>)source));
} }
return pp; });
return new Entry(new WeakReference<>(MinecraftClient.getInstance().world), new WeakReference<>(pp));
}); });
if (p instanceof Attachment) { if (p.get() instanceof Attachment) {
particleEffect = Optional.of(new WeakReference<>((Attachment)p)); loadedEffects.put(partName, (Attachment)p.get());
}
}
record Entry (WeakReference<World> world, WeakReference<Particle> particle) {
public Particle get() {
return world.get() == null || world.get() != MinecraftClient.getInstance().world ? null : particle.get();
} }
} }
} }
public interface Attachment { public interface Attachment {
boolean isStillAlive(); boolean isStillAlive();
void attach(Link link); void attach(Link link);

View file

@ -43,5 +43,4 @@ public interface ParticleSource extends ParticleSpawner {
default void addParticle(ParticleEffect effect, Vec3d position, Vec3d velocity) { default void addParticle(ParticleEffect effect, Vec3d position, Vec3d velocity) {
getWorld().addParticle(effect, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z); getWorld().addParticle(effect, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z);
} }
} }

View file

@ -26,27 +26,30 @@ public class SphereParticleEffect implements ParticleEffect {
private Vec3d offset = Vec3d.ZERO; private Vec3d offset = Vec3d.ZERO;
private final ParticleType<? extends SphereParticleEffect> type;
protected SphereParticleEffect(ParticleType<? extends SphereParticleEffect> type, StringReader reader) throws CommandSyntaxException { protected SphereParticleEffect(ParticleType<? extends SphereParticleEffect> 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<? extends SphereParticleEffect> type, PacketByteBuf buf) { protected SphereParticleEffect(ParticleType<? extends SphereParticleEffect> 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) { public SphereParticleEffect(ParticleType<? extends SphereParticleEffect> type, int tint, float alpha, float rad) {
this(tint, alpha, rad, DEFAULT_OFFSET); this(type, tint, alpha, rad, DEFAULT_OFFSET);
} }
public SphereParticleEffect(Vec3f color, float alpha, float rad) { public SphereParticleEffect(ParticleType<? extends SphereParticleEffect> type, Vec3f color, float alpha, float rad) {
this(color, alpha, rad, DEFAULT_OFFSET); this(type, color, alpha, rad, DEFAULT_OFFSET);
} }
public SphereParticleEffect(int tint, float alpha, float rad, Vec3d offset) { public SphereParticleEffect(ParticleType<? extends SphereParticleEffect> type, int tint, float alpha, float rad, Vec3d offset) {
this(new Vec3f(Color.r(tint), Color.g(tint), Color.b(tint)), alpha, rad, 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<? extends SphereParticleEffect> type, Vec3f color, float alpha, float rad, Vec3d offset) {
this.type = type;
this.color = color; this.color = color;
this.offset = offset; this.offset = offset;
this.alpha = alpha; this.alpha = alpha;
@ -71,7 +74,7 @@ public class SphereParticleEffect implements ParticleEffect {
@Override @Override
public ParticleType<?> getType() { public ParticleType<?> getType() {
return UParticles.SPHERE; return type;
} }
@Override @Override

View file

@ -19,7 +19,7 @@ public interface UParticles {
DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple()); DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple());
ParticleType<SphereParticleEffect> SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY)); ParticleType<SphereParticleEffect> SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY));
ParticleType<DiskParticleEffect> DISK = register("disk", FabricParticleTypes.complex(true, DiskParticleEffect.FACTORY)); ParticleType<SphereParticleEffect> DISK = register("disk", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY));
ParticleType<FollowingParticleEffect> HEALTH_DRAIN = register("health_drain", FabricParticleTypes.complex(true, FollowingParticleEffect.FACTORY)); ParticleType<FollowingParticleEffect> HEALTH_DRAIN = register("health_drain", FabricParticleTypes.complex(true, FollowingParticleEffect.FACTORY));

View file

@ -159,9 +159,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Li
setNoGravity(false); setNoGravity(false);
} }
if (!getSpellSlot().get(true).filter(spell -> spell.tick(this, Situation.PROJECTILE)).isPresent()) { getSpellSlot().get(true).filter(spell -> spell.tick(this, Situation.PROJECTILE));
discard();
}
if (getHydrophobic()) { if (getHydrophobic()) {
if (world.getBlockState(getBlockPos()).getMaterial().isLiquid()) { if (world.getBlockState(getBlockPos()).getMaterial().isLiquid()) {

View file

@ -430,6 +430,8 @@
"death.attack.paradox": "%1$s imploded", "death.attack.paradox": "%1$s imploded",
"death.attack.food_poisoning": "%1$s died of food poisoning", "death.attack.food_poisoning": "%1$s died of food poisoning",
"death.attack.food_poisoning.attacker": "%2$s poisoned %1$s to death", "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.flap_wings": "Wing Flaps",
"unicopia.subtitle.wind_rush": "Wind Gust", "unicopia.subtitle.wind_rush": "Wind Gust",