diff --git a/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/api/client/datagen/v1/builder/SoundTypeBuilder.java b/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/api/client/datagen/v1/builder/SoundTypeBuilder.java index 982e15ff5cf..87182f73b6e 100644 --- a/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/api/client/datagen/v1/builder/SoundTypeBuilder.java +++ b/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/api/client/datagen/v1/builder/SoundTypeBuilder.java @@ -37,8 +37,7 @@ * *

Use in conjunction with {@link FabricSoundsProvider} to generate sound definitions. * - * @see net.minecraft.client.sounds.SoundManager - * @see net.minecraft.client.sounds.WeighedSoundEvents + * @see net.minecraft.client.resources.sounds.SoundEventRegistration */ @ApiStatus.NonExtendable public interface SoundTypeBuilder { @@ -64,11 +63,20 @@ static SoundTypeBuilder of() { } /** - * Sets the sound category the sound event must play on. + * @deprecated Category is not a field interpreted by vanilla in the sounds file, + * calling this method will have no effect. + */ + @Deprecated(forRemoval = true) + default SoundTypeBuilder category(SoundSource category) { + return this; + } + + /** + * Sets an optional replace boolean, which on true allows this sound type to override others. * - *

The default category is {@link SoundSource#NEUTRAL}. GUI elements should use {@link SoundSource#MASTER}. + *

The default is false. */ - SoundTypeBuilder category(SoundSource category); + SoundTypeBuilder replace(boolean replace); /** * Sets an optional translation key string to use for the sound's subtitle. @@ -134,6 +142,8 @@ public String getSerializedName() { /** * Builder for creating a weighted sound entry that can be played for a particular sound type. + * + * @see net.minecraft.client.resources.sounds.Sound */ @ApiStatus.NonExtendable interface EntryBuilder { diff --git a/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/impl/datagen/client/SoundTypeBuilderImpl.java b/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/impl/datagen/client/SoundTypeBuilderImpl.java index 65fc3e33643..f90305bacb5 100644 --- a/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/impl/datagen/client/SoundTypeBuilderImpl.java +++ b/fabric-data-generation-api-v1/src/client/java/net/fabricmc/fabric/impl/datagen/client/SoundTypeBuilderImpl.java @@ -17,14 +17,9 @@ package net.fabricmc.fabric.impl.datagen.client; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.Locale; -import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; @@ -38,14 +33,13 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundSource; import net.fabricmc.fabric.api.client.datagen.v1.builder.SoundTypeBuilder; public final class SoundTypeBuilderImpl implements SoundTypeBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(SoundTypeBuilderImpl.class); - private SoundSource category = SoundSource.NEUTRAL; + private boolean replace = false; @Nullable private String subtitle; private final List sounds = new ArrayList<>(); @@ -53,9 +47,8 @@ public final class SoundTypeBuilderImpl implements SoundTypeBuilder { public SoundTypeBuilderImpl() { } @Override - public SoundTypeBuilder category(SoundSource category) { - Objects.requireNonNull(category, "Sound event category must not be null."); - this.category = category; + public SoundTypeBuilder replace(boolean replace) { + this.replace = replace; return this; } @@ -93,26 +86,38 @@ public SoundType build() { } } - return new SoundType(sounds, category, Optional.ofNullable(subtitle)); + return new SoundType(sounds, replace, Optional.ofNullable(subtitle)); } - public record SoundType(List sounds, SoundSource category, Optional subtitle) { - private static final Map CATEGORIES = Arrays.stream(SoundSource.values()).collect(Collectors.toMap(SoundSource::getName, Function.identity())); - private static final Codec SOUND_CATEGORY_CODEC = Codec.stringResolver(SoundSource::getName, name -> CATEGORIES.getOrDefault(name.toLowerCase(Locale.ROOT), SoundSource.NEUTRAL)); + /** + * Record of the sound event registration class for data generation. + * + * @see net.minecraft.client.resources.sounds.SoundEventRegistration + */ + public record SoundType(List sounds, boolean replace, Optional subtitle) { + /** + * @see net.minecraft.client.resources.sounds.SoundEventRegistrationSerializer + */ public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Entry.CODEC.listOf().fieldOf("sounds").forGetter(SoundType::sounds), - SOUND_CATEGORY_CODEC.fieldOf("category").forGetter(SoundType::category), + Codec.BOOL.optionalFieldOf("replace", false).forGetter(SoundType::replace), Codec.STRING.optionalFieldOf("subtitle").forGetter(SoundType::subtitle) ).apply(instance, SoundType::new)); } - private record Entry(Identifier name, RegistrationType type, float volume, float pitch, int weight, int attenuationDistance, boolean stream, boolean preload) { + /** + * Record of the sound class to use for data generation. + * + * @see net.minecraft.client.resources.sounds.Sound + */ + public record Entry(Identifier name, RegistrationType type, float volume, float pitch, int weight, + int attenuationDistance, boolean stream, boolean preload) { private static final Codec MAP_CODEC = RecordCodecBuilder.create(instance -> instance.group( Identifier.CODEC.fieldOf("name").forGetter(Entry::name), RegistrationType.CODEC.optionalFieldOf("type", RegistrationType.FILE).forGetter(Entry::type), - Codec.FLOAT.optionalFieldOf("volume", EntryBuilder.DEFAULT_VOLUME).forGetter(Entry::volume), - Codec.FLOAT.optionalFieldOf("pitch", EntryBuilder.DEFAULT_PITCH).forGetter(Entry::pitch), - Codec.INT.optionalFieldOf("weight", EntryBuilder.DEFAULT_WEIGHT).forGetter(Entry::weight), + Codec.floatRange(Float.MIN_VALUE, 1.0F).optionalFieldOf("volume", EntryBuilder.DEFAULT_VOLUME).forGetter(Entry::volume), + Codec.floatRange(0.5F, 2.0F).optionalFieldOf("pitch", EntryBuilder.DEFAULT_PITCH).forGetter(Entry::pitch), + Codec.intRange(1, Integer.MAX_VALUE).optionalFieldOf("weight", EntryBuilder.DEFAULT_WEIGHT).forGetter(Entry::weight), Codec.INT.optionalFieldOf("attenuation_distance", EntryBuilder.DEFAULT_ATTENUATION_DISTANCE).forGetter(Entry::attenuationDistance), Codec.BOOL.optionalFieldOf("stream", false).forGetter(Entry::stream), Codec.BOOL.optionalFieldOf("preload", false).forGetter(Entry::preload) @@ -124,10 +129,10 @@ private record Entry(Identifier name, RegistrationType type, float volume, float ); private static final Codec CODEC = Codec.xor(STRING_CODEC, MAP_CODEC).xmap(Either::unwrap, sound -> { if (sound.type() != RegistrationType.FILE - || sound.volume() != 1F - || sound.pitch() != 1F - || sound.weight() != 1 - || sound.attenuationDistance() != 16 + || sound.volume() != EntryBuilder.DEFAULT_VOLUME + || sound.pitch() != EntryBuilder.DEFAULT_PITCH + || sound.weight() != EntryBuilder.DEFAULT_WEIGHT + || sound.attenuationDistance() != EntryBuilder.DEFAULT_ATTENUATION_DISTANCE || sound.stream() || sound.preload()) { return Either.right(sound); diff --git a/fabric-data-generation-api-v1/src/test/java/net/fabricmc/fabric/test/datagen/client/SoundsTypeBuilderTest.java b/fabric-data-generation-api-v1/src/test/java/net/fabricmc/fabric/test/datagen/client/SoundsTypeBuilderTest.java new file mode 100644 index 00000000000..2b8ad737743 --- /dev/null +++ b/fabric-data-generation-api-v1/src/test/java/net/fabricmc/fabric/test/datagen/client/SoundsTypeBuilderTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.datagen.client; + +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import net.minecraft.SharedConstants; +import net.minecraft.resources.Identifier; +import net.minecraft.server.Bootstrap; +import net.minecraft.sounds.SoundEvents; + +import net.fabricmc.fabric.api.client.datagen.v1.builder.SoundTypeBuilder; +import net.fabricmc.fabric.impl.datagen.client.SoundTypeBuilderImpl; + +public class SoundsTypeBuilderTest { + @BeforeAll + static void beforeAll() { + SharedConstants.tryDetectVersion(); + Bootstrap.bootStrap(); + } + + @Test + public void buildSoundType1() { + SoundTypeBuilderImpl.SoundType expected = new SoundTypeBuilderImpl.SoundType( + List.of( + new SoundTypeBuilderImpl.Entry(Identifier.withDefaultNamespace("mob/parrot/idle1"), + SoundTypeBuilder.RegistrationType.FILE, 0.7F, 1.0F, 1, + 16, false, false), + new SoundTypeBuilderImpl.Entry(Identifier.withDefaultNamespace("mob/parrot/idle2"), + SoundTypeBuilder.RegistrationType.FILE, 1.0F, 1.0F, 1, + 16, false, false), + new SoundTypeBuilderImpl.Entry(SoundEvents.ANVIL_HIT.location(), + SoundTypeBuilder.RegistrationType.SOUND_EVENT, 1.0F, 1.0F, 100, + 16, false, false), + new SoundTypeBuilderImpl.Entry(SoundEvents.ARMOR_EQUIP_GENERIC.value().location(), + SoundTypeBuilder.RegistrationType.SOUND_EVENT, 1.0F, 1.0F, 1, + 16, false, false), + new SoundTypeBuilderImpl.Entry(Identifier.withDefaultNamespace("mob/parrot/idle"), + SoundTypeBuilder.RegistrationType.FILE, 0.3F, 0.5F, 1, + 8, true, true) + ), + true, + Optional.of("subtitles.minecraft.block.anvil.use") + ); + + SoundTypeBuilderImpl.SoundType soundType = ((SoundTypeBuilderImpl) SoundTypeBuilder.of(SoundEvents.ANVIL_USE) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle")) + .volume(0.7F), 1) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle2"))) + .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.ANVIL_HIT) + .weight(100)) + .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.ARMOR_EQUIP_GENERIC)) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle")) + .volume(0.3F).pitch(0.5F).stream(true).preload(true).attenuationDistance(8) + ).replace(true)).build(); + + soundTypeEquals(expected, soundType); + } + + @Test + public void buildSoundType2() { + SoundTypeBuilderImpl.SoundType expected = new SoundTypeBuilderImpl.SoundType( + List.of( + new SoundTypeBuilderImpl.Entry(Identifier.withDefaultNamespace("mob/creeper/hurt"), + SoundTypeBuilder.RegistrationType.FILE, 1.0F, 2.0F, 1, + 16, false, false), + new SoundTypeBuilderImpl.Entry(SoundEvents.STONE_BREAK.location(), + SoundTypeBuilder.RegistrationType.SOUND_EVENT, 1.0F, 1.0F, 1, + 16, false, false), + new SoundTypeBuilderImpl.Entry(Identifier.withDefaultNamespace("block/beacon/power"), + SoundTypeBuilder.RegistrationType.FILE, Float.MIN_VALUE, 0.5F, 1, + 0, false, false) + ), + false, + Optional.empty() + ); + + SoundTypeBuilderImpl.SoundType soundType = ((SoundTypeBuilderImpl) SoundTypeBuilder.of() + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/creeper/hurt")) + .volume(1.0F).pitch(2.0F)) + .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.STONE_BREAK) + .weight(1)) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("block/beacon/power")) + .volume(Float.MIN_VALUE).pitch(0.5F).stream(false).preload(false).attenuationDistance(0) + )).build(); + + soundTypeEquals(expected, soundType); + } + + @Test + public void buildSoundType3() { + SoundTypeBuilderImpl.SoundType expected = new SoundTypeBuilderImpl.SoundType( + List.of( + new SoundTypeBuilderImpl.Entry(Identifier.withDefaultNamespace("sound"), + SoundTypeBuilder.RegistrationType.FILE, 1.0F, 1.0F, 1, + 16, false, false) + ), + false, + Optional.of("super_subtitle") + ); + + SoundTypeBuilderImpl.SoundType soundType = ((SoundTypeBuilderImpl) SoundTypeBuilder.of() + .subtitle("super_subtitle") + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("sound")))).build(); + + soundTypeEquals(expected, soundType); + } + + /** + * Assert that the expected and specified sound type equal. + * + * @param expected sound type to be expected + * @param soundType sound type to assert against + */ + public void soundTypeEquals(SoundTypeBuilderImpl.SoundType expected, SoundTypeBuilderImpl.SoundType soundType) { + Assertions.assertEquals(expected.subtitle(), soundType.subtitle()); + Assertions.assertEquals(expected.replace(), soundType.replace()); + Assertions.assertEquals(expected.sounds().size(), soundType.sounds().size()); + + for (int i = 0; i < expected.sounds().size(); i++) { + SoundTypeBuilderImpl.Entry expectedEntry = expected.sounds().get(i); + SoundTypeBuilderImpl.Entry entry = soundType.sounds().get(i); + entryEquals(expectedEntry, entry); + } + } + + /** + * Assert that all fields of the expected and specified entry equal each other. + * + * @param expected entry with fields to be expected + * @param entry entry to assert against + */ + public void entryEquals(SoundTypeBuilderImpl.Entry expected, SoundTypeBuilderImpl.Entry entry) { + Assertions.assertEquals(expected.name().getNamespace(), entry.name().getNamespace()); + Assertions.assertEquals(expected.type().name(), entry.type().name()); + Assertions.assertEquals(expected.stream(), entry.stream()); + Assertions.assertEquals(expected.preload(), entry.preload()); + Assertions.assertEquals(expected.attenuationDistance(), entry.attenuationDistance()); + Assertions.assertEquals(expected.weight(), entry.weight()); + Assertions.assertEquals(expected.volume(), entry.volume()); + Assertions.assertEquals(expected.pitch(), entry.pitch()); + } +} diff --git a/fabric-data-generation-api-v1/src/test/java/net/fabricmc/fabric/test/datagen/client/SoundsTypeCodecTest.java b/fabric-data-generation-api-v1/src/test/java/net/fabricmc/fabric/test/datagen/client/SoundsTypeCodecTest.java new file mode 100644 index 00000000000..75892db65e6 --- /dev/null +++ b/fabric-data-generation-api-v1/src/test/java/net/fabricmc/fabric/test/datagen/client/SoundsTypeCodecTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.datagen.client; + +import java.util.List; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.JsonOps; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import net.minecraft.SharedConstants; +import net.minecraft.client.resources.sounds.Sound; +import net.minecraft.client.resources.sounds.SoundEventRegistration; +import net.minecraft.client.resources.sounds.SoundEventRegistrationSerializer; +import net.minecraft.resources.Identifier; +import net.minecraft.server.Bootstrap; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.RandomSource; + +import net.fabricmc.fabric.api.client.datagen.v1.builder.SoundTypeBuilder; +import net.fabricmc.fabric.impl.datagen.client.SoundTypeBuilderImpl; + +public class SoundsTypeCodecTest { + /** + * Codec copied from {@link net.fabricmc.fabric.api.client.datagen.v1.provider.FabricSoundsProvider} to use in testing, as it is not accessible. + */ + private static final Codec> CODEC = + Codec.unboundedMap(Codec.STRING, SoundTypeBuilderImpl.SoundType.CODEC); + /** + * Gson copied from {@link net.minecraft.client.sounds.SoundManager} to use in testing, as it is not accessible. + */ + private static final Gson GSON = new GsonBuilder().registerTypeAdapter(SoundEventRegistration.class, + new SoundEventRegistrationSerializer()).create(); + /** + * Type token copied from {@link net.minecraft.client.sounds.SoundManager} to use in testing, as it is not accessible. + */ + private static final TypeToken> SOUND_EVENT_REGISTRATION_TYPE = new TypeToken<>() { }; + + private static final Identifier IDENTIFIER = + Identifier.fromNamespaceAndPath("datagen-test", "sound-event-registrable-codec"); + + @BeforeAll + static void beforeAll() { + SharedConstants.tryDetectVersion(); + Bootstrap.bootStrap(); + } + + @Test + public void soundsTypeCodec1() { + SoundTypeBuilder builder = SoundTypeBuilder.of(SoundEvents.ANVIL_USE) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle")) + .volume(0.7F), 1) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle2"))) + .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.ANVIL_HIT) + .weight(100)) + .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.ARMOR_EQUIP_GENERIC)) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle")) + .volume(0.3F).pitch(0.5F).stream(true).preload(true).attenuationDistance(8) + ).replace(true); + + final Map data = + Map.of(IDENTIFIER.getPath(), ((SoundTypeBuilderImpl) builder).build()); + + expectInputDataInOutput(data, process(data)); + } + + @Test + public void soundsTypeCodec2() { + SoundTypeBuilder builder = SoundTypeBuilder.of() + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/creeper/hurt")) + .volume(1.0F).pitch(2.0F)) + .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.STONE_BREAK) + .weight(1)) + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("block/beacon/power")) + .volume(Float.MIN_VALUE).pitch(0.5F).stream(false).preload(false).attenuationDistance(0) + ); + + final Map data = + Map.of(IDENTIFIER.getPath(), ((SoundTypeBuilderImpl) builder).build()); + + expectInputDataInOutput(data, process(data)); + } + + @Test + public void soundsTypeCodec3() { + SoundTypeBuilder builder = SoundTypeBuilder.of() + .subtitle("super_subtitle") + .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("sound"))); + + final Map data = + Map.of(IDENTIFIER.getPath(), ((SoundTypeBuilderImpl) builder).build()); + + expectInputDataInOutput(data, process(data)); + } + + /** + * Test if the output data has all values present in the input data. + * + * @param inputData Sounds input data used for data generation. + * @param outputData Sounds output data interpreted from sounds file. + */ + private static void expectInputDataInOutput(Map inputData, + Map outputData) { + for (String identifier : inputData.keySet()) { + SoundEventRegistration soundEventRegistration = outputData.get(identifier); + Assertions.assertNotNull(soundEventRegistration); + + SoundTypeBuilderImpl.SoundType soundType = inputData.get(identifier); + + Assertions.assertEquals(soundType.replace(), soundEventRegistration.isReplace()); + Assertions.assertEquals(soundType.subtitle().orElse(null), soundEventRegistration.getSubtitle()); + + List entryList = soundType.sounds(); + List soundList = soundEventRegistration.getSounds(); + Assertions.assertEquals(entryList.size(), soundList.size()); + + for (int i = 0; i < entryList.size(); i++) { + SoundTypeBuilderImpl.Entry entry = entryList.get(i); + Sound sound = soundList.get(i); + expectInputDataInOutput(entry, sound); + } + } + } + + /** + * Test if the output data has all values present in the input data. + * + * @param entry Entry used to represent sound for data generation. + * @param sound Sound interpreted from sounds file. + */ + private static void expectInputDataInOutput(SoundTypeBuilderImpl.Entry entry, Sound sound) { + Assertions.assertEquals(entry.name(), sound.getLocation()); + Assertions.assertEquals(entry.type().name(), sound.getType().name()); + Assertions.assertEquals(entry.stream(), sound.shouldStream()); + Assertions.assertEquals(entry.preload(), sound.shouldPreload()); + Assertions.assertEquals(entry.attenuationDistance(), sound.getAttenuationDistance()); + Assertions.assertEquals(entry.weight(), sound.getWeight()); + Assertions.assertEquals(entry.volume(), sound.getVolume().sample(RandomSource.create())); + Assertions.assertEquals(entry.pitch(), sound.getPitch().sample(RandomSource.create())); + } + + /** + * Generate and interpret data like the sounds provider and sounds manager respectively. + * + * @see net.fabricmc.fabric.api.client.datagen.v1.provider.FabricSoundsProvider + * @see net.minecraft.client.sounds.SoundManager + */ + private Map process(Map data) { + // Generate json element, matching the codec from fabric sounds provider. + DataResult result = CODEC.encodeStart(JsonOps.INSTANCE, data); + + // Interpret json data, matching the Gson and type from sound manager. + return GSON.fromJson(result.getOrThrow(), SOUND_EVENT_REGISTRATION_TYPE); + } +} diff --git a/fabric-data-generation-api-v1/src/testmod/generated/resourcepacks/example_builtin/assets/fabric-data-gen-api-v1-testmod/sounds.json b/fabric-data-generation-api-v1/src/testmod/generated/resourcepacks/example_builtin/assets/fabric-data-gen-api-v1-testmod/sounds.json index 8421e08e010..c13621c44ce 100644 --- a/fabric-data-generation-api-v1/src/testmod/generated/resourcepacks/example_builtin/assets/fabric-data-gen-api-v1-testmod/sounds.json +++ b/fabric-data-generation-api-v1/src/testmod/generated/resourcepacks/example_builtin/assets/fabric-data-gen-api-v1-testmod/sounds.json @@ -1,6 +1,6 @@ { "test_sound": { - "category": "neutral", + "replace": true, "sounds": [ { "name": "minecraft:mob/parrot/idle1", diff --git a/fabric-data-generation-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/datagen/client/DataGeneratorClientTestEntrypoint.java b/fabric-data-generation-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/datagen/client/DataGeneratorClientTestEntrypoint.java index 311b4a4acfb..e6b407eceac 100644 --- a/fabric-data-generation-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/datagen/client/DataGeneratorClientTestEntrypoint.java +++ b/fabric-data-generation-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/datagen/client/DataGeneratorClientTestEntrypoint.java @@ -113,7 +113,7 @@ protected void configure(HolderLookup.Provider registryLookup, SoundExporter exp .sound(SoundTypeBuilder.EntryBuilder.ofEvent(SoundEvents.ARMOR_EQUIP_GENERIC)) .sound(SoundTypeBuilder.EntryBuilder.ofFile(Identifier.withDefaultNamespace("mob/parrot/idle")) .volume(0.3F).pitch(0.5F).stream(true).preload(true).attenuationDistance(8) - ) + ).replace(true) ); } }