Skip to content

Commit

Permalink
Tidy up JEI integration
Browse files Browse the repository at this point in the history
  • Loading branch information
mezz committed Sep 7, 2024
1 parent 1d68bb4 commit a5122c6
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 161 deletions.
13 changes: 12 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ repositories {
includeGroup "curse.maven"
}
}
maven {
name "blamejared"
url "https://maven.blamejared.com"
content {
includeGroup "mezz.jei"
}
}

maven {
name "jitpack"
Expand All @@ -100,8 +107,12 @@ dependencies {
}

// deps
implementation fg.deobf("curse.maven:jei-238222:${deps.jei}")

// compile against the JEI API but do not include it at runtime
compileOnly fg.deobf("mezz.jei:jei-${config.mc_version}-common-api:${deps.jei}")
compileOnly fg.deobf("mezz.jei:jei-${config.mc_version}-forge-api:${deps.jei}")
// at runtime, use the full JEI jar for Forge
runtimeOnly fg.deobf("mezz.jei:jei-${config.mc_version}-forge:${deps.jei}")

annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
}
Expand Down
2 changes: 1 addition & 1 deletion dependencies.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
forge=47.1.3
jei=4712868
jei=15.17.0.76
172 changes: 172 additions & 0 deletions src/main/java/org/violetmoon/zeta/integration/InfoRecipeBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package org.violetmoon.zeta.integration;

