-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #877 from Notenoughmail/1.21-sounds-and-particles
[1.21] SoundEvent and ParticleType Utilities
- Loading branch information
Showing
12 changed files
with
438 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
src/main/java/dev/latvian/mods/kubejs/client/KubeAnimatedParticle.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package dev.latvian.mods.kubejs.client; | ||
|
||
import dev.latvian.mods.kubejs.color.Color; | ||
import dev.latvian.mods.kubejs.typings.Info; | ||
import it.unimi.dsi.fastutil.floats.Float2IntFunction; | ||
import net.minecraft.client.multiplayer.ClientLevel; | ||
import net.minecraft.client.particle.SimpleAnimatedParticle; | ||
import net.minecraft.client.particle.SpriteSet; | ||
import net.minecraft.util.RandomSource; | ||
import net.minecraft.world.phys.Vec3; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.function.Consumer; | ||
|
||
public class KubeAnimatedParticle extends SimpleAnimatedParticle { | ||
|
||
private Float2IntFunction lightColorFunction; | ||
@Nullable | ||
private Consumer<KubeAnimatedParticle> onTick; | ||
|
||
public KubeAnimatedParticle(ClientLevel level, double x, double y, double z, SpriteSet sprites) { | ||
super(level, x, y, z, sprites, 0.0125F); | ||
setLifetime(20); | ||
setSpriteFromAge(sprites); | ||
lightColorFunction = super::getLightColor; | ||
} | ||
|
||
public void setGravity(float g) { | ||
gravity = g; | ||
} | ||
|
||
@Info(value = "Sets teh friction of the particle, the particle's motion is multiplied by this value every tick") | ||
public void setFriction(float f) { | ||
friction = f; | ||
} | ||
|
||
public void setColor(Color color, boolean alpha) { | ||
setColor(color.getRgbJS()); | ||
if (alpha) { | ||
setAlpha((color.getArgbJS() >>> 24) / 255F); | ||
} | ||
} | ||
|
||
public void setColor(Color color) { | ||
setColor(color, false); | ||
} | ||
|
||
public void setPhysicality(boolean hasPhysics) { | ||
this.hasPhysics = hasPhysics; | ||
} | ||
|
||
public void setFasterWhenYMotionBlocked(boolean b) { | ||
speedUpWhenYMotionIsBlocked = b; | ||
} | ||
|
||
public void setLightColor(Float2IntFunction function) { | ||
lightColorFunction = function; | ||
} | ||
|
||
public void onTick(@Nullable Consumer<KubeAnimatedParticle> tick) { | ||
onTick = tick; | ||
} | ||
|
||
public void setSpeed(Vec3 speed) { | ||
setParticleSpeed(speed.x(), speed.y(), speed.z()); | ||
} | ||
|
||
// Getters for protected values | ||
|
||
public ClientLevel getLevel() { return level; } | ||
public double getX() { return x; } | ||
public double getY() { return y; } | ||
public double getZ() { return z; } | ||
public double getXSpeed() { return xd; } | ||
public double getYSpeed() { return yd; } | ||
public double getZSpeed() { return zd; } | ||
public SpriteSet getSpriteSet() { return sprites; } | ||
public RandomSource getRandom() { return random; } | ||
|
||
@Override | ||
public int getLightColor(float partialTick) { | ||
return lightColorFunction.get(partialTick); | ||
} | ||
|
||
@Override | ||
public void tick() { | ||
super.tick(); | ||
if (onTick != null) { | ||
onTick.accept(this); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
src/main/java/dev/latvian/mods/kubejs/client/ParticleGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package dev.latvian.mods.kubejs.client; | ||
|
||
import com.google.gson.JsonArray; | ||
import com.google.gson.JsonObject; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ParticleGenerator { | ||
|
||
public transient List<String> textures = new ArrayList<>(); | ||
|
||
public ParticleGenerator texture(String texture) { | ||
textures.add(texture); | ||
return this; | ||
} | ||
|
||
public ParticleGenerator textures(List<String> textures) { | ||
this.textures = textures; | ||
return this; | ||
} | ||
|
||
public JsonObject toJson() { | ||
var array = new JsonArray(textures.size()); | ||
textures.forEach(array::add); | ||
var json = new JsonObject(); | ||
json.add("textures", array); | ||
return json; | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/dev/latvian/mods/kubejs/client/ParticleProviderRegistryKubeEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package dev.latvian.mods.kubejs.client; | ||
|
||
import net.minecraft.client.multiplayer.ClientLevel; | ||
import net.minecraft.client.particle.Particle; | ||
import net.minecraft.client.particle.ParticleEngine; | ||
import net.minecraft.client.particle.ParticleProvider; | ||
import net.minecraft.client.particle.SpriteSet; | ||
import net.minecraft.core.particles.ParticleOptions; | ||
import net.minecraft.core.particles.ParticleType; | ||
import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent; | ||
|
||
import java.util.function.Consumer; | ||
|
||
public class ParticleProviderRegistryKubeEvent implements ClientKubeEvent { | ||
|
||
private final RegisterParticleProvidersEvent parent; | ||
|
||
public ParticleProviderRegistryKubeEvent(RegisterParticleProvidersEvent event) { | ||
parent = event; | ||
} | ||
|
||
public <T extends ParticleOptions> void register(ParticleType<T> type, SpriteSetParticleProvider<T> spriteProvider) { | ||
parent.registerSpriteSet(type, spriteProvider); | ||
} | ||
|
||
public <T extends ParticleOptions> void register(ParticleType<T> type, Consumer<KubeAnimatedParticle> particle) { | ||
parent.registerSpriteSet(type, set -> (type1, level, x, y, z, xSpeed, ySpeed, zSpeed) -> { | ||
var kube = new KubeAnimatedParticle(level, x, y, z, set); | ||
kube.setParticleSpeed(xSpeed, ySpeed, zSpeed); | ||
particle.accept(kube); | ||
return kube; | ||
}); | ||
} | ||
|
||
public <T extends ParticleOptions> void register(ParticleType<T> type) { | ||
register(type, p -> {}); | ||
} | ||
|
||
public <T extends ParticleOptions> void registerSpecial(ParticleType<T> type, ParticleProvider<T> provider) { | ||
parent.registerSpecial(type, provider); | ||
} | ||
|
||
@FunctionalInterface | ||
public interface SpriteSetParticleProvider<T extends ParticleOptions> extends ParticleEngine.SpriteParticleRegistration<T> { | ||
Particle create(T type, ClientLevel clientLevel, double x, double y, double z, SpriteSet sprites, double xSpeed, double ySpeed, double zSpeed); | ||
|
||
default ParticleProvider<T> create(SpriteSet sprites) { | ||
return (type, level, x, y, z, xSpeed, ySpeed, zSpeed) -> create(type, level, x, y, z, sprites, xSpeed, ySpeed, zSpeed); | ||
} | ||
} | ||
} |
171 changes: 171 additions & 0 deletions
171
src/main/java/dev/latvian/mods/kubejs/client/SoundsGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
package dev.latvian.mods.kubejs.client; | ||
|
||
import com.google.gson.JsonArray; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonPrimitive; | ||
import net.minecraft.Util; | ||
import net.minecraft.util.Mth; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.Consumer; | ||
import java.util.stream.Stream; | ||
|
||
public class SoundsGenerator { | ||
|
||
private final Map<String, SoundGen> sounds = new HashMap<>(); | ||
|
||
public void addSound(String path, Consumer<SoundGen> consumer, boolean overlayExisting) { | ||
if (overlayExisting && sounds.containsKey(path)) { | ||
consumer.accept(sounds.get(path)); | ||
} else { | ||
sounds.put(path, Util.make(new SoundGen(), consumer)); | ||
} | ||
} | ||
|
||
public void addSound(String path, Consumer<SoundGen> consumer) { | ||
addSound(path, consumer, false); | ||
} | ||
|
||
public JsonObject toJson() { | ||
var json = new JsonObject(); | ||
sounds.forEach((path, gen) -> json.add(path, gen.toJson())); | ||
return json; | ||
} | ||
|
||
public static class SoundGen { | ||
|
||
private boolean replace = false; | ||
@Nullable | ||
private String subtitle; | ||
private final List<SoundInstance> instances = new ArrayList<>(); | ||
|
||
public SoundGen replace(boolean b) { | ||
replace = b; | ||
return this; | ||
} | ||
|
||
public SoundGen replace() { return replace(true); } | ||
|
||
public SoundGen subtitle(@Nullable String subtitle) { | ||
this.subtitle = subtitle; | ||
return this; | ||
} | ||
|
||
public SoundGen sound(String file) { | ||
instances.add(new SoundInstance(file)); | ||
return this; | ||
} | ||
|
||
public SoundGen sounds(String... sounds) { | ||
instances.addAll(Stream.of(sounds).map(SoundInstance::new).toList()); | ||
return this; | ||
} | ||
|
||
public SoundGen sound(String file, Consumer<SoundInstance> consumer) { | ||
instances.add(Util.make(new SoundInstance(file), consumer)); | ||
return this; | ||
} | ||
|
||
public JsonObject toJson() { | ||
var json = new JsonObject(); | ||
if (replace) { | ||
json.addProperty("replace", true); | ||
} | ||
if (subtitle != null) { | ||
json.addProperty("subtitle", subtitle); | ||
} | ||
if (!instances.isEmpty()) { | ||
var array = new JsonArray(instances.size()); | ||
instances.forEach(inst -> array.add(inst.toJson())); | ||
json.add("sounds", array); | ||
} | ||
return json; | ||
} | ||
|
||
} | ||
|
||
public static class SoundInstance { | ||
|
||
private final String fileLocation; | ||
private boolean complex = false; | ||
private float volume = 1.0F; | ||
private float pitch = 1.0F; | ||
private int weight = 1; | ||
private boolean stream = false; | ||
private int attenuationDistance = 16; | ||
private boolean preload = false; | ||
private boolean isEventReference = false; | ||
|
||
public SoundInstance(String fileLocation) { | ||
this.fileLocation = fileLocation; | ||
} | ||
|
||
private SoundInstance complex() { | ||
complex = true; | ||
return this; | ||
} | ||
|
||
public SoundInstance volume(float f) { | ||
volume = Mth.clamp(f, 0.0F, 1.0F); | ||
return complex(); | ||
} | ||
|
||
public SoundInstance pitch(float f) { | ||
pitch = Mth.clamp(f, 0.0F, 1.0F); | ||
return complex(); | ||
} | ||
|
||
public SoundInstance weight(int i) { | ||
weight = i; | ||
return complex(); | ||
} | ||
|
||
public SoundInstance stream(boolean b) { | ||
stream = b; | ||
return complex(); | ||
} | ||
|
||
public SoundInstance stream() { return stream(true); } | ||
|
||
public SoundInstance attenuationDistance(int i) { | ||
attenuationDistance = i; | ||
return complex(); | ||
} | ||
|
||
public SoundInstance preload(boolean b) { | ||
preload = b; | ||
return complex(); | ||
} | ||
|
||
public SoundInstance preload() { return preload(true); } | ||
|
||
public SoundInstance asReferenceToEvent() { | ||
isEventReference = true; | ||
return complex(); | ||
} | ||
|
||
public JsonElement toJson() { | ||
if (!complex) { | ||
return new JsonPrimitive(fileLocation.toString()); | ||
} | ||
|
||
final JsonObject json = new JsonObject(); | ||
json.addProperty("name", fileLocation.toString()); | ||
json.addProperty("volume", volume); | ||
json.addProperty("pitch", pitch); | ||
json.addProperty("weight", weight); | ||
json.addProperty("stream", stream); | ||
json.addProperty("attenuation_distance", attenuationDistance); | ||
json.addProperty("preload", preload); | ||
if (isEventReference) { | ||
json.addProperty("type", "event"); | ||
} | ||
return json; | ||
} | ||
} | ||
} |
Oops, something went wrong.