Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

I want to do a verification check on my two custom providers before I go and write a tutorial on their implementation.

 

The first one is an advancements provider that takes in a FinishedAdvancement (basically an advancement still as a builder and its location. It's almost exactly similar to the Minecraft implementation.

public abstract class AdvancementsProvider implements IDataProvider {
	private static final Logger LOGGER = LogManager.getLogger();
	private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().create();
	private final DataGenerator generator;

	public AdvancementsProvider(DataGenerator generatorIn) {
		this.generator = generatorIn;
	}

	@Override
	public void act(DirectoryCache cache) throws IOException {
		Path path = this.generator.getOutputFolder();
		Set<ResourceLocation> set = Sets.newHashSet();
		Consumer<FinishedAdvancement> consumer = (advancementIn) -> {
			if (!set.add(advancementIn.getId())) {
				throw new IllegalStateException("Duplicate advancement " + advancementIn.getId());
			} else {
				Path path1 = getPath(path, advancementIn);

				try {
					IDataProvider.save(GSON, cache, advancementIn.serialize(), path1);
				} catch (IOException ioexception) {
					LOGGER.error("Couldn't save advancement {}", path1, ioexception);
				}

			}
		};

		for(Consumer<Consumer<FinishedAdvancement>> consumer1 : this.getAdvancements()) {
			consumer1.accept(consumer);
		}

	}
	
	public abstract List<Consumer<Consumer<FinishedAdvancement>>> getAdvancements();

	private static Path getPath(Path pathIn, FinishedAdvancement advancementIn) {
		return pathIn.resolve("data/" + advancementIn.getId().getNamespace() + "/advancements/" + advancementIn.getId().getPath() + ".json");
	}

	@Override
	public String getName() {
		return "Advancements";
	}
}
public class FinishedAdvancement {

	private final ResourceLocation id;
	private final Advancement.Builder builder;
	
	private FinishedAdvancement(ResourceLocation idIn, Advancement.Builder builderIn) {
		this.id = idIn;
		this.builder = builderIn;
	}

	public JsonObject serialize() {
		return this.builder.serialize();
	}
	
	public ResourceLocation getId() {
		return id;
	}
	
	public static class Builder {
		
		private Advancement.Builder builder;
		
		private Builder() {}
		
		public static FinishedAdvancement.Builder builder() {
			return new FinishedAdvancement.Builder();
		}
		
		public FinishedAdvancement.Builder advancement(Advancement.Builder builderIn) {
			this.builder = builderIn;
			return this;
		}
		
		public FinishedAdvancement build(Consumer<FinishedAdvancement> consumer, ResourceLocation id) {
			FinishedAdvancement advancement = new FinishedAdvancement(id, builder);
			consumer.accept(advancement);
			return advancement;
		}
	}
}

 

The second one is a basic provider for a sounds.json file. The only parameter it doesn't take into account is its type since that is automatically set for its usage.

public abstract class SoundsProvider implements IDataProvider {

	private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create();
	private final DataGenerator gen;
	private final String modid;

	public SoundsProvider(DataGenerator gen, String modid) {
		this.gen = gen;
		this.modid = modid;
	}

	protected abstract void addSounds(Consumer<SoundBuilder> consumer);
	
	@Override
	public void act(DirectoryCache cache) throws IOException {
		JsonObject object = new JsonObject();
		addSounds(builder -> builder.serialize(object));
		IDataProvider.save(GSON, cache, object, this.gen.getOutputFolder().resolve("assets/" + modid + "/sounds.json"));
	}

	@Override
	public String getName() {
		return "Sounds";
	}

}
public class SoundBuilder {

	private ResourceLocation name;
	private boolean replace;
	@Nullable
	private String subtitleTranslationKey;
	private final List<SoundExtension> sounds = new ArrayList<>();
	
	private SoundBuilder(ResourceLocation location) {
		this.name = location;
	}
	
	public static SoundBuilder builder(SoundEvent sound) {
		return builder(sound.getRegistryName());
	}
	
	public static SoundBuilder builder(Supplier<? extends SoundEvent> soundSupplier) {
		return builder(soundSupplier.get());
	}
	
	public static SoundBuilder builder(ResourceLocation location) {
		return new SoundBuilder(location);
	}

	public SoundBuilder replace() {
		this.replace = true;
		return this;
	}
	
	public SoundBuilder subtitle() {
		return subtitle("subtitle." + name.getNamespace() + "." + name.getPath());
	}
	
	public SoundBuilder subtitle(String translationKey) {
		this.subtitleTranslationKey = translationKey;
		return this;
	}
	
	private SoundBuilder defaultSound() {
		return sound(this.name);
	}
	
	public SoundBuilder sound(ResourceLocation name) {
		this.sounds.add(new SoundExtension(name));
		return this;
	}
	
	public SoundBuilder sound(SoundExtension soundIn) {
		this.sounds.add(soundIn);
		return this;
	}
	
	public void build(Consumer<SoundBuilder> consumer) {
		this.validate();
		consumer.accept(this);
	}
	
	private void validate() {
		if(this.sounds.isEmpty()) {
			this.defaultSound();
		}
		this.sounds.forEach(SoundExtension::validate);
	}
	
	public void serialize(JsonObject parentObject) {
		JsonObject object = new JsonObject();
		
		object.addProperty("replace", this.replace);
		if(subtitleTranslationKey != null) {
			object.addProperty("subtitle", this.subtitleTranslationKey);
		}
		
		JsonArray array = new JsonArray();
		this.sounds.forEach(sound -> array.add(sound.serialize()));
		object.add("sounds", array);
		
		parentObject.add(this.name.getPath(), object);
	}
	
	public static class SoundExtension {
		
		private final String name;
		private float volume = 1.0f, pitch = 1.0f;
		private int weight = 1, attenuation_distance = 16;
		private boolean stream, preload;
		
		private SoundExtension(ResourceLocation name) {
			this.name = name.toString().replaceAll("[.]", "/");
		}
		
		public static SoundExtension builder(ResourceLocation name) {
			return new SoundExtension(name);
		}
		
		public SoundExtension volume(float volumeIn) {
			this.volume = volumeIn;
			return this;
		}
		
		public SoundExtension pitch(float pitchIn) {
			this.pitch = pitchIn;
			return this;
		}
		
		public SoundExtension weight(int weightIn) {
			this.weight = weightIn;
			return this;
		}
		
		public SoundExtension stream() {
			this.stream = true;
			return this;
		}
		
		public SoundExtension attenuationDistance(int attenuationDistanceIn) {
			this.attenuation_distance = attenuationDistanceIn;
			return this;
		}
		
		public SoundExtension preload() {
			this.preload = true;
			return this;
		}
		
		private void validate() {
			if(this.volume != MathHelper.clamp(this.volume, 0, 1.0)) {
				throw new IllegalArgumentException("Sound " + name + " has a volume not between 0 and 1.");
			} else if(this.pitch != MathHelper.clamp(this.pitch, 0, 2.0)) {
				throw new IllegalArgumentException("Sound " + name + " has a pitch not between 0 and 2.");
			} else if(this.weight <= 0) {
				throw new IllegalArgumentException("Sound " + name + " has a negative or zero weight.");
			} else if(this.attenuation_distance <= 0) {
				throw new IllegalArgumentException("Sound " + name + " has a negative or zero attenuation distance.");
			}
		}
		
		private JsonObject serialize() {
			JsonObject object = new JsonObject();
			
			object.addProperty("name", this.name);
			object.addProperty("volume", this.volume);
			object.addProperty("pitch", this.pitch);
			object.addProperty("weight", this.weight);
			object.addProperty("weight", this.weight);
			object.addProperty("stream", this.stream);
			object.addProperty("attenuation_distance", this.attenuation_distance);
			object.addProperty("preload", this.preload);
			
			return object;
		}
	}
}

 

Please let me know if there is anything I can do to improve the quality of this code.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.