Skip to content

Commit

Permalink
Add API for other mods to disable EBE features, showing disabled feat…
Browse files Browse the repository at this point in the history
…ures in the config menu
  • Loading branch information
FoundationGames committed Jan 17, 2025
1 parent 8587a04 commit 23ddd5e
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 30 deletions.
71 changes: 66 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,69 @@ Rendering 1700 chests:
![After](https://github.com/FoundationGames/EnhancedBlockEntities/raw/116_indev/img/after.png) <br/>
A 155% frame rate increase!

## Resource Packs
You can edit EBE's block entity models using resource packs, since they have been converted to conventional .json block models. <br/>
To view EBE's built-in resources, click on
Here's an example of how you can customize chests with resource packs using EBE. <br/><br/>
![Custom Chest GIF](https://user-images.githubusercontent.com/55095883/112942134-f67fe780-912f-11eb-8b11-cf316544c22b.gif)
## Is your mod incompatible with EBE?
If you are the developer of a mod that makes changes to block entity rendering, your mod will be broken by EBE. Fortunately, EBE provides an API that allows you to force-disable its features, allowing your mod to function instead.
<br/>
**You don't need to add EBE as a dependency in your development environment either!**

### Add the Entrypoint
`fabric.mod.json`:
```json
{
"entrypoints": {
"main": [...],
"client": [...],
"ebe_v1": [
"my.mod.compat.EBECompatibility"
]
}
}
```

### Need to modify config values? Implement `BiConsumer<Properties, Map<String, Text>>`
`my.mod.compat.EBECompatibility`:
```java
public class EBECompatibility implements BiConsumer<Properties, Map<String, Text>>, ... {
@Override
public void accept(Properties overrideConfigValues, Map<String, Text> overrideReasons) {
overrideConfigValues.setProperty("render_enhanced_chests", "false");

overrideReasons.put("render_enhanced_chests",
Text.literal("EBE Enhanced Chests are not compatible with my mod!")
.formatted(Formatting.YELLOW));
}

...
}
```
The `accept(Properties, Map<String, Text>)` function is called when EBE loads config values. You can override a desired config value by setting the corresponding property of `overrideConfigValues`. This will also gray out the option in the config menu.
<br/>
To explain to users why your mod made that change, you can add a text component to the `overrideReasons` map corresponding to the key of the option you changed.
<br/>
`Text` is `net.minecraft.text.Text` when using Yarn mappings.

### Need to manually reload EBE? Implement `Consumer<Runnable>`
`my.mod.compat.EBECompatibility`:
```java
public class EBECompatibility implements Consumer<Runnable>, ... {
private static Runnable ebeReloader = () -> {};

...

@Override
public void accept(Runnable ebeConfigReloader) {
ebeReloader = ebeConfigReloader;
}
}
```
If your mod needs to modify EBE's config values depending on loaded resources, it may encounter load order problems. This can be somewhat fixed by manually reloading EBE.
<br/>
The `accept(Runnable)` function is called when EBE is first loaded. The `Runnable` executes `EnhancedBlockEntities.load()`. Store this in a field so you can execute it whenever necessary.
```java
void onMyModResourceReload() {
EBECompatibility.someParameter = true;
EBECompatibility.ebeReloader.run();
// Your config modification handler in EBECompatibility can change
// its behavior based on EBECompatibility.someParameter.
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.function.Consumer;

public final class EnhancedBlockEntities implements ClientModInitializer {
public static final String ID = "enhancedblockentities";
public static final String NAMESPACE = "ebe";
Expand All @@ -25,7 +27,10 @@ public final class EnhancedBlockEntities implements ClientModInitializer {

public static final TemplateLoader TEMPLATE_LOADER = new TemplateLoader();

public static final String API_V1 = "ebe_v1";

@Override
@SuppressWarnings("unchecked")
public void onInitializeClient() {
FabricLoader.getInstance().getModContainer(ID).ifPresent(mod -> {
var roots = mod.getRootPaths();
Expand All @@ -35,6 +40,11 @@ public void onInitializeClient() {
}
});

var ebeCompatInitializers = FabricLoader.getInstance().getEntrypointContainers(API_V1, Consumer.class);
for (var init : ebeCompatInitializers) {
init.getEntrypoint().accept((Runnable) EnhancedBlockEntities::load);
}

WorldRenderEvents.END.register(SignRenderManager::endFrame);
ClientTickEvents.END_WORLD_TICK.register(WorldUtil.EVENT_LISTENER);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
import foundationgames.enhancedblockentities.EnhancedBlockEntities;
import foundationgames.enhancedblockentities.util.ConvUtil;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.function.BiConsumer;

public class EBEConfig {
public static final String RENDER_ENHANCED_CHESTS_KEY = "render_enhanced_chests";
Expand Down Expand Up @@ -48,6 +54,8 @@ public class EBEConfig {
public boolean experimentalSigns = true;
public boolean forceResourcePackCompat = false;

public final Map<String, Override> overrides = new HashMap<>();

public void writeTo(Properties properties) {
properties.setProperty(RENDER_ENHANCED_CHESTS_KEY, Boolean.toString(renderEnhancedChests));
properties.setProperty(RENDER_ENHANCED_SIGNS_KEY, Boolean.toString(renderEnhancedSigns));
Expand Down Expand Up @@ -143,6 +151,32 @@ public void load() {
e.printStackTrace();
return;
}

applyCompatConfigModifiers(properties);

readFrom(properties);
}

@SuppressWarnings("unchecked")
private void applyCompatConfigModifiers(Properties properties) {
this.overrides.clear();

var ebeCompatCfgModifiers = FabricLoader.getInstance()
.getEntrypointContainers(EnhancedBlockEntities.API_V1, BiConsumer.class);
for (var modifier : ebeCompatCfgModifiers) {
var mod = modifier.getProvider();
var overrides = new Properties();
var reasons = new HashMap<String, Text>();
modifier.getEntrypoint().accept(overrides, reasons);

for (var key : overrides.stringPropertyNames()) {
@Nullable Text reason = reasons.get(key);
this.overrides.put(key, new Override(mod, reason));
}

properties.putAll(overrides);
}
}

public record Override(ModContainer modResponsible, @Nullable Text reason) {}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
package foundationgames.enhancedblockentities.config.gui.option;

import foundationgames.enhancedblockentities.ReloadType;
import foundationgames.enhancedblockentities.config.EBEConfig;
import foundationgames.enhancedblockentities.util.GuiUtil;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public final class EBEOption {
private static final Text NEWLINE = Text.of("\n");
private static final String OPTION_VALUE = "options.generic_value";
private static final String DIVIDER = "text.ebe.option_value_division";
private static final String OVERRIDDEN = "warning.ebe.overridden";

public final String key;
public final boolean hasValueComments;
public final Text comment;
public final ReloadType reloadType;
public final TextPalette palette;
public final @Nullable EBEConfig.Override override;

private final List<String> values;
private final int defaultValue;
Expand All @@ -27,10 +34,11 @@ public final class EBEOption {
private Tooltip tooltip = null;
private Text text = null;

public EBEOption(String key, List<String> values, int defaultValue, boolean hasValueComments, TextPalette palette, ReloadType reloadType) {
public EBEOption(String key, List<String> values, ConfigView config, boolean hasValueComments, TextPalette palette, ReloadType reloadType) {
this.key = key;
this.values = values;
this.defaultValue = MathHelper.clamp(defaultValue, 0, values.size());
this.defaultValue = MathHelper.clamp(values.indexOf(config.configValues.getProperty(key)), 0, values.size());
this.override = config.overrides.get(key);
this.selected = this.defaultValue;
this.hasValueComments = hasValueComments;
this.palette = palette;
Expand Down Expand Up @@ -62,7 +70,16 @@ public Text getText() {

public Tooltip getTooltip() {
if (tooltip == null) {
if (hasValueComments) tooltip = Tooltip.of(Text.translatable(String.format("option.ebe.%s.valueComment.%s", key, getValue())).append(NEWLINE).append(comment.copyContentOnly()));
if (override != null) {
var text = Text.translatable(OVERRIDDEN, override.modResponsible().getMetadata().getId())
.formatted(Formatting.RED, Formatting.UNDERLINE);
if (override.reason() != null) {
text.append(NEWLINE).append(override.reason());
}

tooltip = Tooltip.of(text);
}
else if (hasValueComments) tooltip = Tooltip.of(Text.translatable(String.format("option.ebe.%s.valueComment.%s", key, getValue())).append(NEWLINE).append(comment.copyContentOnly()));
else tooltip = Tooltip.of(comment.copyContentOnly());
}
return tooltip;
Expand All @@ -78,4 +95,6 @@ public void next() {
public boolean isDefault() {
return selected == defaultValue;
}

public record ConfigView(Properties configValues, Map<String, EBEConfig.Override> overrides) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,71 +125,72 @@ public void addOptions() {
Properties config = new Properties();
EnhancedBlockEntities.CONFIG.writeTo(config);

final var configView = new EBEOption.ConfigView(config, EnhancedBlockEntities.CONFIG.overrides);
final var textRenderer = this.client.textRenderer;

optionsWidget.add(new SectionTextWidget(CHEST_OPTIONS_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.RENDER_ENHANCED_CHESTS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.RENDER_ENHANCED_CHESTS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.RENDER_ENHANCED_CHESTS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.CHEST_AO_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.CHEST_AO_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.CHEST_AO_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.EXPERIMENTAL_CHESTS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.EXPERIMENTAL_CHESTS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.EXPERIMENTAL_CHESTS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
), option(
new EBEOption(EBEConfig.CHRISTMAS_CHESTS_KEY, ALLOWED_FORCED_DISABLED, ALLOWED_FORCED_DISABLED.indexOf(config.getProperty(EBEConfig.CHRISTMAS_CHESTS_KEY)), true, TextPalette.rainbow(0.35f), ReloadType.WORLD)
new EBEOption(EBEConfig.CHRISTMAS_CHESTS_KEY, ALLOWED_FORCED_DISABLED, configView, true, TextPalette.rainbow(0.35f), ReloadType.WORLD)
));

optionsWidget.add(new SectionTextWidget(SIGN_OPTIONS_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.RENDER_ENHANCED_SIGNS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.RENDER_ENHANCED_SIGNS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.RENDER_ENHANCED_SIGNS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.SIGN_TEXT_RENDERING_KEY, SIGN_TEXT_OPTIONS, SIGN_TEXT_OPTIONS.indexOf(config.getProperty(EBEConfig.SIGN_TEXT_RENDERING_KEY)), true, TextPalette.rainbow(0.45f), ReloadType.NONE)
new EBEOption(EBEConfig.SIGN_TEXT_RENDERING_KEY, SIGN_TEXT_OPTIONS, configView, true, TextPalette.rainbow(0.45f), ReloadType.NONE)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.EXPERIMENTAL_SIGNS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.EXPERIMENTAL_SIGNS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.EXPERIMENTAL_SIGNS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
), option(
new EBEOption(EBEConfig.SIGN_AO_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.SIGN_AO_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.SIGN_AO_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));

optionsWidget.add(new SectionTextWidget(BELL_OPTIONS_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.RENDER_ENHANCED_BELLS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.RENDER_ENHANCED_BELLS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.RENDER_ENHANCED_BELLS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.BELL_AO_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.BELL_AO_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.BELL_AO_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));

optionsWidget.add(new SectionTextWidget(BED_OPTIONS_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.RENDER_ENHANCED_BEDS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.RENDER_ENHANCED_BEDS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.RENDER_ENHANCED_BEDS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.EXPERIMENTAL_BEDS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.EXPERIMENTAL_BEDS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.EXPERIMENTAL_BEDS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
), option(
new EBEOption(EBEConfig.BED_AO_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.BED_AO_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.BED_AO_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));

optionsWidget.add(new SectionTextWidget(SHULKER_BOX_OPTIONS_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.RENDER_ENHANCED_SHULKER_BOXES_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.RENDER_ENHANCED_SHULKER_BOXES_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.RENDER_ENHANCED_SHULKER_BOXES_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.SHULKER_BOX_AO_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.SHULKER_BOX_AO_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.SHULKER_BOX_AO_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));

optionsWidget.add(new SectionTextWidget(DECORATED_POT_OPTIONS_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.RENDER_ENHANCED_DECORATED_POTS_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.RENDER_ENHANCED_DECORATED_POTS_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.RENDER_ENHANCED_DECORATED_POTS_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(option(
new EBEOption(EBEConfig.DECORATED_POT_AO_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.DECORATED_POT_AO_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.DECORATED_POT_AO_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));

optionsWidget.add(new SectionTextWidget(ADVANCED_TITLE, textRenderer));
optionsWidget.add(option(
new EBEOption(EBEConfig.FORCE_RESOURCE_PACK_COMPAT_KEY, BOOLEAN_OPTIONS, BOOLEAN_OPTIONS.indexOf(config.getProperty(EBEConfig.FORCE_RESOURCE_PACK_COMPAT_KEY)), false, TextPalette.ON_OFF, ReloadType.RESOURCES)
new EBEOption(EBEConfig.FORCE_RESOURCE_PACK_COMPAT_KEY, BOOLEAN_OPTIONS, configView, false, TextPalette.ON_OFF, ReloadType.RESOURCES)
));
optionsWidget.add(ButtonWidget.builder(DUMP_LABEL, b -> {
try {
Expand All @@ -203,10 +204,16 @@ public void addOptions() {
private ButtonWidget option(EBEOption option) {
options.add(option);

return ButtonWidget.builder(option.getText(), b -> {
var button = ButtonWidget.builder(option.getText(), b -> {
option.next();
b.setMessage(option.getText());
b.setTooltip(option.getTooltip());
}).tooltip(option.getTooltip()).build();

if (option.override != null) {
button.active = false;
}

return button;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.item.BuiltinModelItemRenderer;
import net.minecraft.item.ModelTransformationMode;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ModelTransformationMode;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.Direction;
import org.spongepowered.asm.mixin.Mixin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
"option.ebe.dump": "Dump Example Resources",
"option.ebe.dump.comment": "Dumps the mod's default resources to .minecraft/enhanced_bes_dump/ to be used as an example by resource pack makers.",

"warning.ebe.overridden": "Overwritten by '%s'",

"screen.ebe.config": "Block Entity Settings",

"text.ebe.apply": "Apply",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"from": [1, 0, 1],
"to": [15, 16, 15],
"faces": {
"up": {"uv": [0, 6.5, 7, 13.5], "texture": "#0", "cullface": "up"},
"down": {"uv": [7, 6.5, 14, 13.5], "texture": "#0", "cullface": "down"}
"up": {"uv": [7, 6.5, 14, 13.5], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 6.5, 7, 13.5], "texture": "#0", "cullface": "down"}
}
},
{
Expand Down

0 comments on commit 23ddd5e

Please sign in to comment.