package protocolsupport.protocol.typeremapper.particle; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.function.Function; import java.util.function.UnaryOperator; import protocolsupport.api.ProtocolVersion; import protocolsupport.protocol.typeremapper.block.LegacyBlockData; import protocolsupport.protocol.typeremapper.itemstack.ItemStackRemapper; import protocolsupport.protocol.typeremapper.utils.RemappingRegistry; import protocolsupport.protocol.typeremapper.utils.RemappingTable; import protocolsupport.protocol.typeremapper.utils.RemappingTable.ArrayBasedIdRemappingTable; import protocolsupport.protocol.types.particle.Particle; import protocolsupport.protocol.types.particle.types.ParticleAsh; import protocolsupport.protocol.types.particle.types.ParticleBarrier; import protocolsupport.protocol.types.particle.types.ParticleBlock; import protocolsupport.protocol.types.particle.types.ParticleBubble; import protocolsupport.protocol.types.particle.types.ParticleBubbleColumnUp; import protocolsupport.protocol.types.particle.types.ParticleBubblePop; import protocolsupport.protocol.types.particle.types.ParticleCampfireCozySmoke; import protocolsupport.protocol.types.particle.types.ParticleCampfireSignalSmoke; import protocolsupport.protocol.types.particle.types.ParticleCloud; import protocolsupport.protocol.types.particle.types.ParticleComposter; import protocolsupport.protocol.types.particle.types.ParticleCrimsonSpore; import protocolsupport.protocol.types.particle.types.ParticleCurrentDown; import protocolsupport.protocol.types.particle.types.ParticleDamageIndicator; import protocolsupport.protocol.types.particle.types.ParticleDolphin; import protocolsupport.protocol.types.particle.types.ParticleDragonBreath; import protocolsupport.protocol.types.particle.types.ParticleDrippingHoney; import protocolsupport.protocol.types.particle.types.ParticleDrippingLava; import protocolsupport.protocol.types.particle.types.ParticleDrippingObsidianTear; import protocolsupport.protocol.types.particle.types.ParticleDrippingWater; import protocolsupport.protocol.types.particle.types.ParticleDust; import protocolsupport.protocol.types.particle.types.ParticleElderGuardian; import protocolsupport.protocol.types.particle.types.ParticleEndRod; import protocolsupport.protocol.types.particle.types.ParticleFallingDust; import protocolsupport.protocol.types.particle.types.ParticleFallingHoney; import protocolsupport.protocol.types.particle.types.ParticleFallingLava; import protocolsupport.protocol.types.particle.types.ParticleFallingNectar; import protocolsupport.protocol.types.particle.types.ParticleFallingObsidianTear; import protocolsupport.protocol.types.particle.types.ParticleFallingWater; import protocolsupport.protocol.types.particle.types.ParticleFishing; import protocolsupport.protocol.types.particle.types.ParticleFlash; import protocolsupport.protocol.types.particle.types.ParticleHappyVillager; import protocolsupport.protocol.types.particle.types.ParticleItem; import protocolsupport.protocol.types.particle.types.ParticleLandingHoney; import protocolsupport.protocol.types.particle.types.ParticleLandingLava; import protocolsupport.protocol.types.particle.types.ParticleLandingObsidianTear; import protocolsupport.protocol.types.particle.types.ParticleNautilus; import protocolsupport.protocol.types.particle.types.ParticlePoof; import protocolsupport.protocol.types.particle.types.ParticlePortal; import protocolsupport.protocol.types.particle.types.ParticleRain; import protocolsupport.protocol.types.particle.types.ParticleReversePortal; import protocolsupport.protocol.types.particle.types.ParticleSneeze; import protocolsupport.protocol.types.particle.types.ParticleSpit; import protocolsupport.protocol.types.particle.types.ParticleSplash; import protocolsupport.protocol.types.particle.types.ParticleSquidInk; import protocolsupport.protocol.types.particle.types.ParticleSweepAttack; import protocolsupport.protocol.types.particle.types.ParticleTotemOfUndying; import protocolsupport.protocol.types.particle.types.ParticleWarpedSpore; import protocolsupport.protocol.types.particle.types.ParticleWhiteAsh; import protocolsupport.protocol.utils.ProtocolVersionsHelper; import protocolsupport.protocol.utils.i18n.I18NData; import protocolsupportbuildprocessor.Preload; @Preload public class ParticleRemapper { //TODO: single -> multiple particles public static final RemappingRegistry<ParticleRemappingTable> REGISTRY = new RemappingRegistry<ParticleRemappingTable>() { { Arrays.stream(ProtocolVersion.getAllSupported()) .forEach(version -> { ArrayBasedIdRemappingTable blockDataRemappingTable = LegacyBlockData.REGISTRY.getTable(version); registerRemap(ParticleBlock.class, original -> new ParticleBlock( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount(), blockDataRemappingTable.getRemap(original.getBlockData()) ), version); registerRemap(ParticleFallingDust.class, original -> new ParticleFallingDust( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount(), blockDataRemappingTable.getRemap(original.getBlockData()) )); registerRemap(ParticleItem.class, original -> new ParticleItem( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount(), ItemStackRemapper.remapToClient(version, I18NData.DEFAULT_LOCALE, original.getItemStack()) )); }); registerRemap( ParticleReversePortal.class, original -> new ParticlePortal( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_15_2 ); registerRemap( ParticleFallingLava.class, original -> new ParticleDrippingLava( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_13_2 ); registerRemap( ParticleLandingLava.class, original -> new ParticleDrippingLava( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_13_2 ); registerRemap( ParticleFallingWater.class, original -> new ParticleDrippingWater( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_13_2 ); registerRemap( ParticleComposter.class, original -> new ParticleHappyVillager( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_13_2 ); registerRemap( ParticleSneeze.class, original -> new ParticleCloud( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_13_2 ); //TODO: remap to colored dust instead registerRemap( ParticleDragonBreath.class, original -> new ParticlePoof( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_12_2 ); registerRemap( ParticleDust.class, original -> new ParticleDust( original.getRed(), original.getGreen(), original.getBlue(), 1F, 0, 0, 0, 0, 0 ), ProtocolVersionsHelper.DOWN_1_12_2 ); registerRemap( ParticleSquidInk.class, original -> new ParticleDust( 0, 0, 0, 1F, 0, 0, 0, 0, 0 ), ProtocolVersionsHelper.DOWN_1_12_2 ); registerRemap( ParticleBubblePop.class, original -> new ParticleBubble( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_12_2 ); registerRemap( ParticleCurrentDown.class, original -> new ParticleBubble( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_12_2 ); registerRemap( ParticleBubbleColumnUp.class, original -> new ParticleBubble( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_12_2 ); registerRemap( ParticleSpit.class, original -> new ParticleCloud( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_10 ); registerRemap( ParticleRain.class, original -> new ParticleSplash( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_7_10 ); registerRemap( ParticleFishing.class, original -> new ParticleSplash( original.getOffsetX(), original.getOffsetY(), original.getOffsetZ(), original.getData(), original.getCount() ), ProtocolVersionsHelper.DOWN_1_6_4 ); //TODO: think of possible remaps registerSkip(ParticleAsh.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleWhiteAsh.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleCrimsonSpore.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleWarpedSpore.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleDrippingObsidianTear.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleFallingObsidianTear.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleLandingObsidianTear.class, ProtocolVersionsHelper.DOWN_1_15_2); registerSkip(ParticleDrippingHoney.class, ProtocolVersionsHelper.DOWN_1_14_4); registerSkip(ParticleFallingHoney.class, ProtocolVersionsHelper.DOWN_1_14_4); registerSkip(ParticleLandingHoney.class, ProtocolVersionsHelper.DOWN_1_14_4); registerSkip(ParticleFallingNectar.class, ProtocolVersionsHelper.DOWN_1_14_4); registerSkip(ParticleFlash.class, ProtocolVersionsHelper.DOWN_1_13_2); registerSkip(ParticleCampfireCozySmoke.class, ProtocolVersionsHelper.DOWN_1_13_2); registerSkip(ParticleCampfireSignalSmoke.class, ProtocolVersionsHelper.DOWN_1_13_2); registerSkip(ParticleNautilus.class, ProtocolVersionsHelper.DOWN_1_12_2); registerSkip(ParticleDolphin.class, ProtocolVersionsHelper.DOWN_1_12_2); registerSkip(ParticleTotemOfUndying.class, ProtocolVersionsHelper.DOWN_1_10); registerSkip(ParticleFallingDust.class, ProtocolVersionsHelper.DOWN_1_9_4); //TODO: actually remap to colored dust, after building blockdata -> color table registerSkip(ParticleEndRod.class, ProtocolVersionsHelper.DOWN_1_8); registerSkip(ParticleDamageIndicator.class, ProtocolVersionsHelper.DOWN_1_8); registerSkip(ParticleSweepAttack.class, ProtocolVersionsHelper.DOWN_1_8); registerSkip(ParticleElderGuardian.class, ProtocolVersionsHelper.DOWN_1_7_10); registerSkip(ParticleBarrier.class, ProtocolVersionsHelper.DOWN_1_7_10); } @SuppressWarnings("unchecked") protected <T extends Particle> void registerRemap(Class<T> from, Function<T, Particle> remapFunction, ProtocolVersion... versions) { Arrays.stream(versions) .forEach(version -> getTable(version).setRemap(from, (Function<Particle, Particle>) remapFunction)); } protected void registerSkip(Class<? extends Particle> from, ProtocolVersion... versions) { registerRemap(from, original -> null, versions); } @Override protected ParticleRemappingTable createTable() { return new ParticleRemappingTable(); } }; public static class ParticleRemappingTable extends RemappingTable { protected final Map<Class<? extends Particle>, Function<Particle, Particle>> table = new HashMap<>(); public void setRemap(Class<? extends Particle> particle, Function<Particle, Particle> remap) { table.put(particle, remap); } /** * Returns a remapping function for provided particle type <br> * Returned remapping function is never null <br> * The remapping function itself however can return new particle or null (which means that particle should be skipped) * @param particle particle type * @return remapping function */ public Function<Particle, Particle> getRemap(Class<? extends Particle> particle) { Function<Particle, Particle> function = table.get(particle); return function != null ? function : UnaryOperator.identity(); } } }