From cda4fb7923be8737d8aa9f191ed2c4804b7f03b9 Mon Sep 17 00:00:00 2001 From: Notenoughmail <78008321+Notenoughmail@users.noreply.github.com> Date: Sun, 19 May 2024 15:31:43 -0700 Subject: [PATCH] Sounds - Add sound event asset generation --- .../client/GenerateClientAssetsEventJS.java | 4 + .../client/GeneratedClientResourcePack.java | 2 + .../kubejs/client/KubeAnimatedParticle.java | 2 +- .../mods/kubejs/client/SoundGenerator.java | 157 ++++++++++++++++++ .../mods/kubejs/core/MinecraftClientKJS.java | 2 +- .../kubejs/generator/AssetJsonGenerator.java | 15 ++ .../mods/kubejs/misc/SoundEventBuilder.java | 18 ++ 7 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 common/src/main/java/dev/latvian/mods/kubejs/client/SoundGenerator.java diff --git a/common/src/main/java/dev/latvian/mods/kubejs/client/GenerateClientAssetsEventJS.java b/common/src/main/java/dev/latvian/mods/kubejs/client/GenerateClientAssetsEventJS.java index d6a29b9bc..96a44af50 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/client/GenerateClientAssetsEventJS.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/client/GenerateClientAssetsEventJS.java @@ -62,4 +62,8 @@ public void defaultHandheldItemModel(ResourceLocation id) { public void particle(ResourceLocation id, Consumer consumer) { generator.particle(id, consumer); } + + public void sounds(String namespace, Consumer consumer) { + generator.sounds(namespace, consumer); + } } \ No newline at end of file diff --git a/common/src/main/java/dev/latvian/mods/kubejs/client/GeneratedClientResourcePack.java b/common/src/main/java/dev/latvian/mods/kubejs/client/GeneratedClientResourcePack.java index 0458536ab..9a56793ae 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/client/GeneratedClientResourcePack.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/client/GeneratedClientResourcePack.java @@ -97,6 +97,8 @@ public void generate(Map map) { ClientEvents.HIGH_ASSETS.post(ScriptType.CLIENT, new GenerateClientAssetsEventJS(generator)); + generator.buildSounds(); + for (var lang : ClientEvents.LANG.findUniqueExtraIds(ScriptType.CLIENT)) { var l = String.valueOf(lang); diff --git a/common/src/main/java/dev/latvian/mods/kubejs/client/KubeAnimatedParticle.java b/common/src/main/java/dev/latvian/mods/kubejs/client/KubeAnimatedParticle.java index 1a9c17858..56abeb4cf 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/client/KubeAnimatedParticle.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/client/KubeAnimatedParticle.java @@ -32,7 +32,7 @@ public void setFriction(float f) { public void setColor(Color color, boolean alpha) { setColor(color.getRgbJS()); if (alpha) { - // setAlpha(color.getArgbJS()); TODO: Eugh bitwise math + setAlpha((color.getArgbJS() >> 24) / 255.0F); } } diff --git a/common/src/main/java/dev/latvian/mods/kubejs/client/SoundGenerator.java b/common/src/main/java/dev/latvian/mods/kubejs/client/SoundGenerator.java new file mode 100644 index 000000000..1c8d44e2e --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/kubejs/client/SoundGenerator.java @@ -0,0 +1,157 @@ +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.resources.ResourceLocation; +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 SoundGenerator { + + private final Map entries = new HashMap<>(); + + public void addSound(String path, Consumer consumer) { + if (entries.containsKey(path)) { + consumer.accept(entries.get(path)); + } else { + entries.put(path, Util.make(new SoundEntry(), consumer)); + } + } + + public JsonObject toJson() { + final JsonObject json = new JsonObject(); + entries.forEach((path, entry) -> json.add(path, entry.toJson())); + return json; + } + + public static class SoundEntry { + + private boolean replace = false; + @Nullable + private String subtitle; + private final List sounds = new ArrayList<>(); + + public SoundEntry replace(boolean b) { + replace = b; + return this; + } + + public SoundEntry subtitle(String subtitle) { + this.subtitle = subtitle; + return this; + } + + public SoundEntry sounds(ResourceLocation... sounds) { + this.sounds.addAll(Stream.of(sounds).map(SoundInstance::new).toList()); + return this; + } + + public SoundEntry sound(ResourceLocation file, Consumer consumer) { + sounds.add(Util.make(new SoundInstance(file), consumer)); + return this; + } + + public JsonObject toJson() { + final JsonObject json = new JsonObject(); + if (replace) { + json.addProperty("replace", true); + } + if (subtitle != null) { + json.addProperty("subtitle", subtitle); + } + if (!sounds.isEmpty()) { + final JsonArray array = new JsonArray(sounds.size()); + sounds.forEach(instance -> array.add(instance.toJson())); + json.add("sounds" ,array); + } + return json; + } + } + + public static class SoundInstance { + + private final ResourceLocation 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(ResourceLocation 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 attenuationDistance(int i) { + attenuationDistance = i; + return complex(); + } + + public SoundInstance preload(boolean b) { + preload = b; + return complex(); + } + + 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; + } + } +} diff --git a/common/src/main/java/dev/latvian/mods/kubejs/core/MinecraftClientKJS.java b/common/src/main/java/dev/latvian/mods/kubejs/core/MinecraftClientKJS.java index 5df5a4de5..2d9737864 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/core/MinecraftClientKJS.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/core/MinecraftClientKJS.java @@ -87,7 +87,7 @@ public interface MinecraftClientKJS extends MinecraftEnvironmentKJS { return Screen.hasAltDown(); } - // TODO: A different name may be better, or perhaps this should be in ClientLevelKJS + // PR Review: A different name may be better, or perhaps this should be in ClientLevelKJS default KubeAnimatedParticle kjs$customParticle(SpriteSet spriteSet, double x, double y, double z) { return kjs$customParticle(kjs$self().level, spriteSet, x, y, z); } diff --git a/common/src/main/java/dev/latvian/mods/kubejs/generator/AssetJsonGenerator.java b/common/src/main/java/dev/latvian/mods/kubejs/generator/AssetJsonGenerator.java index 8cc3b6d6c..7384d7898 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/generator/AssetJsonGenerator.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/generator/AssetJsonGenerator.java @@ -5,6 +5,7 @@ import dev.latvian.mods.kubejs.client.ModelGenerator; import dev.latvian.mods.kubejs.client.MultipartBlockStateGenerator; import dev.latvian.mods.kubejs.client.ParticleGenerator; +import dev.latvian.mods.kubejs.client.SoundGenerator; import dev.latvian.mods.kubejs.client.StencilTexture; import dev.latvian.mods.kubejs.client.VariantBlockStateGenerator; import dev.latvian.mods.kubejs.script.data.GeneratedData; @@ -22,10 +23,12 @@ public class AssetJsonGenerator extends ResourceGenerator { private final Map stencils; + private final Map sounds; public AssetJsonGenerator(Map m) { super(ConsoleJS.CLIENT, m); this.stencils = new HashMap<>(); + this.sounds = new HashMap<>(); } public void blockState(ResourceLocation id, Consumer consumer) { @@ -53,6 +56,14 @@ public void particle(ResourceLocation id, Consumer consumer) json(new ResourceLocation(id.getNamespace(), "particles/" + id.getPath()), gen.toJson()); } + public void sounds(String mod, Consumer consumer) { + if (sounds.containsKey(mod)) { + consumer.accept(sounds.get(mod)); + } else { + sounds.put(mod, Util.make(new SoundGenerator(), consumer)); + } + } + public static ResourceLocation asItemModelLocation(ResourceLocation id) { return new ResourceLocation(id.getNamespace(), "models/item/" + id.getPath()); } @@ -87,4 +98,8 @@ public void stencil(ResourceLocation target, String stencil, JsonObject colors) add(new ResourceLocation(target.getNamespace(), "textures/" + target.getPath() + ".png.mcmeta"), () -> st1.mcmeta, false); } } + + public void buildSounds() { + sounds.forEach((mod, gen) -> json(new ResourceLocation(mod, "sounds"), gen.toJson())); + } } diff --git a/common/src/main/java/dev/latvian/mods/kubejs/misc/SoundEventBuilder.java b/common/src/main/java/dev/latvian/mods/kubejs/misc/SoundEventBuilder.java index c470c7fc8..02b4f38a2 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/misc/SoundEventBuilder.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/misc/SoundEventBuilder.java @@ -1,13 +1,26 @@ package dev.latvian.mods.kubejs.misc; +import dev.latvian.mods.kubejs.client.SoundGenerator; +import dev.latvian.mods.kubejs.generator.AssetJsonGenerator; import dev.latvian.mods.kubejs.registry.BuilderBase; import dev.latvian.mods.kubejs.registry.RegistryInfo; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; +import java.util.function.Consumer; + public class SoundEventBuilder extends BuilderBase { + + public transient Consumer gen; + public SoundEventBuilder(ResourceLocation i) { super(i); + gen = e -> e.sounds(id); + } + + public SoundEventBuilder sound(Consumer consumer) { + gen = consumer; + return this; } @Override @@ -19,4 +32,9 @@ public final RegistryInfo getRegistryType() { public SoundEvent createObject() { return SoundEvent.createVariableRangeEvent(id); } + + @Override + public void generateAssetJsons(AssetJsonGenerator generator) { + generator.sounds(id.getNamespace(), g -> g.addSound(id.getPath(), gen)); + } }