Skip to content

Instantly share code, notes, and snippets.

@JamiesWhiteShirt
Last active March 17, 2020 23:41
Show Gist options
  • Save JamiesWhiteShirt/593ba90c9dee760aad8a88317f7f1b4c to your computer and use it in GitHub Desktop.
Save JamiesWhiteShirt/593ba90c9dee760aad8a88317f7f1b4c to your computer and use it in GitHub Desktop.
Particle factory registry
public class ParticleFactoryRegistry {
private static final Constructor<? extends SpriteProvider> SIMPLE_SPRITE_PROVIDER_CONSTRUCTOR;
static {
try {
String intermediaryClassName = "net.minecraft.class_702$class_4090";
String currentClassName = FabricLoader.getInstance().getMappingResolver().mapClassName("intermediary", intermediaryClassName);
@SuppressWarnings("unchecked")
Class<? extends SpriteProvider> clazz = (Class<? extends SpriteProvider>) Class.forName(currentClassName);
SIMPLE_SPRITE_PROVIDER_CONSTRUCTOR = clazz.getDeclaredConstructor(ParticleManager.class);
SIMPLE_SPRITE_PROVIDER_CONSTRUCTOR.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException("Unable to register particles", e);
}
}
public static <T extends ParticleEffect> void register(ParticleManager particleManager, ParticleType<T> particleType, SpriteAwareFactory<T> factory) {
SpriteProvider spriteProvider;
try {
spriteProvider = SIMPLE_SPRITE_PROVIDER_CONSTRUCTOR.newInstance(particleManager);
} catch (Exception e) {
throw new RuntimeException("Unable to register particle", e);
}
ParticleManagerAccessor accessor = (ParticleManagerAccessor) particleManager;
accessor.getFactories().put(Registry.PARTICLE_TYPE.getRawId(particleType), factory.create(spriteProvider));
accessor.getSpriteAwareFactories().put(Registry.PARTICLE_TYPE.getId(particleType), spriteProvider);
}
@FunctionalInterface
private interface SpriteAwareFactory <T extends ParticleEffect> {
ParticleFactory<T> create(SpriteProvider spriteProvider);
}
}
@Mixin(ParticleManager.class)
public interface ParticleManagerAccessor {
@Accessor("factories")
Int2ObjectMap<ParticleFactory<?>> getFactories();
// The generic signature is actually different, this is the closest we can get, and it works due to type erasure.
@Accessor("spriteAwareFactories")
Map<Identifier, SpriteProvider> getSpriteAwareFactories();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment