diff --git a/src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceCollector.kt b/src/main/kotlin/net/mcbrawls/packin/resource/pack/ResourceCollector.kt similarity index 87% rename from src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceCollector.kt rename to src/main/kotlin/net/mcbrawls/packin/resource/pack/ResourceCollector.kt index bcfea04..671ebb2 100644 --- a/src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceCollector.kt +++ b/src/main/kotlin/net/mcbrawls/packin/resource/pack/ResourceCollector.kt @@ -1,8 +1,11 @@ -package net.mcbrawls.packin.resource.provider +package net.mcbrawls.packin.resource.pack import net.mcbrawls.packin.resource.PackResource import net.minecraft.util.Identifier +/** + * Collects resources for a pack. + */ fun interface ResourceCollector { /** * Collect an existing resource. diff --git a/src/main/kotlin/net/mcbrawls/packin/resource/provider/FontProvider.kt b/src/main/kotlin/net/mcbrawls/packin/resource/provider/FontProvider.kt index 25b3bfe..53add03 100644 --- a/src/main/kotlin/net/mcbrawls/packin/resource/provider/FontProvider.kt +++ b/src/main/kotlin/net/mcbrawls/packin/resource/provider/FontProvider.kt @@ -6,6 +6,7 @@ import net.mcbrawls.packin.PackinMod.addProperty import net.mcbrawls.packin.listener.PackinResourceLoader import net.mcbrawls.packin.resource.PackResource import net.mcbrawls.packin.resource.pack.PackinResourcePack +import net.mcbrawls.packin.resource.pack.ResourceCollector import net.minecraft.util.Identifier class FontProvider( diff --git a/src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceProvider.kt b/src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceProvider.kt index a1d98c0..894e379 100644 --- a/src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceProvider.kt +++ b/src/main/kotlin/net/mcbrawls/packin/resource/provider/ResourceProvider.kt @@ -1,7 +1,11 @@ package net.mcbrawls.packin.resource.provider import net.mcbrawls.packin.resource.pack.PackinResourcePack +import net.mcbrawls.packin.resource.pack.ResourceCollector interface ResourceProvider { + /** + * Collects all resources to be added to the pack. + */ fun collectResources(pack: PackinResourcePack, collector: ResourceCollector) } diff --git a/src/main/kotlin/net/mcbrawls/packin/resource/provider/SoundProvider.kt b/src/main/kotlin/net/mcbrawls/packin/resource/provider/SoundProvider.kt new file mode 100644 index 0000000..be798c4 --- /dev/null +++ b/src/main/kotlin/net/mcbrawls/packin/resource/provider/SoundProvider.kt @@ -0,0 +1,83 @@ +package net.mcbrawls.packin.resource.provider + +import com.google.gson.JsonArray +import com.google.gson.JsonObject +import net.mcbrawls.packin.listener.PackinResourceLoader +import net.mcbrawls.packin.resource.pack.PackinResourcePack +import net.mcbrawls.packin.resource.pack.ResourceCollector +import net.minecraft.util.Identifier + +class SoundProvider( + /** + * The sound ids to register. + */ + vararg val sounds: Identifier, + + /** + * A sound to replace sounds that are not found in the source files. + */ + val unimplementedSound: Identifier? = null, +) : ResourceProvider { + override fun collectResources(pack: PackinResourcePack, collector: ResourceCollector) { + var hasUnimplemented = false + + sounds.groupBy(Identifier::getNamespace) + .forEach { (namespace, ids) -> + // register all sound ids + val invalidSoundPaths = ids.filterNot { id -> + val soundPath = createSoundPath(id) + val soundResource = PackinResourceLoader[soundPath] + if (soundResource != null) { + collector.collect(soundResource) + true + } else { + hasUnimplemented = true + false + } + } + + // register sounds json for namespace + val soundsJson = JsonObject().apply { + ids.forEach { id -> + val usedId = if (invalidSoundPaths.contains(id)) { + unimplementedSound + } else { + id + } + + if (usedId != null) { + add( + id.path, + JsonObject().apply { + add( + "sounds", + JsonArray().apply { + add(usedId.toString()) + } + ) + } + ) + } + } + } + + collector.collect(Identifier.of(namespace, "sounds.json"), soundsJson.toString().encodeToByteArray()) + } + + // collect unimplemented sound if applicable + if (hasUnimplemented) { + unimplementedSound?.let { id -> + val path = createSoundPath(id) + val resource = PackinResourceLoader[path] + resource?.also(collector::collect) + } + } + } + + /** + * Creates the file path of the given sound id. + */ + fun createSoundPath(id: Identifier): Identifier { + return id.withPath { "sounds/$it.ogg" } + } +} diff --git a/src/test/kotlin/net/mcbrawls/packin/test/PackinTest.kt b/src/test/kotlin/net/mcbrawls/packin/test/PackinTest.kt index 0e844cd..8694921 100644 --- a/src/test/kotlin/net/mcbrawls/packin/test/PackinTest.kt +++ b/src/test/kotlin/net/mcbrawls/packin/test/PackinTest.kt @@ -13,6 +13,7 @@ import net.mcbrawls.packin.font.FontMetrics.Companion.minecraftWidth import net.mcbrawls.packin.resource.pack.PackMetadata import net.mcbrawls.packin.resource.pack.PackinResourcePack import net.mcbrawls.packin.resource.provider.FontProvider +import net.mcbrawls.packin.resource.provider.SoundProvider import net.minecraft.command.argument.IdentifierArgumentType import net.minecraft.server.command.CommandManager import net.minecraft.text.Text @@ -36,13 +37,23 @@ object PackinTest : ModInitializer { dispatcher.register( CommandManager.literal("out") .executes { context -> - val packBytes = PackinResourcePack.create(PackMetadata("Test", Text.literal("Test"))) { - addProvider(FontProvider(Identifier.of("brawls", "pinch"), 7.0f, 4.0f)) - addProvider(FontProvider(Identifier.of("brawls", "love_bug"), 9.0f, 8.0f)) - addProvider(FontProvider(Identifier.of("brawls", "chocolate"), 11.0f, 8.0f)) - }.createZip() - val path = Path("out.zip") - path.writeBytes(packBytes) + runCatching { + val packBytes = PackinResourcePack.create(PackMetadata("Test", Text.literal("Test"))) { + addProvider(FontProvider(Identifier.of("brawls", "pinch"), 7.0f, 4.0f)) + addProvider(FontProvider(Identifier.of("brawls", "love_bug"), 9.0f, 8.0f)) + addProvider(FontProvider(Identifier.of("brawls", "chocolate"), 11.0f, 8.0f)) + + addProvider( + SoundProvider( + Identifier.of("brawls", "global/action_success"), + Identifier.of("brawls", "global/doesnt_exist"), + unimplementedSound = Identifier.of("brawls", "unimplemented") + ) + ) + }.createZip() + val path = Path("out.zip") + path.writeBytes(packBytes) + }.exceptionOrNull()?.printStackTrace() 1 } )