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 58f5b1de..bda10118 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 @@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.SphereParticleEffect; import com.minelittlepony.unicopia.particle.UParticles; @@ -95,7 +96,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega } if (!source.isClient() && source.asWorld().random.nextInt(300) == 0) { - ParticleUtils.spawnParticle(source.asWorld(), UParticles.LIGHTNING_BOLT, getOrigin(source), Vec3d.ZERO); + ParticleUtils.spawnParticle(source.asWorld(), LightningBoltParticleEffect.DEFAULT, getOrigin(source), Vec3d.ZERO); } return super.tick(source, situation); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DispellEvilSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DispellEvilSpell.java index 5fe7fba1..4a488942 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DispellEvilSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DispellEvilSpell.java @@ -4,7 +4,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.*; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; -import com.minelittlepony.unicopia.particle.UParticles; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.ProjectileDelegate; @@ -39,7 +39,7 @@ public class DispellEvilSpell extends AbstractSpell implements ProjectileDelegat l.takeKnockback(1, d, e); } - source.addParticle(UParticles.LIGHTNING_BOLT, entity.getPos(), Vec3d.ZERO); + source.addParticle(LightningBoltParticleEffect.DEFAULT, entity.getPos(), Vec3d.ZERO); }); source.subtractEnergyCost(1000); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java index 1b00e89b..680a0ff1 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java @@ -65,7 +65,7 @@ public class PortalSpell extends AbstractSpell implements PlaceableSpell.Placeme ParticleEffect effect = teleportationTarget.getTarget() .map(target -> { getType(); - return new FollowingParticleEffect(UParticles.HEALTH_DRAIN, target.pos(), 0.2F).withChild(ParticleTypes.ELECTRIC_SPARK); + return (ParticleEffect)new FollowingParticleEffect(UParticles.HEALTH_DRAIN, target.pos(), 0.2F).withChild(ParticleTypes.ELECTRIC_SPARK); }) .orElse(ParticleTypes.ELECTRIC_SPARK); diff --git a/src/main/java/com/minelittlepony/unicopia/block/ZapBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ZapBlock.java index 2b955fca..c38f0b7a 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/ZapBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/ZapBlock.java @@ -1,9 +1,8 @@ package com.minelittlepony.unicopia.block; import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; -import com.minelittlepony.unicopia.particle.UParticles; - import net.minecraft.block.*; import net.minecraft.entity.EntityType; import net.minecraft.entity.LightningEntity; @@ -79,6 +78,6 @@ public class ZapBlock extends Block { }); } world.emitGameEvent(GameEvent.LIGHTNING_STRIKE, pos, GameEvent.Emitter.of(state)); - ParticleUtils.spawnParticle(world, UParticles.LIGHTNING_BOLT, Vec3d.ofCenter(pos), Vec3d.ZERO); + ParticleUtils.spawnParticle(world, LightningBoltParticleEffect.DEFAULT, Vec3d.ofCenter(pos), Vec3d.ZERO); } } 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 5ea1cf39..6f7610d7 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/DiskParticle.java @@ -15,12 +15,10 @@ public class DiskParticle extends SphereParticle { private final Quaternionf rotation = new Quaternionf(0, 0, 0, 1); public DiskParticle(SphereParticleEffect effect, ClientWorld w, double x, double y, double z, double rX, double rY, double rZ) { - super(effect, w, x, y, z, 0, 0, 0); + super(effect.withOffset(new Vec3d(0, 0.25, 0)), w, x, y, z, 0, 0, 0); - rotation.mul(RotationAxis.POSITIVE_Y.rotationDegrees((float)effect.getOffset().y)); - rotation.mul(RotationAxis.POSITIVE_X.rotationDegrees(180 - (float)effect.getOffset().x)); - - effect.setOffset(new Vec3d(0, 0.25, 0)); + rotation.mul(RotationAxis.POSITIVE_Y.rotationDegrees((float)effect.offset().y)); + rotation.mul(RotationAxis.POSITIVE_X.rotationDegrees(180 - (float)effect.offset().x)); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/FollowingParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/FollowingParticle.java index 4d588bd6..8c6aff15 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/FollowingParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/FollowingParticle.java @@ -24,7 +24,7 @@ public class FollowingParticle extends NoRenderParticle { scale(0.125F); this.parameters = parameters; this.collidesWithWorld = false; - this.particle = parameters.getChildEffect().map(child -> MinecraftClient.getInstance().particleManager.addParticle(child, x, y, z, velocityX, velocityY, velocityZ)).orElse(null); + this.particle = parameters.childEffect().map(child -> MinecraftClient.getInstance().particleManager.addParticle(child, x, y, z, velocityX, velocityY, velocityZ)).orElse(null); } @Override @@ -50,7 +50,7 @@ public class FollowingParticle extends NoRenderParticle { super.tick(); - Vec3d target = parameters.getTarget(world); + Vec3d target = parameters.target().getPosition(world); Vec3d pos = new Vec3d(x, y, z); if (scale * 1.5F < 0.5F) { @@ -62,12 +62,12 @@ public class FollowingParticle extends NoRenderParticle { age = 0; } - Vec3d motion = target.subtract(pos).normalize().multiply(Math.min(distance, parameters.getSpeed())); + Vec3d motion = target.subtract(pos).normalize().multiply(Math.min(distance, parameters.followSpeed())); move(motion.x, motion.y, motion.z); } @Override public String toString() { - return super.toString() + ", Speed " + parameters.getSpeed() + ", Target (" + parameters.getTargetDescriptor() + ") Sub-Particle (" + particle + ")"; + return super.toString() + ", Speed " + parameters.followSpeed() + ", Target (" + parameters.target() + ") Sub-Particle (" + particle + ")"; } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/HealthDrainParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/HealthDrainParticle.java index 8dbff917..b12a2b49 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/HealthDrainParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/HealthDrainParticle.java @@ -14,7 +14,7 @@ public class HealthDrainParticle extends SpriteBillboardParticle { private final FollowingParticleEffect effect; public static Particle create(FollowingParticleEffect effect, SpriteProvider provider, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { - if (effect.getChildEffect().isPresent()) { + if (effect.childEffect().isPresent()) { return new FollowingParticle(effect, provider, world, x, y, z, velocityX, velocityY, velocityZ); } return new HealthDrainParticle(effect, provider, world, x, y, z, velocityX, velocityY, velocityZ); @@ -38,7 +38,7 @@ public class HealthDrainParticle extends SpriteBillboardParticle { public void tick() { super.tick(); - Vec3d target = effect.getTarget(world); + Vec3d target = effect.target().getPosition(world); Vec3d pos = new Vec3d(x, y, z); if (this.scale * 1.5F < 0.5F) { @@ -50,7 +50,7 @@ public class HealthDrainParticle extends SpriteBillboardParticle { age = 0; } - Vec3d motion = target.subtract(pos).normalize().multiply(Math.min(distance, effect.getSpeed())); + Vec3d motion = target.subtract(pos).normalize().multiply(Math.min(distance, effect.followSpeed())); move(motion.x, motion.y, motion.z); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/LightningBoltParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/LightningBoltParticle.java index fb62c048..4fd11f79 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/LightningBoltParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/LightningBoltParticle.java @@ -6,6 +6,7 @@ import java.util.List; import org.joml.Vector3f; import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; @@ -14,7 +15,6 @@ import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.world.ClientWorld; -import net.minecraft.particle.DefaultParticleType; import net.minecraft.sound.SoundCategory; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -23,8 +23,11 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle { private final List> branches = new ArrayList<>(); - public LightningBoltParticle(DefaultParticleType type, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { + private final LightningBoltParticleEffect effect; + + public LightningBoltParticle(LightningBoltParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { super(world, x, y, z, velocityX, velocityY, velocityZ); + this.effect = effect; } @Override @@ -34,7 +37,7 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle { return; } - if (age % 5 == 0) { + if (age % effect.changeFrequency() == 0) { branches.clear(); } if (branches.isEmpty()) { @@ -44,7 +47,9 @@ public class LightningBoltParticle extends AbstractGeometryBasedParticle { branches.add(generateBranch()); } - world.playSound(x, y, z, USounds.Vanilla.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, 10000, 8, true); + if (!effect.silent()) { + world.playSound(x, y, z, USounds.Vanilla.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, 10000, 8, true); + } } world.setLightningTicksLeft(2); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java index d73d5edd..f3f04b23 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/OrientedBillboardParticle.java @@ -20,11 +20,11 @@ public abstract class OrientedBillboardParticle extends AbstractBillboardParticl public OrientedBillboardParticle(OrientedBillboardParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { super(world, x, y, z, velocityX, velocityY, velocityZ); - fixed = effect.isAngleFixed(); + fixed = effect.fixed(); if (fixed) { // Was hamiltonianProduct (CHECK THIS!!) - rotation.mul(RotationAxis.POSITIVE_Y.rotationDegrees(effect.getPitch())); - rotation.mul(RotationAxis.POSITIVE_X.rotationDegrees(180 - effect.getYaw())); + rotation.mul(RotationAxis.POSITIVE_Y.rotationDegrees(effect.pitch())); + rotation.mul(RotationAxis.POSITIVE_X.rotationDegrees(180 - effect.yaw())); } } 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 7b0844e1..911b10bd 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/SphereParticle.java @@ -51,11 +51,11 @@ public class SphereParticle extends Particle implements Attachment { public SphereParticle(SphereParticleEffect parameters, ClientWorld w, double x, double y, double z) { super(w, x, y, z); this.parameters = parameters; - this.radius = parameters.getRadius(); - this.red = parameters.getColor().x / 255F; - this.green = parameters.getColor().y / 255F; - this.blue = parameters.getColor().z / 255F; - this.alpha = parameters.getAlpha(); + this.radius = parameters.radius(); + this.red = parameters.color().x / 255F; + this.green = parameters.color().y / 255F; + this.blue = parameters.color().z / 255F; + this.alpha = parameters.alpha(); setMaxAge(10); } @@ -109,7 +109,7 @@ public class SphereParticle extends Particle implements Attachment { if (link.isPresent()) { link.flatMap(Link::get).map(EntityConvertable::asEntity).ifPresentOrElse(e -> { if (!bound) { - Vec3d offset = parameters.getOffset(); + Vec3d offset = parameters.offset(); setPos(e.getX() + offset.getX(), e.getY() + offset.getY(), e.getZ() + offset.getZ()); prevPosX = e.lastRenderX + offset.getX(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/FairyEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/FairyEntity.java index 37714f05..a6bb8b0b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/FairyEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/FairyEntity.java @@ -10,10 +10,9 @@ import com.minelittlepony.unicopia.WeaklyOwned; import com.minelittlepony.unicopia.entity.DynamicLightSource; import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.entity.MagicImmune; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; -import com.minelittlepony.unicopia.particle.UParticles; - import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -212,7 +211,7 @@ public class FairyEntity extends PathAwareEntity implements DynamicLightSource, attacker.onStruckByLightning(serverWorld, lightning); } emitGameEvent(GameEvent.LIGHTNING_STRIKE); - ParticleUtils.spawnParticle(getWorld(), UParticles.LIGHTNING_BOLT, getPos(), Vec3d.ZERO); + ParticleUtils.spawnParticle(getWorld(), LightningBoltParticleEffect.DEFAULT, getPos(), Vec3d.ZERO); return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/item/JarItem.java b/src/main/java/com/minelittlepony/unicopia/item/JarItem.java index 809576a2..6943d0c5 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/JarItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/JarItem.java @@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.AwaitTickQueue; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.entity.IItemEntity; import com.minelittlepony.unicopia.entity.ItemImpl; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; @@ -128,7 +129,7 @@ public class JarItem extends ProjectileItem implements ItemImpl.GroundTickCallba } if (lightning) { - ParticleUtils.spawnParticle(projectile.getWorld(), UParticles.LIGHTNING_BOLT, projectile.getPos(), Vec3d.ZERO); + ParticleUtils.spawnParticle(projectile.getWorld(), LightningBoltParticleEffect.DEFAULT, projectile.getPos(), Vec3d.ZERO); } if (rain || thunder) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java index 438769db..e2e60e79 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java @@ -10,8 +10,8 @@ import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.group.MultiItem; import com.minelittlepony.unicopia.item.toxin.*; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; -import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.RegistryUtils; @@ -67,7 +67,7 @@ public class ZapAppleItem extends Item implements ChameleonItem, ToxicHolder, Mu } player.emitGameEvent(GameEvent.LIGHTNING_STRIKE); - ParticleUtils.spawnParticle(w, UParticles.LIGHTNING_BOLT, player.getPos(), Vec3d.ZERO); + ParticleUtils.spawnParticle(w, LightningBoltParticleEffect.DEFAULT, player.getPos(), Vec3d.ZERO); return stack; } diff --git a/src/main/java/com/minelittlepony/unicopia/particle/FollowingParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/FollowingParticleEffect.java index 3ad756c2..4455f7f7 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/FollowingParticleEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/FollowingParticleEffect.java @@ -12,87 +12,44 @@ import net.minecraft.entity.Entity; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.math.Vec3d; import net.minecraft.registry.Registries; -import net.minecraft.world.World; -public class FollowingParticleEffect implements ParticleEffect { +public record FollowingParticleEffect ( + ParticleType type, + WeakTarget target, + float followSpeed, + Optional childEffect + ) implements ParticleEffect { @SuppressWarnings("deprecation") public static final Factory FACTORY = ParticleFactoryHelper.of(FollowingParticleEffect::new, FollowingParticleEffect::new); - private final ParticleType type; - - private Vec3d fixedTarget; - - private int movingTarget; - - private final float followSpeed; - - private Optional childEffect = Optional.empty(); - protected FollowingParticleEffect(ParticleType type, StringReader reader) throws CommandSyntaxException { - this(type, -1, ParticleFactoryHelper.readVector(reader), ParticleFactoryHelper.readFloat(reader)); - - if (reader.canRead()) { - reader.expect(' '); - childEffect = ParticleFactoryHelper.read(reader); - } + this(type, + new WeakTarget(reader), + ParticleFactoryHelper.readFloat(reader), + ParticleFactoryHelper.readOptional(reader, r -> { + r.expect(' '); + return ParticleFactoryHelper.read(r); + })); } protected FollowingParticleEffect(ParticleType type, PacketByteBuf buf) { - this(type, buf.readInt(), new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()), buf.readFloat()); - - if (buf.readBoolean()) { - childEffect = ParticleFactoryHelper.read(Registries.PARTICLE_TYPE.get(buf.readInt()), buf); - } + this(type, + new WeakTarget(buf), + buf.readFloat(), + buf.readOptional(b -> ParticleFactoryHelper.readEffect(b)) + ); } public FollowingParticleEffect(ParticleType type, Vec3d target, float followSpeed) { - this.type = type; - this.fixedTarget = target; - this.movingTarget = -1; - this.followSpeed = followSpeed; + this(type, new WeakTarget(target, (Entity)null), followSpeed, Optional.empty()); } public FollowingParticleEffect(ParticleType type, Entity target, float followSpeed) { - this(type, target.getId(), target.getCameraPosVec(1), followSpeed); + this(type, new WeakTarget(target.getCameraPosVec(1), target), followSpeed, Optional.empty()); } - private FollowingParticleEffect(ParticleType type, int movingTarget, Vec3d fixedTarget, float followSpeed) { - this.type = type; - this.movingTarget = movingTarget; - this.fixedTarget = fixedTarget; - this.followSpeed = followSpeed; - } - - public ParticleEffect withChild(ParticleEffect child) { - childEffect = Optional.of(child); - return this; - } - - public Optional getChildEffect() { - return childEffect; - } - - public String getTargetDescriptor() { - if (movingTarget > -1) { - return "Moving(" + movingTarget + ")"; - } - return fixedTarget.toString(); - } - - public Vec3d getTarget(World world) { - if (movingTarget > -1) { - Entity e = world.getEntityById(movingTarget); - if (e != null) { - fixedTarget = e.getCameraPosVec(1); - } else { - movingTarget = -1; - } - } - return fixedTarget; - } - - public float getSpeed() { - return followSpeed; + public FollowingParticleEffect withChild(ParticleEffect child) { + return new FollowingParticleEffect(type, target, followSpeed, Optional.of(child)); } @Override @@ -102,29 +59,30 @@ public class FollowingParticleEffect implements ParticleEffect { @Override public void write(PacketByteBuf buf) { - buf.writeInt(movingTarget); - buf.writeDouble(fixedTarget.x); - buf.writeDouble(fixedTarget.y); - buf.writeDouble(fixedTarget.z); + target.write(buf); buf.writeFloat(followSpeed); - getChildEffect().ifPresentOrElse(child -> { - buf.writeBoolean(true); - buf.writeInt(Registries.PARTICLE_TYPE.getRawId(child.getType())); + buf.writeOptional(childEffect(), (b, child) -> { + b.writeBoolean(true); + b.writeInt(Registries.PARTICLE_TYPE.getRawId(child.getType())); child.write(buf); - }, () -> buf.writeBoolean(false)); + }); } @Override public String asString() { - return getChildEffect().map(child -> { + return childEffect().map(child -> { return String.format(Locale.ROOT, "%s %.2f %.2f %.2f %.2f %s", Registries.PARTICLE_TYPE.getId(getType()), - fixedTarget.x, fixedTarget.y, fixedTarget.z, + target.fixedPosition.x, + target.fixedPosition.y, + target.fixedPosition.z, followSpeed, child.asString()); }).orElseGet(() -> { return String.format(Locale.ROOT, "%s %.2f %.2f %.2f %.2f", Registries.PARTICLE_TYPE.getId(getType()), - fixedTarget.x, fixedTarget.y, fixedTarget.z, + target.fixedPosition.x, + target.fixedPosition.y, + target.fixedPosition.z, followSpeed); }); diff --git a/src/main/java/com/minelittlepony/unicopia/particle/LightningBoltParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/LightningBoltParticleEffect.java new file mode 100644 index 00000000..85e54009 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/particle/LightningBoltParticleEffect.java @@ -0,0 +1,44 @@ +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.ParticleEffect; +import net.minecraft.particle.ParticleType; + +public record LightningBoltParticleEffect ( + boolean silent, + int changeFrequency, + int maxBranchLength + ) implements ParticleEffect { + public static final LightningBoltParticleEffect DEFAULT = new LightningBoltParticleEffect(false, 10, 6); + @SuppressWarnings("deprecation") + public static final ParticleEffect.Factory FACTORY = ParticleFactoryHelper.of(LightningBoltParticleEffect::new, LightningBoltParticleEffect::new); + + protected LightningBoltParticleEffect(ParticleType particleType, StringReader reader) throws CommandSyntaxException { + this(ParticleFactoryHelper.readBoolean(reader), ParticleFactoryHelper.readInt(reader), ParticleFactoryHelper.readInt(reader)); + } + + protected LightningBoltParticleEffect(ParticleType particleType, PacketByteBuf buf) { + this(buf.readBoolean(), buf.readInt(), buf.readInt()); + } + + @Override + public ParticleType getType() { + return UParticles.LIGHTNING_BOLT; + } + + @Override + public void write(PacketByteBuf buffer) { + buffer.writeBoolean(silent); + buffer.writeInt(changeFrequency); + buffer.writeInt(maxBranchLength); + } + + @Override + public String asString() { + return String.format("%s %s %s", silent, changeFrequency, maxBranchLength); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/particle/MagicParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/MagicParticleEffect.java index a8bc1d90..3b5671a9 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/MagicParticleEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/MagicParticleEffect.java @@ -15,14 +15,14 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.util.math.random.Random; import net.minecraft.registry.Registries; -public class MagicParticleEffect implements ParticleEffect { +public record MagicParticleEffect ( + boolean tinted, + Vector3f color + ) implements ParticleEffect { public static final MagicParticleEffect UNICORN = new MagicParticleEffect(false, new Vector3f()); @SuppressWarnings("deprecation") public static final ParticleEffect.Factory FACTORY = ParticleFactoryHelper.of(MagicParticleEffect::new, MagicParticleEffect::new); - private final boolean tinted; - private final Vector3f color; - protected MagicParticleEffect(ParticleType particleType, StringReader reader) throws CommandSyntaxException { this(ParticleFactoryHelper.readBoolean(reader), AbstractDustParticleEffect.readColor(reader)); } @@ -39,17 +39,8 @@ public class MagicParticleEffect implements ParticleEffect { this(true, color); } - protected MagicParticleEffect(boolean tint, Vector3f color) { - tinted = tint; - this.color = color; - } - - public boolean hasTint() { - return tinted; - } - public Vector3f getColor(Random random) { - if (hasTint()) { + if (tinted()) { return color; } diff --git a/src/main/java/com/minelittlepony/unicopia/particle/OrientedBillboardParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/OrientedBillboardParticleEffect.java index 26384776..b57360d8 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/OrientedBillboardParticleEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/OrientedBillboardParticleEffect.java @@ -11,16 +11,15 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.util.math.Vec3d; import net.minecraft.registry.Registries; -public class OrientedBillboardParticleEffect implements ParticleEffect { +public record OrientedBillboardParticleEffect ( + ParticleType type, + boolean fixed, + float yaw, + float pitch + ) implements ParticleEffect { @SuppressWarnings("deprecation") public static final ParticleEffect.Factory FACTORY = ParticleFactoryHelper.of(OrientedBillboardParticleEffect::new, OrientedBillboardParticleEffect::new); - private final boolean fixed; - private final float yaw; - private final float pitch; - - private final ParticleType type; - protected OrientedBillboardParticleEffect(ParticleType type, StringReader reader) throws CommandSyntaxException { this(type, ParticleFactoryHelper.readBoolean(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readFloat(reader)); } @@ -37,25 +36,6 @@ public class OrientedBillboardParticleEffect implements ParticleEffect { this(type, true, yaw, pitch); } - private OrientedBillboardParticleEffect(ParticleType type, boolean fixed, float yaw, float pitch) { - this.fixed = fixed; - this.yaw = yaw; - this.pitch = pitch; - this.type = type; - } - - public boolean isAngleFixed() { - return fixed; - } - - public float getYaw() { - return yaw; - } - - public float getPitch() { - return pitch; - } - @Override public ParticleType getType() { return type; diff --git a/src/main/java/com/minelittlepony/unicopia/particle/ParticleFactoryHelper.java b/src/main/java/com/minelittlepony/unicopia/particle/ParticleFactoryHelper.java index f30883e8..7890f91f 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/ParticleFactoryHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/ParticleFactoryHelper.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.particle; import java.util.Optional; - import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -15,33 +14,58 @@ import net.minecraft.util.math.Vec3d; public interface ParticleFactoryHelper { @SuppressWarnings("unchecked") - static Optional read(StringReader reader) throws CommandSyntaxException { - return Optional.ofNullable((T)ParticleEffectArgumentType.readParameters(reader, Registries.PARTICLE_TYPE.getReadOnlyWrapper())); + static T read(StringReader reader) throws CommandSyntaxException { + return (T)ParticleEffectArgumentType.readParameters(reader, Registries.PARTICLE_TYPE.getReadOnlyWrapper()); } @SuppressWarnings("deprecation") - static Optional read(ParticleType type, PacketByteBuf buf) { - return Optional.ofNullable(type.getParametersFactory().read(type, buf)); + static ParticleEffect readEffect(PacketByteBuf buf) { + @SuppressWarnings("unchecked") + ParticleType type = (ParticleType)Registries.PARTICLE_TYPE.get(buf.readInt()); + return type.getParametersFactory().read(type, buf); } static Vec3d readVector(StringReader reader) throws CommandSyntaxException { return new Vec3d(readDouble(reader), readDouble(reader), readDouble(reader)); } + static Vec3d readVector(PacketByteBuf buffer) { + return new Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()); + } + + static void writeVector(PacketByteBuf buffer, Vec3d vector) { + buffer.writeDouble(vector.x); + buffer.writeDouble(vector.y); + buffer.writeDouble(vector.z); + } + static boolean readBoolean(StringReader reader) throws CommandSyntaxException { reader.expect(' '); return reader.readBoolean(); } + static Optional readOptional(StringReader reader, ReaderFunc readFunc) throws CommandSyntaxException { + if (reader.canRead()) { + return Optional.ofNullable(readFunc.read(reader)); + } + return Optional.empty(); + } + static double readDouble(StringReader reader) throws CommandSyntaxException { reader.expect(' '); return reader.readDouble(); } + static float readFloat(StringReader reader) throws CommandSyntaxException { reader.expect(' '); return reader.readFloat(); } + static int readInt(StringReader reader) throws CommandSyntaxException { + reader.expect(' '); + return reader.readInt(); + } + @SuppressWarnings("deprecation") static ParticleEffect.Factory of(CommandReader commandReader, PacketReader packetReader) { return new ParticleEffect.Factory<>() { @@ -56,6 +80,10 @@ public interface ParticleFactoryHelper { }; } + interface ReaderFunc { + T read(StringReader reader) throws CommandSyntaxException; + } + interface CommandReader { T read(ParticleType type, StringReader reader) throws CommandSyntaxException; } diff --git a/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java index 212e84cd..702610d4 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/SphereParticleEffect.java @@ -15,26 +15,24 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.util.math.Vec3d; import net.minecraft.registry.Registries; -public class SphereParticleEffect implements ParticleEffect { +public record SphereParticleEffect ( + ParticleType type, + Vector3f color, + float alpha, + float radius, + Vec3d offset + ) implements ParticleEffect { @SuppressWarnings("deprecation") public static final Factory FACTORY = ParticleFactoryHelper.of(SphereParticleEffect::new, SphereParticleEffect::new); private static final Vec3d DEFAULT_OFFSET = new Vec3d(0, 0.5, 0); - private final Vector3f color; - private final float alpha; - private final float radius; - - private Vec3d offset = Vec3d.ZERO; - - private final ParticleType type; - protected SphereParticleEffect(ParticleType type, StringReader reader) throws CommandSyntaxException { this(type, AbstractDustParticleEffect.readColor(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readFloat(reader), ParticleFactoryHelper.readVector(reader)); } protected SphereParticleEffect(ParticleType type, PacketByteBuf buf) { - this(type, AbstractDustParticleEffect.readColor(buf), buf.readFloat(), buf.readFloat()); + this(type, buf.readVector3f(), buf.readFloat(), buf.readFloat(), ParticleFactoryHelper.readVector(buf)); } public SphereParticleEffect(ParticleType type, int tint, float alpha, float rad) { @@ -49,32 +47,8 @@ public class SphereParticleEffect implements ParticleEffect { this(type, new Vector3f(Color.r(tint) * 255, Color.g(tint) * 255, Color.b(tint) * 255), alpha, rad, offset); } - public SphereParticleEffect(ParticleType type, Vector3f color, float alpha, float rad, Vec3d offset) { - this.type = type; - this.color = color; - this.offset = offset; - this.alpha = alpha; - this.radius = rad; - } - - public Vec3d getOffset() { - return offset; - } - - public void setOffset(Vec3d offset) { - this.offset = offset; - } - - public Vector3f getColor() { - return color; - } - - public float getAlpha() { - return alpha; - } - - public float getRadius() { - return radius; + public SphereParticleEffect withOffset(Vec3d offset) { + return new SphereParticleEffect(type, color, alpha, radius, offset); } @Override @@ -84,14 +58,10 @@ public class SphereParticleEffect implements ParticleEffect { @Override public void write(PacketByteBuf buf) { - buf.writeFloat(color.x); - buf.writeFloat(color.y); - buf.writeFloat(color.z); + buf.writeVector3f(color); buf.writeFloat(alpha); buf.writeFloat(radius); - buf.writeDouble(offset.getX()); - buf.writeDouble(offset.getY()); - buf.writeDouble(offset.getZ()); + ParticleFactoryHelper.writeVector(buf, offset); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java index 7a279906..8d5208f0 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java @@ -28,7 +28,7 @@ public interface UParticles { DefaultParticleType GROUND_POUND = register("ground_pound", FabricParticleTypes.simple()); DefaultParticleType CLOUDS_ESCAPING = register("clouds_escaping", FabricParticleTypes.simple(true)); - DefaultParticleType LIGHTNING_BOLT = register("lightning_bolt", FabricParticleTypes.simple(true)); + ParticleType LIGHTNING_BOLT = register("lightning_bolt", FabricParticleTypes.complex(true, LightningBoltParticleEffect.FACTORY)); DefaultParticleType SHOCKWAVE = register("shockwave", FabricParticleTypes.simple(true)); static > T register(String name, T type) { diff --git a/src/main/java/com/minelittlepony/unicopia/particle/WeakTarget.java b/src/main/java/com/minelittlepony/unicopia/particle/WeakTarget.java new file mode 100644 index 00000000..9dd5ace2 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/particle/WeakTarget.java @@ -0,0 +1,55 @@ +package com.minelittlepony.unicopia.particle; + +import org.jetbrains.annotations.Nullable; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import net.minecraft.entity.Entity; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public class WeakTarget { + Vec3d fixedPosition; + private int targetId; + + public WeakTarget(Vec3d fixedPosition, @Nullable Entity entity) { + this.fixedPosition = fixedPosition; + targetId = entity == null ? -1 : entity.getId(); + } + + public WeakTarget(PacketByteBuf buf) { + fixedPosition = ParticleFactoryHelper.readVector(buf); + targetId = buf.readInt(); + } + + public WeakTarget(StringReader reader) throws CommandSyntaxException { + this(ParticleFactoryHelper.readVector(reader), null); + } + + public Vec3d getPosition(World world) { + if (targetId > -1) { + Entity e = world.getEntityById(targetId); + if (e != null) { + fixedPosition = e.getCameraPosVec(1); + } else { + targetId = -1; + } + } + return fixedPosition; + } + + @Override + public String toString() { + if (targetId > -1) { + return "Moving(" + targetId + ")"; + } + return "Fixed(" + fixedPosition + ")"; + } + + public void write(PacketByteBuf buf) { + ParticleFactoryHelper.writeVector(buf, fixedPosition); + buf.writeInt(targetId); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/server/world/ZapAppleStageStore.java b/src/main/java/com/minelittlepony/unicopia/server/world/ZapAppleStageStore.java index c90bc2af..4111a432 100644 --- a/src/main/java/com/minelittlepony/unicopia/server/world/ZapAppleStageStore.java +++ b/src/main/java/com/minelittlepony/unicopia/server/world/ZapAppleStageStore.java @@ -7,8 +7,8 @@ import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.block.ZapAppleLeavesBlock; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; -import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.util.Tickable; import net.minecraft.block.BlockState; @@ -97,7 +97,7 @@ public class ZapAppleStageStore extends PersistentState implements Tickable { public void triggerLightningStrike(BlockPos pos) { world.emitGameEvent(GameEvent.LIGHTNING_STRIKE, pos, GameEvent.Emitter.of(world.getBlockState(pos))); - ParticleUtils.spawnParticle(world, UParticles.LIGHTNING_BOLT, Vec3d.ofCenter(pos), Vec3d.ZERO); + ParticleUtils.spawnParticle(world, LightningBoltParticleEffect.DEFAULT, Vec3d.ofCenter(pos), Vec3d.ZERO); if (nextLightningEvent <= 0) { StreamSupport.stream(BlockPos.iterateRandomly(world.random, 20, pos, 10).spliterator(), false)