Skip to content

Commit

Permalink
Implement PARTICLE_EFFECT for area effect clouds
Browse files Browse the repository at this point in the history
  • Loading branch information
aromaa committed Jan 8, 2024
1 parent 7c66cde commit 2d2b7cc
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.spongepowered.api.util.Color;
import org.spongepowered.common.accessor.world.entity.AreaEffectCloudAccessor;
import org.spongepowered.common.data.provider.DataProviderRegistrator;
import org.spongepowered.common.effect.particle.SpongeParticleHelper;
import org.spongepowered.common.util.MissingImplementationException;
import org.spongepowered.common.util.PotionEffectUtil;
import org.spongepowered.common.util.SpongeTicks;
Expand Down Expand Up @@ -56,12 +57,8 @@ public static void register(final DataProviderRegistrator registrator) {
return true;
})
.create(Keys.PARTICLE_EFFECT)
.get(h -> {
throw new MissingImplementationException("AreaEffectCloudData", "PARTICLE_EFFECT::getter");
})
.set((h, v) -> {
throw new MissingImplementationException("AreaEffectCloudData", "PARTICLE_EFFECT::setter");
})
.get(h -> SpongeParticleHelper.spongeParticleOptions(h.getParticle()))
.set((h, v) -> h.setParticle(SpongeParticleHelper.vanillaParticleOptions(v)))
.create(Keys.RADIUS)
.get(h -> (double) h.getRadius())
.set((h, v) -> h.setRadius(v.floatValue()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@
*/
package org.spongepowered.common.effect.particle;

import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.network.protocol.Packet;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.math.vector.Vector3d;

import java.util.List;

interface CachedParticlePacket {

void process(Vector3d position, List<Packet<?>> output);

@Nullable ParticleOptions particleOptions();
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.gameevent.BlockPositionSource;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.effect.particle.ParticleEffect;
import org.spongepowered.api.effect.particle.ParticleOption;
import org.spongepowered.api.effect.particle.ParticleOptions;
import org.spongepowered.api.effect.particle.ParticleType;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
Expand All @@ -53,7 +55,9 @@
import org.spongepowered.math.vector.Vector3f;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

Expand All @@ -75,22 +79,23 @@ public static void sendPackets(final ParticleEffect particleEffect, final Vector
}

public static List<Packet<?>> toPackets(final ParticleEffect effect, final Vector3d position) {
SpongeParticleEffect spongeEffect = (SpongeParticleEffect) effect;

CachedParticlePacket cachedPacket = spongeEffect.cachedPacket;
if (cachedPacket == null) {
// Also save the generated packet cache for repeated uses.
cachedPacket = spongeEffect.cachedPacket = SpongeParticleHelper.getCachedPacket(spongeEffect);
}

final List<Packet<?>> packets = new ArrayList<>();
cachedPacket.process(position, packets);
SpongeParticleHelper.getCachedPacket((SpongeParticleEffect) effect).process(position, packets);
return packets;
}

public static net.minecraft.core.particles.@Nullable ParticleOptions vanillaParticleOptions(final ParticleEffect effect) {
return SpongeParticleHelper.getCachedPacket((SpongeParticleEffect) effect).particleOptions();
}

private static CachedParticlePacket getCachedPacket(final SpongeParticleEffect effect) {
final ParticleType type = effect.type();
return SpongeParticleHelper.getNamedPacket(effect, (net.minecraft.core.particles.ParticleType<?>) type);
if (effect.cachedPacket == null) {
final ParticleType type = effect.type();

effect.cachedPacket = SpongeParticleHelper.getNamedPacket(effect, (net.minecraft.core.particles.ParticleType<?>) type);
}

return effect.cachedPacket;
}

@SuppressWarnings({"unchecked", "ConstantConditions"})
Expand Down Expand Up @@ -215,13 +220,63 @@ public static int getBlockStateId(final ParticleEffect effect, final Optional<Bl
.orElse(0);
}

public static ParticleEffect spongeParticleOptions(final net.minecraft.core.particles.ParticleOptions effect) {
final net.minecraft.core.particles.ParticleType<?> type = effect.getType();
if (type instanceof SimpleParticleType) {
return new SpongeParticleEffect((ParticleType) type, Collections.emptyMap());
}

if (type.getDeserializer() == BlockParticleOption.DESERIALIZER) {
final BlockParticleOption particleData = (BlockParticleOption) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(ParticleOptions.BLOCK_STATE.get(), particleData.getState()));
} else if (type.getDeserializer() == DustColorTransitionOptions.DESERIALIZER) {
final DustColorTransitionOptions particleData = (DustColorTransitionOptions) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(
ParticleOptions.COLOR.get(), Color.of(
Vector3f.from(particleData.getFromColor().x, particleData.getFromColor().y, particleData.getFromColor().z).mul(255)),
ParticleOptions.TO_COLOR.get(), Color.of(
Vector3f.from(particleData.getToColor().x, particleData.getToColor().y, particleData.getToColor().z).mul(255)),
ParticleOptions.SCALE.get(), particleData.getScale()
));
} else if (type.getDeserializer() == DustParticleOptions.DESERIALIZER) {
// This particle type supports a color option.
final DustParticleOptions particleData = (DustParticleOptions) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(
ParticleOptions.COLOR.get(), Color.of(
Vector3f.from(particleData.getColor().x, particleData.getColor().y, particleData.getColor().z).mul(255)),
ParticleOptions.SCALE.get(), particleData.getScale()
));
} else if (type.getDeserializer() == ItemParticleOption.DESERIALIZER) {
// This particle type supports an item option.
final ItemParticleOption particleData = (ItemParticleOption) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(ParticleOptions.BLOCK_STATE.get(), particleData.getItem().copy()));
} else if (type.getDeserializer() == SculkChargeParticleOptions.DESERIALIZER) {
final SculkChargeParticleOptions particleData = (SculkChargeParticleOptions) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(ParticleOptions.ROLL.get(), particleData.roll()));
} else if (type.getDeserializer() == ShriekParticleOption.DESERIALIZER) {
final ShriekParticleOption particleData = (ShriekParticleOption) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(ParticleOptions.DELAY.get(), particleData.getDelay()));
} else if (type.getDeserializer() == VibrationParticleOption.DESERIALIZER) {
// TODO add position source
final VibrationParticleOption particleData = (VibrationParticleOption) effect;
return new SpongeParticleEffect((ParticleType) type, Map.of(ParticleOptions.TRAVEL_TIME.get(), Ticks.of(particleData.getArrivalInTicks())));
}

return new SpongeParticleEffect((ParticleType) type, Collections.emptyMap());
}

private static final class EmptyCachedPacket implements CachedParticlePacket {

public static final EmptyCachedPacket INSTANCE = new EmptyCachedPacket();

@Override
public void process(final Vector3d position, final List<Packet<?>> output) {
}

@Override
public net.minecraft.core.particles.@Nullable ParticleOptions particleOptions() {
return null;
}
}

private static final class NamedCachedPacket implements CachedParticlePacket {
Expand Down Expand Up @@ -280,5 +335,10 @@ public void process(final Vector3d position, final List<Packet<?>> output) {
}
}
}

@Override
public net.minecraft.core.particles.@Nullable ParticleOptions particleOptions() {
return this.particleData;
}
}
}

0 comments on commit 2d2b7cc

Please sign in to comment.