package com.simibubi.create; import java.io.IOException; import java.nio.file.Path; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Pair; import net.minecraft.data.DataGenerator; import net.minecraft.data.DirectoryCache; import net.minecraft.data.IDataProvider; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvents; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.registries.IForgeRegistry; //@EventBusSubscriber(bus = Bus.FORGE) public class AllSoundEvents { public static Map entries = Maps.newHashMap(); public static final SoundEntry SCHEMATICANNON_LAUNCH_BLOCK = create("schematicannon_launch_block").subtitle("Schematicannon fires") .playExisting(SoundEvents.GENERIC_EXPLODE, .1f, 1.1f) .category(SoundCategory.BLOCKS) .build(), SCHEMATICANNON_FINISH = create("schematicannon_finish").subtitle("Schematicannon dings") .playExisting(SoundEvents.NOTE_BLOCK_BELL, 1, .7f) .category(SoundCategory.BLOCKS) .build(), DEPOT_SLIDE = create("depot_slide").subtitle("Item slides") .playExisting(SoundEvents.SAND_BREAK, .125f, 1.5f) .category(SoundCategory.BLOCKS) .build(), DEPOT_PLOP = create("depot_plop").subtitle("Item lands") .playExisting(SoundEvents.ITEM_FRAME_ADD_ITEM, .25f, 1.25f) .category(SoundCategory.BLOCKS) .build(), FUNNEL_FLAP = create("funnel_flap").subtitle("Funnel Flaps") .playExisting(SoundEvents.ITEM_FRAME_ROTATE_ITEM, .125f, 1.5f) .playExisting(SoundEvents.WOOL_BREAK, .0425f, .75f) .category(SoundCategory.BLOCKS) .build(), SLIME_ADDED = create("slime_added").subtitle("Slime squishes") .playExisting(SoundEvents.SLIME_BLOCK_PLACE) .category(SoundCategory.BLOCKS) .build(), MECHANICAL_PRESS_ACTIVATION = create("mechanical_press_activation").subtitle("Mechanical Press clangs") .playExisting(SoundEvents.ANVIL_LAND, .125f, 1f) .playExisting(SoundEvents.ITEM_BREAK, .5f, 1f) .category(SoundCategory.BLOCKS) .build(), MECHANICAL_PRESS_ACTIVATION_ON_BELT = create("mechanical_press_activation_belt").subtitle("Mechanical Press bonks") .playExisting(SoundEvents.WOOL_HIT, .75f, 1f) .playExisting(SoundEvents.ITEM_BREAK, .15f, .75f) .category(SoundCategory.BLOCKS) .build(), MIXING = create("mixing").subtitle("Mixing Noises") .playExisting(SoundEvents.GILDED_BLACKSTONE_BREAK, .125f, .5f) .playExisting(SoundEvents.NETHERRACK_BREAK, .125f, .5f) .category(SoundCategory.BLOCKS) .build(), CRANKING = create("cranking").subtitle("Hand Crank turns") .playExisting(SoundEvents.WOOD_PLACE, .075f, .5f) .playExisting(SoundEvents.WOODEN_BUTTON_CLICK_OFF, .025f, .5f) .category(SoundCategory.BLOCKS) .build(), WORLDSHAPER_PLACE = create("worldshaper_place").subtitle("Worldshaper zaps") .playExisting(SoundEvents.NOTE_BLOCK_BASEDRUM) .category(SoundCategory.PLAYERS) .build(), SCROLL_VALUE = create("scroll_value").subtitle("Scroll-input clicks") .playExisting(SoundEvents.NOTE_BLOCK_HAT, .124f, 1f) .category(SoundCategory.PLAYERS) .build(), CONFIRM = create("confirm").subtitle("Affirmative ding") .playExisting(SoundEvents.NOTE_BLOCK_BELL, 0.5f, 0.8f) .category(SoundCategory.PLAYERS) .build(), DENY = create("deny").subtitle("Declining boop") .playExisting(SoundEvents.NOTE_BLOCK_BASS, 1f, 0.5f) .category(SoundCategory.PLAYERS) .build(), COGS = create("cogs").subtitle("Cogwheels rumble") .category(SoundCategory.BLOCKS) .build(), FWOOMP = create("fwoomp").subtitle("Potato Launcher fwoomps") .category(SoundCategory.PLAYERS) .build(), POTATO_HIT = create("potato_hit").subtitle("Vegetable impacts") .playExisting(SoundEvents.ITEM_FRAME_BREAK, .75f, .75f) .playExisting(SoundEvents.WEEPING_VINES_BREAK, .75f, 1.25f) .category(SoundCategory.PLAYERS) .build(), CONTRAPTION_ASSEMBLE = create("contraption_assemble").subtitle("Contraption moves") .playExisting(SoundEvents.WOODEN_TRAPDOOR_OPEN, .5f, .5f) .playExisting(SoundEvents.CHEST_OPEN, .045f, .74f) .category(SoundCategory.BLOCKS) .build(), CONTRAPTION_DISASSEMBLE = create("contraption_disassemble").subtitle("Contraption stops") .playExisting(SoundEvents.IRON_TRAPDOOR_CLOSE, .35f, .75f) .category(SoundCategory.BLOCKS) .build(), WRENCH_ROTATE = create("wrench_rotate").subtitle("Wrench used") .playExisting(SoundEvents.WOODEN_TRAPDOOR_CLOSE, .25f, 1.25f) .category(SoundCategory.BLOCKS) .build(), WRENCH_REMOVE = create("wrench_remove").subtitle("Component breaks") .playExisting(SoundEvents.ITEM_PICKUP, .25f, .75f) .playExisting(SoundEvents.NETHERITE_BLOCK_HIT, .25f, .75f) .category(SoundCategory.BLOCKS) .build(), CRAFTER_CLICK = create("crafter_click").subtitle("Crafter clicks") .playExisting(SoundEvents.NETHERITE_BLOCK_HIT, .25f, 1) .playExisting(SoundEvents.WOODEN_TRAPDOOR_OPEN, .125f, 1) .category(SoundCategory.BLOCKS) .build(), CRAFTER_CRAFT = create("crafter_craft").subtitle("Crafter crafts") .playExisting(SoundEvents.ITEM_BREAK, .125f, .75f) .category(SoundCategory.BLOCKS) .build(), COPPER_ARMOR_EQUIP = create("copper_armor_equip").subtitle("Diving equipment clinks") .playExisting(SoundEvents.ARMOR_EQUIP_GOLD, 1f, 1f) .category(SoundCategory.PLAYERS) .build(), AUTO_POLISH = create("deployer_polish").subtitle("Deployer applies polish") .playExisting(SoundEvents.UI_STONECUTTER_TAKE_RESULT, 1f, 1f) .category(SoundCategory.BLOCKS) .build(), CONTROLLER_CLICK = create("controller_click").subtitle("Controller clicks") .playExisting(SoundEvents.ITEM_FRAME_ADD_ITEM, .35f, 1f) .category(SoundCategory.BLOCKS) .build(), CONTROLLER_PUT = create("controller_put").subtitle("Controller thumps") .playExisting(SoundEvents.BOOK_PUT, 1f, 1f) .category(SoundCategory.BLOCKS) .build(), CONTROLLER_TAKE = create("controller_take").subtitle("Lectern empties") .playExisting(SoundEvents.ITEM_FRAME_REMOVE_ITEM, 1f, 1f) .category(SoundCategory.BLOCKS) .build(), SAW_ACTIVATE_WOOD = create("saw_activate_wood").subtitle("Mechanical Saw activates") .playExisting(SoundEvents.BOAT_PADDLE_LAND, .75f, 1.5f) .category(SoundCategory.BLOCKS) .build(), SAW_ACTIVATE_STONE = create("saw_activate_stone").subtitle("Mechanical Saw activates") .playExisting(SoundEvents.UI_STONECUTTER_TAKE_RESULT, .125f, 1.25f) .category(SoundCategory.BLOCKS) .build(), BLAZE_MUNCH = create("blaze_munch").subtitle("Blaze Burner munches") .playExisting(SoundEvents.GENERIC_EAT, .5f, 1f) .category(SoundCategory.BLOCKS) .build(), CRUSHING_1 = create("crushing_1").subtitle("Crushing noises") .playExisting(SoundEvents.NETHERRACK_HIT) .category(SoundCategory.BLOCKS) .build(), CRUSHING_2 = create("crushing_2").noSubtitle() .playExisting(SoundEvents.GRAVEL_PLACE) .category(SoundCategory.BLOCKS) .build(), CRUSHING_3 = create("crushing_3").noSubtitle() .playExisting(SoundEvents.NETHERITE_BLOCK_BREAK) .category(SoundCategory.BLOCKS) .build(), PECULIAR_BELL_USE = create("peculiar_bell_use").subtitle("Peculiar Bell tolls") .playExisting(SoundEvents.BELL_BLOCK) .category(SoundCategory.BLOCKS) .build(), HAUNTED_BELL_CONVERT = create("haunted_bell_convert").subtitle("Haunted Bell awakens") .category(SoundCategory.BLOCKS) .build(), HAUNTED_BELL_USE = create("haunted_bell_use").subtitle("Haunted Bell tolls") .category(SoundCategory.BLOCKS) .build(); public static SoundEntryBuilder create(String id) { return new SoundEntryBuilder(id); } public static void register(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); for (SoundEntry entry : entries.values()) entry.register(registry); } public static void prepare() { for (SoundEntry entry : entries.values()) entry.prepare(); } public static JsonElement provideLangEntries() { JsonObject object = new JsonObject(); for (SoundEntry entry : entries.values()) if (entry.hasSubtitle()) object.addProperty(entry.getSubtitleKey(), entry.getSubtitle()); return object; } public static SoundEntryProvider provider(DataGenerator generator) { return new SoundEntryProvider(generator); } // @SubscribeEvent // public static void cancelSubtitlesOfCompoundedSounds(PlaySoundEvent event) { // ResourceLocation soundLocation = event.getSound().getSoundLocation(); // if (!soundLocation.getNamespace().equals(Create.ID)) // return; // if (soundLocation.getPath().contains("_compounded_") // event.setResultSound(); // // } private static class SoundEntryProvider implements IDataProvider { private DataGenerator generator; public SoundEntryProvider(DataGenerator generator) { this.generator = generator; } @Override public void run(DirectoryCache cache) throws IOException { generate(generator.getOutputFolder(), cache); } @Override public String getName() { return "Create's Custom Sounds"; } public void generate(Path path, DirectoryCache cache) { Gson GSON = (new GsonBuilder()).setPrettyPrinting() .disableHtmlEscaping() .create(); path = path.resolve("assets/create"); try { JsonObject json = new JsonObject(); entries.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .forEach(entry -> { entry.getValue() .write(json); }); IDataProvider.save(GSON, cache, json, path.resolve("sounds.json")); } catch (IOException e) { e.printStackTrace(); } } } static class SoundEntryBuilder { protected String id; protected String subtitle = "unregistered"; protected SoundCategory category = SoundCategory.BLOCKS; List>> wrappedEvents; public SoundEntryBuilder(String id) { wrappedEvents = Lists.newArrayList(); this.id = id; } public SoundEntryBuilder subtitle(String subtitle) { this.subtitle = subtitle; return this; } public SoundEntryBuilder noSubtitle() { this.subtitle = null; return this; } public SoundEntryBuilder category(SoundCategory category) { this.category = category; return this; } public SoundEntryBuilder playExisting(SoundEvent event, float volume, float pitch) { wrappedEvents.add(Pair.of(event, Couple.create(volume, pitch))); return this; } public SoundEntryBuilder playExisting(SoundEvent event) { return playExisting(event, 1, 1); } public SoundEntry build() { SoundEntry entry = wrappedEvents.isEmpty() ? new CustomSoundEntry(id, subtitle, category) : new WrappedSoundEntry(id, subtitle, wrappedEvents, category); entries.put(entry.getLocation(), entry); return entry; } } public static abstract class SoundEntry { protected String id; protected String subtitle; protected SoundCategory category; public SoundEntry(String id, String subtitle, SoundCategory category) { this.id = id; this.subtitle = subtitle; this.category = category; } public abstract void prepare(); public abstract void register(IForgeRegistry registry); public abstract void write(JsonObject json); public abstract SoundEvent getMainEvent(); public String getSubtitleKey() { return Create.ID + ".subtitle." + id; } public String getId() { return id; } public ResourceLocation getLocation() { return Create.asResource(id); } public boolean hasSubtitle() { return subtitle != null; } public String getSubtitle() { return subtitle; } public void playOnServer(World world, BlockPos pos) { playOnServer(world, pos, 1, 1); } public void playOnServer(World world, BlockPos pos, float volume, float pitch) { play(world, null, pos, volume, pitch); } public void play(World world, PlayerEntity entity, BlockPos pos) { play(world, entity, pos, 1, 1); } public void playFrom(Entity entity) { playFrom(entity, 1, 1); } public void playFrom(Entity entity, float volume, float pitch) { if (!entity.isSilent()) play(entity.level, null, entity.blockPosition(), volume, pitch); } public void play(World world, PlayerEntity entity, BlockPos pos, float volume, float pitch) { play(world, entity, pos.getX(), pos.getY(), pos.getZ(), volume, pitch); } public void play(World world, PlayerEntity entity, Vector3d pos, float volume, float pitch) { play(world, entity, pos.x(), pos.y(), pos.z(), volume, pitch); } public abstract void play(World world, PlayerEntity entity, double x, double y, double z, float volume, float pitch); public void playAt(World world, BlockPos pos, float volume, float pitch, boolean fade) { playAt(world, pos.getX() + .5, pos.getY() + .5, pos.getZ() + .5, volume, pitch, fade); } public void playAt(World world, Vector3d pos, float volume, float pitch, boolean fade) { playAt(world, pos.x(), pos.y(), pos.z(), volume, pitch, fade); } public abstract void playAt(World world, double x, double y, double z, float volume, float pitch, boolean fade); } static class WrappedSoundEntry extends SoundEntry { private List>> wrappedEvents; private List>> compiledEvents; public WrappedSoundEntry(String id, String subtitle, List>> wrappedEvents, SoundCategory category) { super(id, subtitle, category); this.wrappedEvents = wrappedEvents; compiledEvents = Lists.newArrayList(); } @Override public void prepare() { for (int i = 0; i < wrappedEvents.size(); i++) { ResourceLocation location = Create.asResource(getIdOf(i)); SoundEvent sound = new SoundEvent(location).setRegistryName(location); compiledEvents.add(Pair.of(sound, wrappedEvents.get(i) .getSecond())); } } @Override public void register(IForgeRegistry registry) { for (Pair> pair : compiledEvents) registry.register(pair.getFirst()); } @Override public SoundEvent getMainEvent() { return compiledEvents.get(0) .getFirst(); } protected String getIdOf(int i) { return i == 0 ? id : id + "_compounded_" + i; } @Override public void write(JsonObject json) { for (int i = 0; i < wrappedEvents.size(); i++) { Pair> pair = wrappedEvents.get(i); JsonObject entry = new JsonObject(); JsonArray list = new JsonArray(); JsonObject s = new JsonObject(); s.addProperty("name", pair.getFirst() .getLocation() .toString()); s.addProperty("type", "event"); list.add(s); entry.add("sounds", list); if (i == 0 && hasSubtitle()) entry.addProperty("subtitle", getSubtitleKey()); json.add(getIdOf(i), entry); } } @Override public void play(World world, PlayerEntity entity, double x, double y, double z, float volume, float pitch) { for (Pair> pair : compiledEvents) { Couple volPitch = pair.getSecond(); world.playSound(entity, x, y, z, pair.getFirst(), category, volPitch.getFirst() * volume, volPitch.getSecond() * pitch); } } @Override public void playAt(World world, double x, double y, double z, float volume, float pitch, boolean fade) { for (Pair> pair : compiledEvents) { Couple volPitch = pair.getSecond(); world.playLocalSound(x, y, z, pair.getFirst(), category, volPitch.getFirst() * volume, volPitch.getSecond() * pitch, fade); } } } static class CustomSoundEntry extends SoundEntry { protected SoundEvent event; public CustomSoundEntry(String id, String subtitle, SoundCategory category) { super(id, subtitle, category); } @Override public void prepare() { ResourceLocation location = getLocation(); event = new SoundEvent(location).setRegistryName(location); } @Override public void register(IForgeRegistry registry) { registry.register(event); } @Override public SoundEvent getMainEvent() { return event; } @Override public void write(JsonObject json) { JsonObject entry = new JsonObject(); JsonArray list = new JsonArray(); list.add(getLocation().toString()); entry.add("sounds", list); entry.addProperty("subtitle", getSubtitleKey()); json.add(id, entry); } @Override public void play(World world, PlayerEntity entity, double x, double y, double z, float volume, float pitch) { world.playSound(entity, x, y, z, event, category, volume, pitch); } @Override public void playAt(World world, double x, double y, double z, float volume, float pitch, boolean fade) { world.playLocalSound(x, y, z, event, category, volume, pitch, fade); } } }