import mezz.jei.api.registration.IRecipeRegistration;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import org.violetmoon.zeta.config.ConfigFlagManager;
import org.violetmoon.zeta.config.ConfigObjectMapper;
import org.violetmoon.zeta.event.load.ZGatherHints;
import org.violetmoon.zeta.module.ZetaModule;
import org.violetmoon.zeta.util.Hint;
import org.violetmoon.zeta.util.RegistryUtil;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class InfoRecipeBuilder implements ZGatherHints {

private final IRecipeRegistration registration;
private final String modId;
private final RegistryAccess registryAccess;
private final List<Item> blacklist;
private final MutableComponent externalPreamble;

public InfoRecipeBuilder(IRecipeRegistration registration, String modId, RegistryAccess registryAccess, List<Item> blacklist) {
this.registration = registration;
this.modId = modId;
this.registryAccess = registryAccess;
this.blacklist = blacklist;

this.externalPreamble = Component.translatable(modId + ".jei.hint.preamble");
externalPreamble.setStyle(externalPreamble.getStyle().withColor(0x0b5d4b));
}

@Override
public void accept(ItemLike itemLike, Component extra) {
Item item = itemLike.asItem();

if (blacklist.contains(item))
return;

MutableComponent compound = Component.literal("");
if (!BuiltInRegistries.ITEM.getKey(item).getNamespace().equals(modId))
compound = compound.append(externalPreamble);
compound = compound.append(extra);

registration.addItemStackInfo(new ItemStack(item), compound);
}

private void applyTag(TagKey<?> tkey, String key, Object... extra) {
if (key.isEmpty())
key = tkey.location().getPath();

try {
List<?> tagItems = RegistryUtil.getTagValues(registryAccess, tkey);
applyIterable(tagItems, key, extra);
} catch (IllegalStateException e) {
throw new RuntimeException("TagKey " + tkey + " failed to load.", e);
}
}

private void applyIterable(Iterable<?> iter, String key, Object... extra) {
if (key.isEmpty())
throw new RuntimeException("Multi-item @Hints need a defined key.");

for (Object obj : iter)
applyObject(obj, key, extra);
}

private void applyObject(Object obj, String key, Object... extra) {
if (obj instanceof ItemLike ilike)
applyItemLike(ilike, key, extra);
else
throw new RuntimeException("Not an ItemLike.");
}

private void applyItemLike(ItemLike itemLike, String key, Object... extra) {
if (key.isEmpty())
hintItem(itemLike, extra);
else
hintItem(itemLike, key, extra);
}

@Override
public void hintItem(ItemLike itemLike, Object... extra) {
Item item = itemLike.asItem();
ResourceLocation res = BuiltInRegistries.ITEM.getKey(item);
String ns = res.getNamespace();
String path = res.getPath();
if (ns.equals(modId))
ns = "";
else ns += ".";

hintItem(itemLike, ns + path, extra);
}

@Override
public void hintItem(ItemLike itemLike, String key, Object... extra) {
Item item = itemLike.asItem();
String hint = modId + ".jei.hint." + key;
accept(item, Component.translatable(hint, extra));
}

@Override
public void gatherHintsFromModule(ZetaModule module, ConfigFlagManager cfm) {
if (!module.isEnabled())
return;

List<Field> fields = ConfigObjectMapper.walkModuleFields(module.getClass());

Map<String, Field> fieldsByName = new HashMap<>();
for (Field f : fields)
fieldsByName.put(f.getName(), f);

for (Field f : fields) {
try {
Hint hint = f.getAnnotation(Hint.class);
if (hint == null)
continue;
f.setAccessible(true);

//Target
Object target = ConfigObjectMapper.getField(module, f);
if (target == null)
continue;

//Flag
String flag = hint.value();
if (!flag.isEmpty() && cfm.getFlag(flag) == !hint.negate())
continue;

//Translation, & gathering extra content
String key = hint.key();
List<Object> extraList = new ArrayList<>(hint.content().length);
for (String c : hint.content()) {
if (c.isEmpty())
continue;

Field extraField = fieldsByName.get(c);
if (extraField == null)
throw new RuntimeException("No field " + c + " referenced in @Hint " + f);

Object yes = ConfigObjectMapper.getField(module, extraField);
extraList.add(yes);
}
Object[] extra = extraList.toArray(new Object[0]);

//Application
if (target instanceof TagKey<?> tkey)
applyTag(tkey, key, extra);
else if (target instanceof Iterable<?> iter)
applyIterable(iter, key, extra);
else
applyObject(target, key, extra);

} catch (Exception e) {
throw new RuntimeException("Problem applying annotation hint " + f.getName() +
" from module " + module.getClass().getName() +
": " + e.getMessage(), e);
}
}
}
}
160 changes: 1 addition & 159 deletions src/main/java/org/violetmoon/zeta/integration/ZetaJeiPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,21 @@
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.PotionItem;
import net.minecraft.world.item.TippedArrowItem;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.level.ItemLike;
import org.jetbrains.annotations.NotNull;
import org.violetmoon.zeta.Zeta;
import org.violetmoon.zeta.config.ConfigFlagManager;
import org.violetmoon.zeta.config.ConfigObjectMapper;
import org.violetmoon.zeta.config.ZetaGeneralConfig;
import org.violetmoon.zeta.event.load.ZGatherHints;
import org.violetmoon.zeta.mod.ZetaMod;
import org.violetmoon.zeta.module.ZetaModule;
import org.violetmoon.zeta.util.Hint;
import org.violetmoon.zeta.util.RegistryUtil;
import org.violetmoon.zeta.util.zetalist.ZetaList;

import java.lang.reflect.Field;
import java.util.*;

@JeiPlugin
Expand Down Expand Up @@ -119,156 +110,7 @@ public void registerRecipes(@NotNull IRecipeRegistration registration) {

List<Item> blacklist = RegistryUtil.massRegistryGet(ZetaGeneralConfig.suppressedInfo, BuiltInRegistries.ITEM);
for (Zeta z : ZetaList.INSTANCE.getZetas()) {
z.loadBus.fire(new GatherHintImpl(registration, z, registryAccess, blacklist), ZGatherHints.class);
}
}

// feel free to move it as public outer class
private static class GatherHintImpl implements ZGatherHints {

private final Zeta zeta;
private final RegistryAccess registryAccess;
private final IRecipeRegistration registration;
private final List<Item> blacklist;
private final MutableComponent externalPreamble;

public GatherHintImpl(IRecipeRegistration registration, Zeta z, RegistryAccess registryAccess, List<Item> blacklist) {
this.zeta = z;
this.registryAccess = registryAccess;
this.registration = registration;
this.blacklist = blacklist;

this.externalPreamble = Component.translatable(z.modid + ".jei.hint.preamble");
externalPreamble.setStyle(externalPreamble.getStyle().withColor(0x0b5d4b));
}

@Override
public void accept(ItemLike itemLike, Component extra) {
Item item = itemLike.asItem();

if (blacklist.contains(item))
return;

MutableComponent compound = Component.literal("");
if (!BuiltInRegistries.ITEM.getKey(item).getNamespace().equals(zeta.modid))
compound = compound.append(externalPreamble);
compound = compound.append(extra);

registration.addItemStackInfo(new ItemStack(item), compound);
}

private void applyTag(TagKey<?> tkey, String key, Object... extra) {
if (key.isEmpty())
key = tkey.location().getPath();

try {
List<?> tagItems = RegistryUtil.getTagValues(registryAccess, tkey);
applyIterable(tagItems, key, extra);
} catch (IllegalStateException e) {
throw new RuntimeException("TagKey " + tkey + " failed to load.", e);
}
}

private void applyIterable(Iterable<?> iter, String key, Object... extra) {
if (key.isEmpty())
throw new RuntimeException("Multi-item @Hints need a defined key.");

for (Object obj : iter)
applyObject(obj, key, extra);
}

private void applyObject(Object obj, String key, Object... extra) {
if (obj instanceof ItemLike ilike)
applyItemLike(ilike, key, extra);
else
throw new RuntimeException("Not an ItemLike.");
}

private void applyItemLike(ItemLike itemLike, String key, Object... extra) {
if (key.isEmpty())
hintItem(itemLike, extra);
else
hintItem(itemLike, key, extra);
}

@Override
public void hintItem(ItemLike itemLike, Object... extra) {
Item item = itemLike.asItem();
ResourceLocation res = BuiltInRegistries.ITEM.getKey(item);
String ns = res.getNamespace();
String path = res.getPath();
if (ns.equals(zeta.modid))
ns = "";
else ns += ".";

hintItem(itemLike, ns + path, extra);
}

@Override
public void hintItem(ItemLike itemLike, String key, Object... extra) {
Item item = itemLike.asItem();
String hint = zeta.modid + ".jei.hint." + key;
accept(item, Component.translatable(hint, extra));
}

@Override
public void gatherHintsFromModule(ZetaModule module, ConfigFlagManager cfm) {
if (!module.isEnabled())
return;

List<Field> fields = ConfigObjectMapper.walkModuleFields(module.getClass());

Map<String, Field> fieldsByName = new HashMap<>();
for (Field f : fields)
fieldsByName.put(f.getName(), f);

for (Field f : fields) {
try {
Hint hint = f.getAnnotation(Hint.class);
if (hint == null)
continue;
f.setAccessible(true);

//Target
Object target = ConfigObjectMapper.getField(module, f);
if (target == null)
continue;

//Flag
String flag = hint.value();
if (!flag.isEmpty() && cfm.getFlag(flag) == !hint.negate())
continue;

//Translation, & gathering extra content
String key = hint.key();
List<Object> extraList = new ArrayList<>(hint.content().length);
for (String c : hint.content()) {
if (c.isEmpty())
continue;

Field extraField = fieldsByName.get(c);
if (extraField == null)
throw new RuntimeException("No field " + c + " referenced in @Hint " + f);

Object yes = ConfigObjectMapper.getField(module, extraField);
extraList.add(yes);
}
Object[] extra = extraList.toArray(new Object[0]);

//Application
if (target instanceof TagKey<?> tkey)
applyTag(tkey, key, extra);
else if (target instanceof Iterable<?> iter)
applyIterable(iter, key, extra);
else
applyObject(target, key, extra);

} catch (Exception e) {
throw new RuntimeException("Problem applying annotation hint " + f.getName() +
" from module " + module.getClass().getName() +
": " + e.getMessage(), e);
}
}
z.loadBus.fire(new InfoRecipeBuilder(registration, z.modid, registryAccess, blacklist), ZGatherHints.class);
}
}

Expand Down

0 comments on commit a5122c6

Please sign in to comment.