mirror of
https://github.com/AlmostReliable/almostunified.git
synced 2024-11-27 10:05:47 -05:00
Recipe Modification Indicator (#8)
Co-authored-by: LLytho <main@lytho.dev>
This commit is contained in:
parent
5e7789795b
commit
a80405d726
30 changed files with 940 additions and 291 deletions
|
@ -582,7 +582,7 @@ ij_json_keep_indents_on_empty_lines = false
|
||||||
ij_json_keep_line_breaks = true
|
ij_json_keep_line_breaks = true
|
||||||
ij_json_space_after_colon = true
|
ij_json_space_after_colon = true
|
||||||
ij_json_space_after_comma = true
|
ij_json_space_after_comma = true
|
||||||
ij_json_space_before_colon = true
|
ij_json_space_before_colon = false
|
||||||
ij_json_space_before_comma = false
|
ij_json_space_before_comma = false
|
||||||
ij_json_spaces_within_braces = false
|
ij_json_spaces_within_braces = false
|
||||||
ij_json_spaces_within_brackets = false
|
ij_json_spaces_within_brackets = false
|
||||||
|
|
|
@ -1,60 +1,57 @@
|
||||||
|
@file:Suppress("UnstableApiUsage")
|
||||||
|
|
||||||
|
val junitVersion: String by project
|
||||||
|
val minecraftVersion: String by project
|
||||||
|
val fabricLoaderVersion: String by project
|
||||||
|
val jeiVersion: String by project
|
||||||
|
val kubejsVersion: String by project
|
||||||
|
val mappingsChannel: String by project
|
||||||
|
val mappingsVersion: String by project
|
||||||
|
val modId: String by project
|
||||||
|
val modName: String by project
|
||||||
|
|
||||||
|
val baseArchiveName = "$modId-common-$minecraftVersion"
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`maven-publish`
|
|
||||||
id("fabric-loom") version "0.12-SNAPSHOT"
|
id("fabric-loom") version "0.12-SNAPSHOT"
|
||||||
id("com.github.gmazzo.buildconfig") version "3.0.3"
|
id("com.github.gmazzo.buildconfig") version "3.0.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
val minecraftVersion: String by project
|
|
||||||
val modName: String by project
|
|
||||||
val modId: String by project
|
|
||||||
val fabricLoaderVersion: String by project
|
|
||||||
val mappingsChannel: String by project
|
|
||||||
val mappingsVersion: String by project
|
|
||||||
val kubejsVersion: String by project
|
|
||||||
val jeiVersion: String by project
|
|
||||||
|
|
||||||
val baseArchiveName = "${modName}-common-${minecraftVersion}"
|
|
||||||
|
|
||||||
base {
|
base {
|
||||||
archivesName.set(baseArchiveName)
|
archivesName.set(baseArchiveName)
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
remapArchives.set(false);
|
shareCaches()
|
||||||
|
remapArchives.set(false)
|
||||||
setupRemappedVariants.set(false);
|
setupRemappedVariants.set(false);
|
||||||
runConfigs.configureEach {
|
runConfigs.configureEach {
|
||||||
ideConfigGenerated(false)
|
ideConfigGenerated(false)
|
||||||
}
|
}
|
||||||
|
mixin {
|
||||||
|
useLegacyMixinAp.set(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft("com.mojang:minecraft:${minecraftVersion}")
|
minecraft("com.mojang:minecraft:$minecraftVersion")
|
||||||
|
modCompileOnly("net.fabricmc:fabric-loader:$fabricLoaderVersion")
|
||||||
mappings(loom.layered {
|
mappings(loom.layered {
|
||||||
officialMojangMappings()
|
officialMojangMappings()
|
||||||
// TODO: change this when updating to 1.19.2
|
// TODO: change this when updating to 1.19.2
|
||||||
parchment("org.parchmentmc.data:${mappingsChannel}-${minecraftVersion}.2:${mappingsVersion}@zip")
|
parchment("org.parchmentmc.data:$mappingsChannel-$minecraftVersion.2:$mappingsVersion@zip")
|
||||||
})
|
})
|
||||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
|
||||||
|
|
||||||
modApi("dev.latvian.mods:kubejs-fabric:${kubejsVersion}")
|
modCompileOnly("mezz.jei:jei-$minecraftVersion-common:$jeiVersion") // required for common jei plugin and mixin
|
||||||
modCompileOnlyApi("mezz.jei:jei-${minecraftVersion}-common-api:${jeiVersion}")
|
modCompileOnly("dev.latvian.mods:kubejs:$kubejsVersion") // required for common kubejs plugin
|
||||||
|
|
||||||
/**
|
// JUnit Tests
|
||||||
* DON'T USE THIS! NEEDED TO COMPILE THIS PROJECT
|
testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
|
||||||
*/
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
|
||||||
modCompileOnly("net.fabricmc:fabric-loader:${fabricLoaderVersion}")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test dependencies
|
|
||||||
*/
|
|
||||||
testImplementation ("org.junit.jupiter:junit-jupiter-api:5.8.1")
|
|
||||||
testRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
withType<Test> {
|
// TODO: test if this is necessary
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
processResources {
|
processResources {
|
||||||
val buildProps = project.properties
|
val buildProps = project.properties
|
||||||
|
|
||||||
|
@ -62,13 +59,15 @@ tasks {
|
||||||
expand(buildProps)
|
expand(buildProps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildConfig {
|
buildConfig {
|
||||||
buildConfigField("String", "MOD_ID", "\"${modId}\"")
|
buildConfigField("String", "MOD_ID", "\"${modId}\"")
|
||||||
buildConfigField("String", "MOD_VERSION", "\"${project.version}\"")
|
buildConfigField("String", "MOD_VERSION", "\"${project.version}\"")
|
||||||
buildConfigField("String", "MOD_NAME", "\"${modName}\"")
|
buildConfigField("String", "MOD_NAME", "\"${modName}\"")
|
||||||
|
|
||||||
packageName(project.group as String)
|
packageName(project.group as String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ public interface AlmostUnifiedPlatform {
|
||||||
*/
|
*/
|
||||||
boolean isDevelopmentEnvironment();
|
boolean isDevelopmentEnvironment();
|
||||||
|
|
||||||
|
boolean isClient();
|
||||||
|
|
||||||
Path getConfigPath();
|
Path getConfigPath();
|
||||||
|
|
||||||
Path getLogPath();
|
Path getLogPath();
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package com.almostreliable.unified.compat;
|
package com.almostreliable.unified.compat;
|
||||||
|
|
||||||
|
|
||||||
import com.almostreliable.unified.AlmostUnifiedPlatform;
|
|
||||||
import com.almostreliable.unified.BuildConfig;
|
import com.almostreliable.unified.BuildConfig;
|
||||||
import com.almostreliable.unified.Platform;
|
|
||||||
import com.almostreliable.unified.config.Config;
|
import com.almostreliable.unified.config.Config;
|
||||||
import com.almostreliable.unified.config.UnifyConfig;
|
import com.almostreliable.unified.config.UnifyConfig;
|
||||||
import mezz.jei.api.IModPlugin;
|
import mezz.jei.api.IModPlugin;
|
||||||
|
@ -25,11 +22,6 @@ public class AlmostJEI implements IModPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRuntimeAvailable(IJeiRuntime jei) {
|
public void onRuntimeAvailable(IJeiRuntime jei) {
|
||||||
var auPlatform = AlmostUnifiedPlatform.INSTANCE;
|
|
||||||
if (auPlatform.getPlatform() == Platform.FABRIC && auPlatform.isModLoaded("roughlyenoughitems")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UnifyConfig config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer());
|
UnifyConfig config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer());
|
||||||
if (config.reiOrJeiDisabled()) {
|
if (config.reiOrJeiDisabled()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.almostreliable.unified.compat;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.recipe.ClientRecipeTracker.ClientRecipeLink;
|
||||||
|
import com.almostreliable.unified.utils.Utils;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import net.minecraft.client.renderer.Rect2i;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class RecipeIndicator {
|
||||||
|
|
||||||
|
public static final int SIZE = 16;
|
||||||
|
private static final ResourceLocation TEXTURE = Utils.getRL("textures/ingot.png");
|
||||||
|
|
||||||
|
private RecipeIndicator() {}
|
||||||
|
|
||||||
|
public static List<Component> constructTooltip(ClientRecipeLink link) {
|
||||||
|
var unified = Component.translatable(Utils.prefix("unified")).append(": ")
|
||||||
|
.withStyle(c -> c.withColor(ChatFormatting.AQUA));
|
||||||
|
unified.append(Component.translatable(Utils.prefix(link.isUnified() ? "yes" : "no"))
|
||||||
|
.withStyle(c -> c.withColor(ChatFormatting.WHITE)));
|
||||||
|
|
||||||
|
var duplicate = Component.translatable(Utils.prefix("duplicate")).append(": ")
|
||||||
|
.withStyle(c -> c.withColor(ChatFormatting.AQUA));
|
||||||
|
duplicate.append(Component.translatable(Utils.prefix(link.isDuplicate() ? "yes" : "no"))
|
||||||
|
.withStyle(c -> c.withColor(ChatFormatting.WHITE)));
|
||||||
|
|
||||||
|
return List.of(
|
||||||
|
Component.translatable(Utils.prefix("description")).withStyle(c -> c.withColor(ChatFormatting.GOLD)),
|
||||||
|
Component.literal(""),
|
||||||
|
unified,
|
||||||
|
duplicate,
|
||||||
|
Component.literal(""),
|
||||||
|
Component.translatable(Utils.prefix("warning")).withStyle(c -> c.withColor(ChatFormatting.RED))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderIndicator(PoseStack poseStack, Rect2i area) {
|
||||||
|
poseStack.pushPose();
|
||||||
|
poseStack.translate(area.getX(), area.getY(), 0);
|
||||||
|
var scale = area.getWidth() / (float) SIZE;
|
||||||
|
poseStack.scale(scale, scale, scale);
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||||
|
RenderSystem.setShaderTexture(0, TEXTURE);
|
||||||
|
GuiComponent.blit(poseStack, 0, 0, 0, 0, SIZE, SIZE, SIZE, SIZE);
|
||||||
|
poseStack.popPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderTooltip(PoseStack poseStack, Rect2i area, int mX, int mY, ClientRecipeLink link) {
|
||||||
|
var screen = Minecraft.getInstance().screen;
|
||||||
|
if (screen == null) return;
|
||||||
|
if (mX >= area.getX() && mX <= area.getX() + area.getWidth() &&
|
||||||
|
mY >= area.getY() && mY <= area.getY() + area.getHeight()) {
|
||||||
|
screen.renderComponentTooltip(poseStack, constructTooltip(link), mX, mY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.almostreliable.unified.mixin;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.AlmostUnifiedPlatform;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||||
|
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class AlmostMixinPlugin implements IMixinConfigPlugin {
|
||||||
|
|
||||||
|
private static final BooleanSupplier TRUE = () -> true;
|
||||||
|
private static final Map<String, BooleanSupplier> CONDITIONS = ImmutableMap.of(
|
||||||
|
"com.almostreliable.unified.mixin.JeiRecipeLayoutMixin", modLoaded("jei")
|
||||||
|
);
|
||||||
|
|
||||||
|
private static BooleanSupplier modLoaded(String id) {
|
||||||
|
return () -> AlmostUnifiedPlatform.INSTANCE.isModLoaded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad(String mixinPackage) {}
|
||||||
|
|
||||||
|
@SuppressWarnings("ReturnOfNull")
|
||||||
|
@Override
|
||||||
|
public String getRefMapperConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||||
|
return CONDITIONS.getOrDefault(mixinClassName, TRUE).getAsBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}
|
||||||
|
|
||||||
|
@SuppressWarnings("ReturnOfNull")
|
||||||
|
@Override
|
||||||
|
public List<String> getMixins() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.almostreliable.unified.mixin;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.compat.RecipeIndicator;
|
||||||
|
import com.almostreliable.unified.recipe.CRTLookup;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import mezz.jei.api.gui.drawable.IDrawable;
|
||||||
|
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||||
|
import mezz.jei.common.gui.recipes.layout.RecipeLayout;
|
||||||
|
import net.minecraft.client.renderer.Rect2i;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
@Mixin(RecipeLayout.class)
|
||||||
|
public abstract class JeiRecipeLayoutMixin<R> {
|
||||||
|
|
||||||
|
@Shadow(remap = false) @Final
|
||||||
|
private static int RECIPE_BORDER_PADDING;
|
||||||
|
@Shadow(remap = false) @Final
|
||||||
|
private IRecipeCategory<R> recipeCategory;
|
||||||
|
@Shadow(remap = false) @Final
|
||||||
|
private R recipe;
|
||||||
|
|
||||||
|
@Inject(method = "drawRecipe", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;pushPose()V", ordinal = 1), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
|
private void unified$drawRecipe(PoseStack stack, int mouseX, int mouseY, CallbackInfo ci, IDrawable background, int mX, int mY, IDrawable categoryBackground, int x, int y) {
|
||||||
|
var recipeId = recipeCategory.getRegistryName(recipe);
|
||||||
|
if (recipeId == null) return;
|
||||||
|
|
||||||
|
var link = CRTLookup.getLink(recipeId);
|
||||||
|
if (link == null) return;
|
||||||
|
|
||||||
|
var posX = x - RecipeIndicator.SIZE / 2 - RECIPE_BORDER_PADDING + 1;
|
||||||
|
var posY = y - RecipeIndicator.SIZE / 2 - RECIPE_BORDER_PADDING + 1;
|
||||||
|
var area = new Rect2i(posX, posY, 10, 10);
|
||||||
|
RecipeIndicator.renderIndicator(stack, area);
|
||||||
|
RecipeIndicator.renderTooltip(stack, area, mX, mY, link);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.almostreliable.unified.recipe;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.BuildConfig;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public final class CRTLookup {
|
||||||
|
|
||||||
|
private CRTLookup() {}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ClientRecipeTracker.ClientRecipeLink getLink(ResourceLocation recipeId) {
|
||||||
|
ResourceLocation linkRecipe = new ResourceLocation(BuildConfig.MOD_ID, recipeId.getNamespace());
|
||||||
|
if (Minecraft.getInstance().level == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Minecraft.getInstance().level
|
||||||
|
.getRecipeManager()
|
||||||
|
.byKey(linkRecipe)
|
||||||
|
.filter(ClientRecipeTracker.class::isInstance)
|
||||||
|
.map(ClientRecipeTracker.class::cast)
|
||||||
|
.map(tracker -> tracker.getLink(recipeId))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,231 @@
|
||||||
|
package com.almostreliable.unified.recipe;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.BuildConfig;
|
||||||
|
import com.almostreliable.unified.utils.Utils;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This recipe is used to track which recipes were unified. It is NOT used for crafting.
|
||||||
|
* Each tracker will hold one namespace with a list of recipes that were unified for it.
|
||||||
|
*/
|
||||||
|
public class ClientRecipeTracker implements Recipe<Container> {
|
||||||
|
public static final ResourceLocation ID = Utils.getRL("client_recipe_tracker");
|
||||||
|
public static final String RECIPES = "recipes";
|
||||||
|
public static final String NAMESPACE = "namespace";
|
||||||
|
public static final int UNIFIED_FLAG = 1;
|
||||||
|
public static final int DUPLICATE_FLAG = 2;
|
||||||
|
public static final RecipeSerializer<ClientRecipeTracker> SERIALIZER = new Serializer();
|
||||||
|
public static final RecipeType<ClientRecipeTracker> TYPE = new RecipeType<>() {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ID.getPath();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final ResourceLocation id;
|
||||||
|
private final Map<ResourceLocation, ClientRecipeLink> recipes = new HashMap<>();
|
||||||
|
private final String namespace;
|
||||||
|
|
||||||
|
protected ClientRecipeTracker(ResourceLocation id, String namespace) {
|
||||||
|
this.id = id;
|
||||||
|
this.namespace = namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a raw string representation.
|
||||||
|
*
|
||||||
|
* @param isUnified Whether the recipe was unified.
|
||||||
|
* @param isDuplicate Whether the recipe had duplicates.
|
||||||
|
* @param idPath The path of the recipe.
|
||||||
|
* @return String representation as: `flag$idPath`
|
||||||
|
*/
|
||||||
|
private static String createRaw(boolean isUnified, boolean isDuplicate, String idPath) {
|
||||||
|
int flag = 0;
|
||||||
|
if (isUnified) flag |= UNIFIED_FLAG;
|
||||||
|
if (isDuplicate) flag |= DUPLICATE_FLAG;
|
||||||
|
return flag + "$" + idPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Default recipe stuff. Ignore this. Forget this.">
|
||||||
|
@Override
|
||||||
|
public boolean matches(Container container, Level level) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack assemble(Container container) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCraftInDimensions(int width, int height) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getResultItem() {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return SERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeType<?> getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(ClientRecipeLink clientRecipeLink) {
|
||||||
|
recipes.put(clientRecipeLink.id(), clientRecipeLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ClientRecipeLink getLink(ResourceLocation recipeId) {
|
||||||
|
return recipes.get(recipeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record ClientRecipeLink(ResourceLocation id, boolean isUnified, boolean isDuplicate) {}
|
||||||
|
|
||||||
|
public static class Serializer implements RecipeSerializer<ClientRecipeTracker> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a recipe from a json file. Recipe will look like this:
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* {
|
||||||
|
* "type": "almostunified:client_recipe_tracker",
|
||||||
|
* "namespace": "minecraft", // The namespace of the recipes.
|
||||||
|
* "recipes": [
|
||||||
|
* "flag$recipePath",
|
||||||
|
* "flag$recipe2Path",
|
||||||
|
* ...
|
||||||
|
* "flag$recipeNPath"
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param recipeId The id of the recipe for the tracker.
|
||||||
|
* @param json The json object.
|
||||||
|
* @return The recipe tracker.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ClientRecipeTracker fromJson(ResourceLocation recipeId, JsonObject json) {
|
||||||
|
String namespace = json.get(NAMESPACE).getAsString();
|
||||||
|
JsonArray recipes = json.get(RECIPES).getAsJsonArray();
|
||||||
|
ClientRecipeTracker tracker = new ClientRecipeTracker(recipeId, namespace);
|
||||||
|
for (JsonElement element : recipes) {
|
||||||
|
ClientRecipeLink clientRecipeLink = parseRaw(namespace, element.getAsString());
|
||||||
|
tracker.add(clientRecipeLink);
|
||||||
|
}
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientRecipeTracker fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
|
||||||
|
int size = buffer.readInt();
|
||||||
|
String namespace = buffer.readUtf();
|
||||||
|
|
||||||
|
ClientRecipeTracker recipe = new ClientRecipeTracker(recipeId, namespace);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
String raw = buffer.readUtf();
|
||||||
|
ClientRecipeLink clientRecipeLink = parseRaw(namespace, raw);
|
||||||
|
recipe.add(clientRecipeLink);
|
||||||
|
}
|
||||||
|
return recipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the tracker to the buffer. The namespace is written separately to save some bytes.
|
||||||
|
* Buffer output will look like:
|
||||||
|
* <pre>
|
||||||
|
* size
|
||||||
|
* namespace
|
||||||
|
* flag$recipePath
|
||||||
|
* flag$recipe2Path
|
||||||
|
* ...
|
||||||
|
* flag$recipeNPath
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param buffer The buffer to write to
|
||||||
|
* @param recipe The recipe to write
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void toNetwork(FriendlyByteBuf buffer, ClientRecipeTracker recipe) {
|
||||||
|
buffer.writeInt(recipe.recipes.size());
|
||||||
|
buffer.writeUtf(recipe.namespace);
|
||||||
|
for (ClientRecipeLink clientRecipeLink : recipe.recipes.values()) {
|
||||||
|
String raw = createRaw(clientRecipeLink.isUnified(),
|
||||||
|
clientRecipeLink.isDuplicate(),
|
||||||
|
clientRecipeLink.id().getPath());
|
||||||
|
buffer.writeUtf(raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link ClientRecipeLink} from a raw string for the given namespace.
|
||||||
|
*
|
||||||
|
* @param namespace The namespace to use.
|
||||||
|
* @param raw The raw string.
|
||||||
|
* @return The client sided recipe link.
|
||||||
|
*/
|
||||||
|
private static ClientRecipeLink parseRaw(String namespace, String raw) {
|
||||||
|
String[] split = raw.split("\\$", 2);
|
||||||
|
int flag = Integer.parseInt(split[0]);
|
||||||
|
boolean isUnified = (flag & UNIFIED_FLAG) != 0;
|
||||||
|
boolean isDuplicate = (flag & DUPLICATE_FLAG) != 0;
|
||||||
|
return new ClientRecipeLink(new ResourceLocation(namespace, split[1]), isUnified, isDuplicate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RawBuilder {
|
||||||
|
|
||||||
|
private final Map<String, JsonArray> recipesByNamespace = new HashMap<>();
|
||||||
|
|
||||||
|
public void add(RecipeLink recipe) {
|
||||||
|
ResourceLocation recipeId = recipe.getId();
|
||||||
|
JsonArray array = recipesByNamespace.computeIfAbsent(recipeId.getNamespace(), k -> new JsonArray());
|
||||||
|
array.add(createRaw(recipe.isUnified(), recipe.hasDuplicateLink(), recipeId.getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a map with the namespace as key and the json recipe.
|
||||||
|
* These recipes are used later in {@link Serializer#fromJson(ResourceLocation, JsonObject)}
|
||||||
|
*
|
||||||
|
* @return The map with the namespace as key and the json recipe.
|
||||||
|
*/
|
||||||
|
public Map<ResourceLocation, JsonObject> compute() {
|
||||||
|
Map<ResourceLocation, JsonObject> result = new HashMap<>();
|
||||||
|
recipesByNamespace.forEach((namespace, recipes) -> {
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.addProperty("type", ID.toString());
|
||||||
|
json.addProperty(NAMESPACE, namespace);
|
||||||
|
json.add(RECIPES, recipes);
|
||||||
|
result.put(new ResourceLocation(BuildConfig.MOD_ID, namespace), json);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,7 +74,7 @@ public class RecipeDumper {
|
||||||
.stream()
|
.stream()
|
||||||
.sorted(Comparator.comparing(r -> r.getId().toString()))
|
.sorted(Comparator.comparing(r -> r.getId().toString()))
|
||||||
.map(r -> "\t\t- " + r.getId() + "\n")
|
.map(r -> "\t\t- " + r.getId() + "\n")
|
||||||
.collect(Collectors.joining("", String.format("\t%s\n", link.getMaster().getDumpInfo()), "\n"));
|
.collect(Collectors.joining("", String.format("\t%s\n", link.getMaster().getId().toString()), "\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dumpOverview(StringBuilder stringBuilder) {
|
private void dumpOverview(StringBuilder stringBuilder) {
|
||||||
|
@ -139,7 +139,7 @@ public class RecipeDumper {
|
||||||
getSortedUnifiedRecipes(type).forEach(recipe -> {
|
getSortedUnifiedRecipes(type).forEach(recipe -> {
|
||||||
stringBuilder
|
stringBuilder
|
||||||
.append("\t- ")
|
.append("\t- ")
|
||||||
.append(recipe.getDumpInfo())
|
.append(recipe.getId().toString())
|
||||||
.append("\n")
|
.append("\n")
|
||||||
.append("\t\t Original: ")
|
.append("\t\t Original: ")
|
||||||
.append(recipe.getOriginal().toString())
|
.append(recipe.getOriginal().toString())
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.almostreliable.unified.recipe;
|
package com.almostreliable.unified.recipe;
|
||||||
|
|
||||||
import com.almostreliable.unified.BuildConfig;
|
|
||||||
import com.almostreliable.unified.utils.JsonCompare;
|
import com.almostreliable.unified.utils.JsonCompare;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
@ -10,6 +9,7 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class RecipeLink {
|
public class RecipeLink {
|
||||||
private final ResourceLocation id;
|
private final ResourceLocation id;
|
||||||
|
@ -165,23 +165,6 @@ public class RecipeLink {
|
||||||
return getUnified() != null ? getUnified() : getOriginal();
|
return getUnified() != null ? getUnified() : getOriginal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceLocation createNewRecipeId() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
if (isUnified()) sb.append("u");
|
|
||||||
if (hasDuplicateLink()) sb.append("d");
|
|
||||||
if (!sb.isEmpty()) sb.append("/");
|
|
||||||
sb.append(getId().getNamespace()).append("/").append(getId().getPath());
|
|
||||||
return new ResourceLocation(BuildConfig.MOD_ID, sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDumpInfo() {
|
|
||||||
if (isUnified() || hasDuplicateLink()) {
|
|
||||||
return getId() + " (Renamed to: " + createNewRecipeId() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
return getId().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class DuplicateLink {
|
public static final class DuplicateLink {
|
||||||
private final Set<RecipeLink> recipes = new HashSet<>();
|
private final Set<RecipeLink> recipes = new HashSet<>();
|
||||||
private RecipeLink currentMaster;
|
private RecipeLink currentMaster;
|
||||||
|
@ -208,6 +191,10 @@ public class RecipeLink {
|
||||||
return Collections.unmodifiableSet(recipes);
|
return Collections.unmodifiableSet(recipes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<RecipeLink> getRecipesWithoutMaster() {
|
||||||
|
return recipes.stream().filter(recipe -> recipe != currentMaster).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Link{currentMaster=" + currentMaster + ", recipes=" + recipes.size() + "}";
|
return "Link{currentMaster=" + currentMaster + ", recipes=" + recipes.size() + "}";
|
||||||
|
|
|
@ -17,7 +17,6 @@ import com.google.gson.JsonPrimitive;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ public class RecipeTransformer {
|
||||||
this.duplicationConfig = duplicationConfig;
|
this.duplicationConfig = duplicationConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasValidType(JsonObject json) {
|
public boolean hasValidRecipeType(JsonObject json) {
|
||||||
if (json.get("type") instanceof JsonPrimitive primitive) {
|
if (json.get("type") instanceof JsonPrimitive primitive) {
|
||||||
ResourceLocation type = ResourceLocation.tryParse(primitive.getAsString());
|
ResourceLocation type = ResourceLocation.tryParse(primitive.getAsString());
|
||||||
return type != null && unifyConfig.includeRecipeType(type);
|
return type != null && unifyConfig.includeRecipeType(type);
|
||||||
|
@ -55,6 +54,7 @@ public class RecipeTransformer {
|
||||||
public Result transformRecipes(Map<ResourceLocation, JsonElement> recipes) {
|
public Result transformRecipes(Map<ResourceLocation, JsonElement> recipes) {
|
||||||
AlmostUnified.LOG.warn("Recipe count: " + recipes.size());
|
AlmostUnified.LOG.warn("Recipe count: " + recipes.size());
|
||||||
|
|
||||||
|
ClientRecipeTracker.RawBuilder tracker = new ClientRecipeTracker.RawBuilder();
|
||||||
Result result = new Result();
|
Result result = new Result();
|
||||||
Map<ResourceLocation, List<RecipeLink>> byType = groupRecipesByType(recipes);
|
Map<ResourceLocation, List<RecipeLink>> byType = groupRecipesByType(recipes);
|
||||||
|
|
||||||
|
@ -65,12 +65,14 @@ public class RecipeTransformer {
|
||||||
recipeLink.getId(),
|
recipeLink.getId(),
|
||||||
json)));
|
json)));
|
||||||
} else {
|
} else {
|
||||||
transformRecipes(recipeLinks, recipes::put, recipes::remove);
|
transformRecipes(recipeLinks, recipes, tracker);
|
||||||
}
|
}
|
||||||
result.addAll(recipeLinks);
|
result.addAll(recipeLinks);
|
||||||
});
|
});
|
||||||
|
|
||||||
AlmostUnified.LOG.warn("Recipe count afterwards: " + recipes.size());
|
AlmostUnified.LOG.warn("Recipe count afterwards: " + recipes.size());
|
||||||
|
Map<ResourceLocation, JsonObject> compute = tracker.compute();
|
||||||
|
recipes.putAll(compute);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,34 +102,26 @@ public class RecipeTransformer {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transformRecipes(List<RecipeLink> recipeLinks, BiConsumer<ResourceLocation, JsonElement> onAdd, Consumer<ResourceLocation> onRemove) {
|
/**
|
||||||
Set<RecipeLink.DuplicateLink> duplicates = new HashSet<>(recipeLinks.size());
|
* Transforms a list of recipes. Part of the transformation is to unify recipes with the given {@link ReplacementMap}.
|
||||||
List<RecipeLink> unified = new ArrayList<>(recipeLinks.size());
|
* After unification, recipes will be checked for duplicates.
|
||||||
for (RecipeLink curRecipe : recipeLinks) {
|
* All duplicates will be removed from <b>{@code Map<ResourceLocation, JsonElement> allRecipes}</b>,
|
||||||
unifyRecipe(curRecipe);
|
* while unified recipes will replace the original recipes in the map.
|
||||||
if (curRecipe.isUnified()) {
|
* <p>
|
||||||
onAdd.accept(curRecipe.getId(), curRecipe.getUnified());
|
* This method will also add the recipes to the given {@link ClientRecipeTracker.RawBuilder}
|
||||||
unified.add(curRecipe);
|
*
|
||||||
}
|
* @param recipeLinks The list of recipes to transform.
|
||||||
}
|
* @param allRecipes The map of all existing recipes.
|
||||||
|
* @param tracker The tracker to add the recipes to.
|
||||||
for (RecipeLink recipeLink : duplicationConfig.isStrictMode() ? recipeLinks : unified) {
|
*/
|
||||||
if (handleDuplicate(recipeLink, recipeLinks) && recipeLink.getDuplicateLink() != null) {
|
private void transformRecipes(List<RecipeLink> recipeLinks, Map<ResourceLocation, JsonElement> allRecipes, ClientRecipeTracker.RawBuilder tracker) {
|
||||||
duplicates.add(recipeLink.getDuplicateLink());
|
var unified = unifyRecipes(recipeLinks, (r) -> allRecipes.put(r.getId(), r.getUnified()));
|
||||||
}
|
var duplicates = handleDuplicates(duplicationConfig.isStrictMode() ? recipeLinks : unified, recipeLinks);
|
||||||
}
|
duplicates
|
||||||
|
.stream()
|
||||||
for (RecipeLink.DuplicateLink link : duplicates) {
|
.flatMap(d -> d.getRecipesWithoutMaster().stream())
|
||||||
link.getRecipes().forEach(recipe -> {
|
.forEach(r -> allRecipes.remove(r.getId()));
|
||||||
onRemove.accept(recipe.getId());
|
unified.forEach(tracker::add);
|
||||||
unified.remove(recipe);
|
|
||||||
});
|
|
||||||
onAdd.accept(link.getMaster().createNewRecipeId(), link.getMaster().getActual());
|
|
||||||
}
|
|
||||||
for (RecipeLink link : unified) {
|
|
||||||
onRemove.accept(link.getId());
|
|
||||||
onAdd.accept(link.createNewRecipeId(), link.getActual());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<ResourceLocation, List<RecipeLink>> groupRecipesByType(Map<ResourceLocation, JsonElement> recipes) {
|
public Map<ResourceLocation, List<RecipeLink>> groupRecipesByType(Map<ResourceLocation, JsonElement> recipes) {
|
||||||
|
@ -139,8 +133,32 @@ public class RecipeTransformer {
|
||||||
.collect(Collectors.groupingByConcurrent(RecipeLink::getType));
|
.collect(Collectors.groupingByConcurrent(RecipeLink::getType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a recipe should be included in the transformation.
|
||||||
|
*
|
||||||
|
* @param recipe The recipe to check.
|
||||||
|
* @param json The recipe's json. Will be used to check if the recipe has a valid type.
|
||||||
|
* @return True if the recipe should be included, false otherwise.
|
||||||
|
*/
|
||||||
private boolean includeRecipe(ResourceLocation recipe, JsonElement json) {
|
private boolean includeRecipe(ResourceLocation recipe, JsonElement json) {
|
||||||
return unifyConfig.includeRecipe(recipe) && json.isJsonObject() && hasValidType(json.getAsJsonObject());
|
return unifyConfig.includeRecipe(recipe) && json.isJsonObject() && hasValidRecipeType(json.getAsJsonObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares a list of recipes against another list for duplicates.
|
||||||
|
*
|
||||||
|
* @param recipeLinks The list of recipes
|
||||||
|
* @param linksToCompare The list of recipes to compare against
|
||||||
|
* @return A list of {@link RecipeLink.DuplicateLink}s containing all duplicates.
|
||||||
|
*/
|
||||||
|
private Set<RecipeLink.DuplicateLink> handleDuplicates(Collection<RecipeLink> recipeLinks, List<RecipeLink> linksToCompare) {
|
||||||
|
Set<RecipeLink.DuplicateLink> duplicates = new HashSet<>(recipeLinks.size());
|
||||||
|
for (RecipeLink recipeLink : recipeLinks) {
|
||||||
|
if (handleDuplicate(recipeLink, linksToCompare) && recipeLink.getDuplicateLink() != null) {
|
||||||
|
duplicates.add(recipeLink.getDuplicateLink());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return duplicates;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleDuplicate(RecipeLink curRecipe, List<RecipeLink> recipes) {
|
private boolean handleDuplicate(RecipeLink curRecipe, List<RecipeLink> recipes) {
|
||||||
|
@ -166,6 +184,25 @@ public class RecipeTransformer {
|
||||||
return foundDuplicate;
|
return foundDuplicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unifies a list of recipes. On unification, {@code Consumer<RecipeLink>} will be called
|
||||||
|
*
|
||||||
|
* @param recipeLinks The list of recipes to unify.
|
||||||
|
* @param onUnified A consumer that will be called on each unified recipe.
|
||||||
|
* @return A list of unified recipes.
|
||||||
|
*/
|
||||||
|
private Set<RecipeLink> unifyRecipes(List<RecipeLink> recipeLinks, Consumer<RecipeLink> onUnified) {
|
||||||
|
Set<RecipeLink> unified = new HashSet<>(recipeLinks.size());
|
||||||
|
for (RecipeLink recipeLink : recipeLinks) {
|
||||||
|
unifyRecipe(recipeLink);
|
||||||
|
if (recipeLink.isUnified()) {
|
||||||
|
onUnified.accept(recipeLink);
|
||||||
|
unified.add(recipeLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unified;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unifies a single recipe link. This method will modify the recipe link in-place.
|
* Unifies a single recipe link. This method will modify the recipe link in-place.
|
||||||
* {@link RecipeHandlerFactory} will apply multiple unification's onto the recipe.
|
* {@link RecipeHandlerFactory} will apply multiple unification's onto the recipe.
|
||||||
|
|
|
@ -24,4 +24,17 @@ public final class Utils {
|
||||||
|
|
||||||
return UnifyTag.item(rl);
|
return UnifyTag.item(rl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T cast(Object o) {
|
||||||
|
return (T) o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceLocation getRL(String path) {
|
||||||
|
return new ResourceLocation(BuildConfig.MOD_ID, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String prefix(String path) {
|
||||||
|
return BuildConfig.MOD_ID + "." + path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
"package": "com.almostreliable.unified.mixin",
|
"package": "com.almostreliable.unified.mixin",
|
||||||
"refmap": "almostunified.refmap.json",
|
"refmap": "almostunified.refmap.json",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
|
"plugin": "com.almostreliable.unified.mixin.AlmostMixinPlugin",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"RecipeManagerMixin",
|
"RecipeManagerMixin",
|
||||||
"ReloadableServerResourcesMixin"
|
"ReloadableServerResourcesMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
"JeiRecipeLayoutMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"almostunified.description": "Modified by Almost Unified!",
|
||||||
|
"almostunified.warning": "Don't report the recipe to the original author.",
|
||||||
|
"almostunified.unified": "Unified",
|
||||||
|
"almostunified.duplicate": "Had Duplicates",
|
||||||
|
"almostunified.yes": "Yes",
|
||||||
|
"almostunified.no": "No"
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 554 B |
|
@ -1,63 +1,31 @@
|
||||||
plugins {
|
@file:Suppress("UnstableApiUsage")
|
||||||
idea
|
|
||||||
`maven-publish`
|
|
||||||
id("fabric-loom") version "0.12-SNAPSHOT"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
val extraModsDirectory: String by project
|
||||||
|
val fabricRecipeViewer: String by project
|
||||||
val minecraftVersion: String by project
|
val minecraftVersion: String by project
|
||||||
val fabricVersion: String by project
|
val fabricVersion: String by project
|
||||||
val fabricLoaderVersion: String by project
|
val fabricLoaderVersion: String by project
|
||||||
val modName: String by project
|
|
||||||
val modId: String by project
|
|
||||||
val mappingsChannel: String by project
|
|
||||||
val mappingsVersion: String by project
|
|
||||||
val extraModsDirectory: String by project
|
|
||||||
val reiVersion: String by project
|
val reiVersion: String by project
|
||||||
val jeiVersion: String by project
|
val jeiVersion: String by project
|
||||||
|
val kubejsVersion: String by project
|
||||||
|
val mappingsChannel: String by project
|
||||||
|
val mappingsVersion: String by project
|
||||||
|
val modId: String by project
|
||||||
|
val modName: String by project
|
||||||
|
|
||||||
val baseArchiveName = "${modId}-fabric-${minecraftVersion}"
|
val baseArchiveName = "$modId-fabric-$minecraftVersion"
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("fabric-loom") version "0.12-SNAPSHOT"
|
||||||
|
}
|
||||||
|
|
||||||
base {
|
base {
|
||||||
archivesName.set(baseArchiveName)
|
archivesName.set(baseArchiveName)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
minecraft("com.mojang:minecraft:${minecraftVersion}")
|
|
||||||
mappings(loom.layered {
|
|
||||||
officialMojangMappings()
|
|
||||||
// TODO: change this when updating to 1.19.2
|
|
||||||
parchment("org.parchmentmc.data:${mappingsChannel}-${minecraftVersion}.2:${mappingsVersion}@zip")
|
|
||||||
})
|
|
||||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
|
||||||
|
|
||||||
modImplementation("net.fabricmc:fabric-loader:${fabricLoaderVersion}")
|
|
||||||
modApi("net.fabricmc.fabric-api:fabric-api:${fabricVersion}")
|
|
||||||
modImplementation("net.fabricmc.fabric-api:fabric-api:${fabricVersion}")
|
|
||||||
|
|
||||||
modCompileOnly("me.shedaniel:RoughlyEnoughItems-api-fabric:${reiVersion}")
|
|
||||||
modRuntimeOnly("me.shedaniel:RoughlyEnoughItems-fabric:${reiVersion}")
|
|
||||||
|
|
||||||
// required to run the fabric client
|
|
||||||
modRuntimeOnly("teamreborn:energy:2.2.0")
|
|
||||||
modCompileOnlyApi("mezz.jei:jei-${minecraftVersion}-common-api:${jeiVersion}")
|
|
||||||
modCompileOnlyApi("mezz.jei:jei-${minecraftVersion}-fabric-api:${jeiVersion}")
|
|
||||||
|
|
||||||
fileTree("$extraModsDirectory-$minecraftVersion") { include("**/*.jar") }
|
|
||||||
.forEach { f ->
|
|
||||||
val sepIndex = f.nameWithoutExtension.lastIndexOf('-');
|
|
||||||
if(sepIndex == -1) {
|
|
||||||
throw IllegalArgumentException("Invalid mod name: ${f.nameWithoutExtension}")
|
|
||||||
}
|
|
||||||
val mod = f.nameWithoutExtension.substring(0, sepIndex);
|
|
||||||
val version = f.nameWithoutExtension.substring(sepIndex + 1);
|
|
||||||
println("Extra mod $mod with version $version detected")
|
|
||||||
modLocalRuntime("$extraModsDirectory:$mod:$version")
|
|
||||||
}
|
|
||||||
|
|
||||||
implementation(project(":Common", "namedElements"))
|
|
||||||
}
|
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
|
shareCaches()
|
||||||
|
|
||||||
runs {
|
runs {
|
||||||
named("client") {
|
named("client") {
|
||||||
client()
|
client()
|
||||||
|
@ -76,19 +44,59 @@ loom {
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
defaultRefmapName.set("${modId}.refmap.json")
|
defaultRefmapName.set("$modId.refmap.json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":Common", "namedElements")) { isTransitive = false }
|
||||||
|
|
||||||
|
minecraft("com.mojang:minecraft:$minecraftVersion")
|
||||||
|
modImplementation("net.fabricmc:fabric-loader:$fabricLoaderVersion")
|
||||||
|
modImplementation("net.fabricmc.fabric-api:fabric-api:$fabricVersion")
|
||||||
|
mappings(loom.layered {
|
||||||
|
officialMojangMappings()
|
||||||
|
// TODO: change this when updating to 1.19.2
|
||||||
|
parchment("org.parchmentmc.data:$mappingsChannel-$minecraftVersion.2:$mappingsVersion@zip")
|
||||||
|
})
|
||||||
|
|
||||||
|
modCompileOnly("me.shedaniel:RoughlyEnoughItems-api-fabric:$reiVersion") // required for fabric rei plugin
|
||||||
|
modCompileOnly("mezz.jei:jei-$minecraftVersion-fabric:$jeiVersion") // required for common jei plugin and mixin
|
||||||
|
// runtime only
|
||||||
|
when (fabricRecipeViewer) {
|
||||||
|
"rei" -> modLocalRuntime("me.shedaniel:RoughlyEnoughItems-fabric:$reiVersion")
|
||||||
|
"jei" -> modLocalRuntime("mezz.jei:jei-$minecraftVersion-fabric:$jeiVersion")
|
||||||
|
else -> throw GradleException("Invalid fabricRecipeViewer value: $fabricRecipeViewer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// required for common kubejs plugin and fabric runtime
|
||||||
|
modCompileOnly(modLocalRuntime("dev.latvian.mods:kubejs-fabric:$kubejsVersion")!!)
|
||||||
|
|
||||||
|
val extraMods = fileTree("$extraModsDirectory-$minecraftVersion") { include("**/*.jar") }
|
||||||
|
if (extraMods.files.isNotEmpty()) {
|
||||||
|
// required when running the fabric client with extra mods
|
||||||
|
modLocalRuntime("teamreborn:energy:2.2.0")
|
||||||
|
}
|
||||||
|
extraMods.forEach { f ->
|
||||||
|
val sepIndex = f.nameWithoutExtension.lastIndexOf('-')
|
||||||
|
if (sepIndex == -1) {
|
||||||
|
throw IllegalArgumentException("Invalid mod name: ${f.nameWithoutExtension}")
|
||||||
|
}
|
||||||
|
val mod = f.nameWithoutExtension.substring(0, sepIndex)
|
||||||
|
val version = f.nameWithoutExtension.substring(sepIndex + 1)
|
||||||
|
println("Extra mod $mod with version $version detected")
|
||||||
|
modLocalRuntime("$extraModsDirectory:$mod:$version")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
// TODO: test if this is necessary
|
||||||
jar {
|
jar {
|
||||||
from("LICENSE") {
|
from("LICENSE") {
|
||||||
rename { "${it}_${modName}" }
|
rename { "${it}_${modName}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
withType<JavaCompile> {
|
// TODO: test if this is necessary
|
||||||
source(project(":Common").sourceSets.main.get().allSource)
|
|
||||||
}
|
|
||||||
processResources {
|
processResources {
|
||||||
from(project(":Common").sourceSets.main.get().resources)
|
from(project(":Common").sourceSets.main.get().resources)
|
||||||
inputs.property("version", project.version)
|
inputs.property("version", project.version)
|
||||||
|
@ -97,6 +105,9 @@ tasks {
|
||||||
expand("version" to project.version)
|
expand("version" to project.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
withType<JavaCompile> {
|
||||||
|
source(project(":Common").sourceSets.main.get().allSource)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package com.almostreliable.unified;
|
package com.almostreliable.unified;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.recipe.ClientRecipeTracker;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
|
||||||
public class AlmostUnifiedFabric implements ModInitializer {
|
public class AlmostUnifiedFabric implements ModInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
Registry.register(Registry.RECIPE_SERIALIZER, ClientRecipeTracker.ID, ClientRecipeTracker.SERIALIZER);
|
||||||
|
Registry.register(Registry.RECIPE_TYPE, ClientRecipeTracker.ID, ClientRecipeTracker.TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.almostreliable.unified;
|
package com.almostreliable.unified;
|
||||||
|
|
||||||
import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory;
|
import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -22,6 +23,11 @@ public class AlmostUnifiedPlatformFabric implements AlmostUnifiedPlatform {
|
||||||
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClient() {
|
||||||
|
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getConfigPath() {
|
public Path getConfigPath() {
|
||||||
return FabricLoader.getInstance().getConfigDir().resolve(BuildConfig.MOD_ID);
|
return FabricLoader.getInstance().getConfigDir().resolve(BuildConfig.MOD_ID);
|
||||||
|
|
|
@ -1,24 +1,96 @@
|
||||||
package com.almostreliable.unified.compat;
|
package com.almostreliable.unified.compat;
|
||||||
|
|
||||||
import com.almostreliable.unified.AlmostUnifiedPlatform;
|
|
||||||
import com.almostreliable.unified.config.Config;
|
import com.almostreliable.unified.config.Config;
|
||||||
import com.almostreliable.unified.config.UnifyConfig;
|
import com.almostreliable.unified.config.UnifyConfig;
|
||||||
|
import com.almostreliable.unified.recipe.CRTLookup;
|
||||||
|
import com.almostreliable.unified.recipe.ClientRecipeTracker.ClientRecipeLink;
|
||||||
|
import com.almostreliable.unified.utils.Utils;
|
||||||
|
import me.shedaniel.math.Rectangle;
|
||||||
|
import me.shedaniel.rei.api.client.gui.DisplayRenderer;
|
||||||
|
import me.shedaniel.rei.api.client.gui.widgets.Widget;
|
||||||
|
import me.shedaniel.rei.api.client.gui.widgets.Widgets;
|
||||||
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
|
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
|
||||||
|
import me.shedaniel.rei.api.client.registry.category.ButtonArea;
|
||||||
|
import me.shedaniel.rei.api.client.registry.category.CategoryRegistry;
|
||||||
|
import me.shedaniel.rei.api.client.registry.category.extension.CategoryExtensionProvider;
|
||||||
|
import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
|
||||||
|
import me.shedaniel.rei.api.client.registry.display.DisplayCategoryView;
|
||||||
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
|
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
|
||||||
|
import me.shedaniel.rei.api.common.display.Display;
|
||||||
|
import me.shedaniel.rei.api.common.plugins.PluginManager;
|
||||||
|
import me.shedaniel.rei.api.common.registry.ReloadStage;
|
||||||
import me.shedaniel.rei.api.common.util.EntryStacks;
|
import me.shedaniel.rei.api.common.util.EntryStacks;
|
||||||
|
import net.minecraft.client.renderer.Rect2i;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
public class AlmostREI implements REIClientPlugin {
|
public class AlmostREI implements REIClientPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerEntries(EntryRegistry registry) {
|
public void registerEntries(EntryRegistry registry) {
|
||||||
if (AlmostUnifiedPlatform.INSTANCE.isModLoaded("jei")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UnifyConfig config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer());
|
UnifyConfig config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer());
|
||||||
if(config.reiOrJeiDisabled()) {
|
if (config.reiOrJeiDisabled()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HideHelper.createHidingList(config).stream().map(EntryStacks::of).forEach(registry::removeEntry);
|
HideHelper.createHidingList(config).stream().map(EntryStacks::of).forEach(registry::removeEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postStage(PluginManager<REIClientPlugin> manager, ReloadStage stage) {
|
||||||
|
if (stage != ReloadStage.END || !manager.equals(PluginManager.getClientInstance())) return;
|
||||||
|
CategoryRegistry.getInstance().forEach(category -> {
|
||||||
|
IndicatorExtension extension = new IndicatorExtension(category.getPlusButtonArea().orElse(null));
|
||||||
|
category.registerExtension(Utils.cast(extension));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("OverrideOnly")
|
||||||
|
private record IndicatorExtension(@Nullable ButtonArea plusButtonArea)
|
||||||
|
implements CategoryExtensionProvider<Display> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DisplayCategoryView<Display> provide(Display display, DisplayCategory<Display> category, DisplayCategoryView<Display> lastView) {
|
||||||
|
return display
|
||||||
|
.getDisplayLocation()
|
||||||
|
.map(CRTLookup::getLink)
|
||||||
|
.map(link -> (DisplayCategoryView<Display>) new IndicatorView(lastView, link))
|
||||||
|
.orElse(lastView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class IndicatorView implements DisplayCategoryView<Display> {
|
||||||
|
|
||||||
|
private final DisplayCategoryView<Display> lastView;
|
||||||
|
private final ClientRecipeLink link;
|
||||||
|
|
||||||
|
private IndicatorView(DisplayCategoryView<Display> lastView, ClientRecipeLink link) {
|
||||||
|
this.lastView = lastView;
|
||||||
|
this.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DisplayRenderer getDisplayRenderer(Display display) {
|
||||||
|
return lastView.getDisplayRenderer(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Widget> setupDisplay(Display display, Rectangle bounds) {
|
||||||
|
var widgets = lastView.setupDisplay(display, bounds);
|
||||||
|
var area = calculateArea(bounds);
|
||||||
|
widgets.add(Widgets.createDrawableWidget((helper, stack, mX, mY, delta) ->
|
||||||
|
RecipeIndicator.renderIndicator(stack, area)));
|
||||||
|
var tooltipArea = new Rectangle(area.getX(), area.getY(), area.getWidth(), area.getHeight());
|
||||||
|
widgets.add(Widgets.createTooltip(tooltipArea, RecipeIndicator.constructTooltip(link)));
|
||||||
|
return widgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect2i calculateArea(Rectangle bounds) {
|
||||||
|
if (plusButtonArea != null) {
|
||||||
|
var area = plusButtonArea.get(bounds);
|
||||||
|
return new Rect2i(area.x, area.y - area.height - 2, area.width, area.height);
|
||||||
|
}
|
||||||
|
return new Rect2i(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,127 +1,127 @@
|
||||||
plugins {
|
@file:Suppress("UnstableApiUsage")
|
||||||
java
|
|
||||||
eclipse
|
|
||||||
`maven-publish`
|
|
||||||
id("net.minecraftforge.gradle") version ("5.1.+")
|
|
||||||
id("org.parchmentmc.librarian.forgegradle") version ("1.+")
|
|
||||||
id("org.spongepowered.mixin") version ("0.7.+")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
val junitVersion: String by project
|
||||||
|
val extraModsDirectory: String by project
|
||||||
|
val forgeRecipeViewer: String by project
|
||||||
val minecraftVersion: String by project
|
val minecraftVersion: String by project
|
||||||
val mixinVersion: String by project
|
|
||||||
val forgeVersion: String by project
|
val forgeVersion: String by project
|
||||||
val modId: String by project
|
val reiVersion: String by project
|
||||||
|
val jeiVersion: String by project
|
||||||
|
val kubejsVersion: String by project
|
||||||
val mappingsChannel: String by project
|
val mappingsChannel: String by project
|
||||||
val mappingsVersion: String by project
|
val mappingsVersion: String by project
|
||||||
val extraModsDirectory: String by project
|
val modId: String by project
|
||||||
val jeiVersion: String by project
|
val modName: String by project
|
||||||
|
|
||||||
val baseArchiveName = "${modId}-forge-${minecraftVersion}"
|
val baseArchiveName = "$modId-forge-$minecraftVersion"
|
||||||
|
val commonTests: SourceSetOutput = project(":Common").sourceSets["test"].output
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("dev.architectury.loom") version "0.12.0-SNAPSHOT"
|
||||||
|
}
|
||||||
|
|
||||||
base {
|
base {
|
||||||
archivesName.set(baseArchiveName)
|
archivesName.set(baseArchiveName)
|
||||||
}
|
}
|
||||||
|
|
||||||
minecraft {
|
loom {
|
||||||
// TODO: change this when updating to 1.19.2
|
shareCaches()
|
||||||
mappings(mappingsChannel, "1.18.2-${mappingsVersion}-${minecraftVersion}")
|
silentMojangMappingsLicense()
|
||||||
|
|
||||||
runs {
|
runs {
|
||||||
create("client") {
|
named("client") {
|
||||||
workingDirectory(project.file("run"))
|
client()
|
||||||
ideaModule("${rootProject.name}.${project.name}.main")
|
configName = "Forge Client"
|
||||||
taskName("Client")
|
ideConfigGenerated(true)
|
||||||
property("mixin.env.remapRefMap", "true")
|
runDir("run")
|
||||||
property("mixin.env.refMapRemappingFile", "${projectDir}/build/createSrgToMcp/output.srg")
|
vmArgs("-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AllowEnhancedClassRedefinition")
|
||||||
jvmArg("-XX:+IgnoreUnrecognizedVMOptions")
|
|
||||||
jvmArg("-XX:+AllowEnhancedClassRedefinition")
|
|
||||||
mods {
|
|
||||||
create(modId) {
|
|
||||||
source(sourceSets.main.get())
|
|
||||||
source(project(":Common").sourceSets.main.get())
|
|
||||||
}
|
}
|
||||||
|
named("server") {
|
||||||
|
server()
|
||||||
|
configName = "Forge Server"
|
||||||
|
ideConfigGenerated(true)
|
||||||
|
runDir("run")
|
||||||
|
vmArgs("-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AllowEnhancedClassRedefinition")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
create("server") {
|
forge {
|
||||||
workingDirectory(project.file("run"))
|
mixinConfig("$modId-common.mixins.json")
|
||||||
ideaModule("${rootProject.name}.${project.name}.main")
|
|
||||||
taskName("Server")
|
|
||||||
property("mixin.env.remapRefMap", "true")
|
|
||||||
property("mixin.env.refMapRemappingFile", "${projectDir}/build/createSrgToMcp/output.srg")
|
|
||||||
jvmArg("-XX:+IgnoreUnrecognizedVMOptions")
|
|
||||||
jvmArg("-XX:+AllowEnhancedClassRedefinition")
|
|
||||||
mods {
|
|
||||||
create(modId) {
|
|
||||||
source(sourceSets.main.get())
|
|
||||||
source(project(":Common").sourceSets.main.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets.main.get().resources.srcDir("src/generated/resources")
|
|
||||||
|
|
||||||
// from millions of solutions, this is the only one which works... :-)
|
|
||||||
val commonTests: SourceSetOutput = project(":Common").sourceSets["test"].output
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
minecraft("net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}")
|
|
||||||
compileOnly(project(":Common"))
|
|
||||||
|
|
||||||
compileOnly(fg.deobf("mezz.jei:jei-${minecraftVersion}-common-api:${jeiVersion}"))
|
|
||||||
compileOnly(fg.deobf("mezz.jei:jei-${minecraftVersion}-forge-api:${jeiVersion}"))
|
|
||||||
runtimeOnly(fg.deobf("mezz.jei:jei-${minecraftVersion}-forge:${jeiVersion}"))
|
|
||||||
|
|
||||||
fileTree("$extraModsDirectory-$minecraftVersion") { include("**/*.jar") }
|
|
||||||
.forEach { f ->
|
|
||||||
val sepIndex = f.nameWithoutExtension.lastIndexOf('-');
|
|
||||||
if(sepIndex == -1) {
|
|
||||||
throw IllegalArgumentException("Invalid mod name: ${f.nameWithoutExtension}")
|
|
||||||
}
|
|
||||||
val mod = f.nameWithoutExtension.substring(0, sepIndex);
|
|
||||||
val version = f.nameWithoutExtension.substring(sepIndex + 1);
|
|
||||||
println("Extra mod $mod with version $version detected")
|
|
||||||
runtimeOnly(fg.deobf("$extraModsDirectory:$mod:$version"))
|
|
||||||
}
|
|
||||||
|
|
||||||
annotationProcessor("org.spongepowered:mixin:${mixinVersion}:processor")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test dependencies
|
|
||||||
*/
|
|
||||||
testImplementation(project(":Common"))
|
|
||||||
testImplementation(commonTests)
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
|
|
||||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
add(sourceSets.main.get(), "${modId}.refmap.json")
|
defaultRefmapName.set("$modId.refmap.json")
|
||||||
config("${modId}-common.mixins.json")
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":Common", "namedElements")) { isTransitive = false }
|
||||||
|
|
||||||
|
minecraft("com.mojang:minecraft:$minecraftVersion")
|
||||||
|
forge("net.minecraftforge:forge:$minecraftVersion-$forgeVersion")
|
||||||
|
mappings(loom.layered {
|
||||||
|
officialMojangMappings()
|
||||||
|
// TODO: change this when updating to 1.19.2
|
||||||
|
parchment("org.parchmentmc.data:$mappingsChannel-$minecraftVersion.2:$mappingsVersion@zip")
|
||||||
|
})
|
||||||
|
|
||||||
|
modCompileOnly("me.shedaniel:RoughlyEnoughItems-forge:$reiVersion") // required for forge rei plugin | api does not work here!
|
||||||
|
modCompileOnly("mezz.jei:jei-$minecraftVersion-forge:$jeiVersion") // required for common jei plugin and mixin
|
||||||
|
// runtime only
|
||||||
|
when (forgeRecipeViewer) {
|
||||||
|
"rei" -> modLocalRuntime("me.shedaniel:RoughlyEnoughItems-forge:$reiVersion")
|
||||||
|
"jei" -> modLocalRuntime("mezz.jei:jei-$minecraftVersion-forge:$jeiVersion")
|
||||||
|
else -> throw GradleException("Invalid forgeRecipeViewer value: $forgeRecipeViewer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// required for common kubejs plugin and forge runtime
|
||||||
|
modCompileOnly(modLocalRuntime("dev.latvian.mods:kubejs-forge:$kubejsVersion")!!)
|
||||||
|
|
||||||
|
fileTree("$extraModsDirectory-$minecraftVersion") { include("**/*.jar") }
|
||||||
|
.forEach { f ->
|
||||||
|
val sepIndex = f.nameWithoutExtension.lastIndexOf('-')
|
||||||
|
if (sepIndex == -1) {
|
||||||
|
throw IllegalArgumentException("Invalid mod name: ${f.nameWithoutExtension}")
|
||||||
|
}
|
||||||
|
val mod = f.nameWithoutExtension.substring(0, sepIndex)
|
||||||
|
val version = f.nameWithoutExtension.substring(sepIndex + 1)
|
||||||
|
println("Extra mod $mod with version $version detected")
|
||||||
|
modLocalRuntime("$extraModsDirectory:$mod:$version")
|
||||||
|
}
|
||||||
|
|
||||||
|
// JUnit Tests
|
||||||
|
testImplementation(project(":Common"))
|
||||||
|
testImplementation(commonTests)
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
|
||||||
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
// TODO: test if this is necessary
|
||||||
jar {
|
jar {
|
||||||
finalizedBy("reobfJar")
|
from("LICENSE") {
|
||||||
|
rename { "${it}_${modName}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: test if this is necessary
|
||||||
|
processResources {
|
||||||
|
from(project(":Common").sourceSets.main.get().resources)
|
||||||
|
inputs.property("version", project.version)
|
||||||
|
|
||||||
|
filesMatching("META-INF/mods.toml") {
|
||||||
|
expand("version" to project.version)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
withType<JavaCompile> {
|
withType<JavaCompile> {
|
||||||
source(project(":Common").sourceSets.main.get().allSource)
|
source(project(":Common").sourceSets.main.get().allSource)
|
||||||
}
|
}
|
||||||
withType<Test> {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
processResources {
|
|
||||||
from(project(":Common").sourceSets.main.get().resources)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
register("mavenJava", MavenPublication::class) {
|
register("mavenJava", MavenPublication::class) {
|
||||||
artifactId = baseArchiveName
|
artifactId = baseArchiveName
|
||||||
artifact(tasks.jar)
|
from(components["java"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
Forge/gradle.properties
Normal file
1
Forge/gradle.properties
Normal file
|
@ -0,0 +1 @@
|
||||||
|
loom.platform = forge
|
|
@ -1,12 +1,24 @@
|
||||||
package com.almostreliable.unified;
|
package com.almostreliable.unified;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.recipe.ClientRecipeTracker;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.RegisterEvent;
|
||||||
|
|
||||||
@Mod(BuildConfig.MOD_ID)
|
@Mod(BuildConfig.MOD_ID)
|
||||||
public class AlmostUnifiedForge {
|
public class AlmostUnifiedForge {
|
||||||
|
|
||||||
public AlmostUnifiedForge() {
|
public AlmostUnifiedForge() {
|
||||||
|
var modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
modEventBus.addListener((RegisterEvent event) -> {
|
||||||
|
if (event.getRegistryKey().equals(Registry.RECIPE_SERIALIZER_REGISTRY)) {
|
||||||
|
ForgeRegistries.RECIPE_SERIALIZERS.register(ClientRecipeTracker.ID, ClientRecipeTracker.SERIALIZER);
|
||||||
|
}
|
||||||
|
if (event.getRegistryKey().equals(Registry.RECIPE_TYPE_REGISTRY)) {
|
||||||
|
ForgeRegistries.RECIPE_TYPES.register(ClientRecipeTracker.ID, ClientRecipeTracker.TYPE);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,12 @@ package com.almostreliable.unified;
|
||||||
import com.almostreliable.unified.api.ModConstants;
|
import com.almostreliable.unified.api.ModConstants;
|
||||||
import com.almostreliable.unified.compat.IERecipeUnifier;
|
import com.almostreliable.unified.compat.IERecipeUnifier;
|
||||||
import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory;
|
import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
import net.minecraftforge.fml.loading.FMLPaths;
|
import net.minecraftforge.fml.loading.FMLPaths;
|
||||||
|
import net.minecraftforge.fml.loading.LoadingModList;
|
||||||
|
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
@ -18,6 +21,9 @@ public class AlmostUnifiedPlatformForge implements AlmostUnifiedPlatform {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isModLoaded(String modId) {
|
public boolean isModLoaded(String modId) {
|
||||||
|
if (ModList.get() == null) {
|
||||||
|
return LoadingModList.get().getMods().stream().map(ModInfo::getModId).anyMatch(modId::equals);
|
||||||
|
}
|
||||||
return ModList.get().isLoaded(modId);
|
return ModList.get().isLoaded(modId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +32,11 @@ public class AlmostUnifiedPlatformForge implements AlmostUnifiedPlatform {
|
||||||
return !FMLLoader.isProduction();
|
return !FMLLoader.isProduction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClient() {
|
||||||
|
return FMLLoader.getDist() == Dist.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getConfigPath() {
|
public Path getConfigPath() {
|
||||||
return FMLPaths.CONFIGDIR.get().resolve(BuildConfig.MOD_ID);
|
return FMLPaths.CONFIGDIR.get().resolve(BuildConfig.MOD_ID);
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.almostreliable.unified.compat;
|
||||||
|
|
||||||
|
import com.almostreliable.unified.recipe.CRTLookup;
|
||||||
|
import com.almostreliable.unified.recipe.ClientRecipeTracker;
|
||||||
|
import com.almostreliable.unified.utils.Utils;
|
||||||
|
import me.shedaniel.math.Rectangle;
|
||||||
|
import me.shedaniel.rei.api.client.gui.DisplayRenderer;
|
||||||
|
import me.shedaniel.rei.api.client.gui.widgets.Widget;
|
||||||
|
import me.shedaniel.rei.api.client.gui.widgets.Widgets;
|
||||||
|
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
|
||||||
|
import me.shedaniel.rei.api.client.registry.category.ButtonArea;
|
||||||
|
import me.shedaniel.rei.api.client.registry.category.CategoryRegistry;
|
||||||
|
import me.shedaniel.rei.api.client.registry.category.extension.CategoryExtensionProvider;
|
||||||
|
import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
|
||||||
|
import me.shedaniel.rei.api.client.registry.display.DisplayCategoryView;
|
||||||
|
import me.shedaniel.rei.api.common.display.Display;
|
||||||
|
import me.shedaniel.rei.api.common.plugins.PluginManager;
|
||||||
|
import me.shedaniel.rei.api.common.registry.ReloadStage;
|
||||||
|
import me.shedaniel.rei.forge.REIPlugin;
|
||||||
|
import net.minecraft.client.renderer.Rect2i;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@REIPlugin(Dist.CLIENT)
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public class AlmostREI implements REIClientPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postStage(PluginManager<REIClientPlugin> manager, ReloadStage stage) {
|
||||||
|
if (stage != ReloadStage.END || !manager.equals(PluginManager.getClientInstance())) return;
|
||||||
|
CategoryRegistry.getInstance().forEach(category -> {
|
||||||
|
IndicatorExtension extension = new IndicatorExtension(category.getPlusButtonArea().orElse(null));
|
||||||
|
category.registerExtension(Utils.cast(extension));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("OverrideOnly")
|
||||||
|
private record IndicatorExtension(@Nullable ButtonArea plusButtonArea)
|
||||||
|
implements CategoryExtensionProvider<Display> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DisplayCategoryView<Display> provide(Display display, DisplayCategory<Display> category, DisplayCategoryView<Display> lastView) {
|
||||||
|
return display
|
||||||
|
.getDisplayLocation()
|
||||||
|
.map(CRTLookup::getLink)
|
||||||
|
.map(link -> (DisplayCategoryView<Display>) new IndicatorView(lastView, link))
|
||||||
|
.orElse(lastView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class IndicatorView implements DisplayCategoryView<Display> {
|
||||||
|
|
||||||
|
private final DisplayCategoryView<Display> lastView;
|
||||||
|
private final ClientRecipeTracker.ClientRecipeLink link;
|
||||||
|
|
||||||
|
private IndicatorView(DisplayCategoryView<Display> lastView, ClientRecipeTracker.ClientRecipeLink link) {
|
||||||
|
this.lastView = lastView;
|
||||||
|
this.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DisplayRenderer getDisplayRenderer(Display display) {
|
||||||
|
return lastView.getDisplayRenderer(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Widget> setupDisplay(Display display, Rectangle bounds) {
|
||||||
|
var widgets = lastView.setupDisplay(display, bounds);
|
||||||
|
var area = calculateArea(bounds);
|
||||||
|
widgets.add(Widgets.createDrawableWidget((helper, stack, mX, mY, delta) ->
|
||||||
|
RecipeIndicator.renderIndicator(stack, area)));
|
||||||
|
var tooltipArea = new Rectangle(area.getX(), area.getY(), area.getWidth(), area.getHeight());
|
||||||
|
widgets.add(Widgets.createTooltip(tooltipArea, RecipeIndicator.constructTooltip(link)));
|
||||||
|
return widgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rect2i calculateArea(Rectangle bounds) {
|
||||||
|
if (plusButtonArea != null) {
|
||||||
|
var area = plusButtonArea.get(bounds);
|
||||||
|
return new Rect2i(area.x, area.y - area.height - 2, area.width, area.height);
|
||||||
|
}
|
||||||
|
return new Rect2i(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,51 +2,39 @@ import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val license: String by project
|
val license: String by project
|
||||||
|
val extraModsDirectory: String by project
|
||||||
val minecraftVersion: String by project
|
val minecraftVersion: String by project
|
||||||
|
val forgeMinVersion: String by project
|
||||||
val modId: String by project
|
val modId: String by project
|
||||||
val modName: String by project
|
val modName: String by project
|
||||||
val modAuthor: String by project
|
val modAuthor: String by project
|
||||||
val modDescription: String by project
|
val modDescription: String by project
|
||||||
val forgeMinVersion: String by project
|
|
||||||
val extraModsDirectory: String by project
|
|
||||||
val githubUser: String by project
|
val githubUser: String by project
|
||||||
val githubRepo: String by project
|
val githubRepo: String by project
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
idea
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
subprojects {
|
||||||
|
apply(plugin = "maven-publish")
|
||||||
|
apply(plugin = "java")
|
||||||
|
apply(plugin = "eclipse")
|
||||||
|
apply(plugin = "idea")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
maven("https://maven.parchmentmc.org/")
|
||||||
|
maven("https://maven.shedaniel.me")
|
||||||
|
maven("https://dvs1.progwml6.com/files/maven/")
|
||||||
|
maven("https://maven.saps.dev/minecraft")
|
||||||
flatDir {
|
flatDir {
|
||||||
name = extraModsDirectory
|
name = extraModsDirectory
|
||||||
dir(file("$extraModsDirectory-$minecraftVersion"))
|
dir(file("$extraModsDirectory-$minecraftVersion"))
|
||||||
}
|
}
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
maven("https://repo.spongepowered.org/repository/maven-public/")
|
|
||||||
maven("https://maven.shedaniel.me")
|
|
||||||
maven("https://dvs1.progwml6.com/files/maven/")
|
|
||||||
maven("https://maven.saps.dev/minecraft") {
|
|
||||||
content {
|
|
||||||
includeGroup("dev.latvian.mods")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<GenerateModuleMetadata> {
|
|
||||||
enabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
apply(plugin = "java")
|
|
||||||
|
|
||||||
extensions.configure<JavaPluginExtension> {
|
extensions.configure<JavaPluginExtension> {
|
||||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
withJavadocJar()
|
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,22 +55,18 @@ subprojects {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
withType<JavaCompile> {
|
|
||||||
options.encoding = "UTF-8"
|
|
||||||
options.release.set(17)
|
|
||||||
}
|
|
||||||
processResources {
|
processResources {
|
||||||
val resourceTargets = listOf("META-INF/mods.toml", "pack.mcmeta", "fabric.mod.json")
|
val resourceTargets = listOf("META-INF/mods.toml", "pack.mcmeta", "fabric.mod.json")
|
||||||
|
|
||||||
val replaceProperties = mapOf(
|
val replaceProperties = mapOf(
|
||||||
"version" to project.version as String,
|
"version" to project.version as String,
|
||||||
"license" to license,
|
"license" to license,
|
||||||
|
"minecraftVersion" to minecraftVersion,
|
||||||
|
"forgeMinVersion" to forgeMinVersion,
|
||||||
"modId" to modId,
|
"modId" to modId,
|
||||||
"modName" to modName,
|
"modName" to modName,
|
||||||
"minecraftVersion" to minecraftVersion,
|
|
||||||
"modAuthor" to modAuthor,
|
"modAuthor" to modAuthor,
|
||||||
"modDescription" to modDescription,
|
"modDescription" to modDescription,
|
||||||
"forgeMinVersion" to forgeMinVersion,
|
|
||||||
"githubUser" to githubUser,
|
"githubUser" to githubUser,
|
||||||
"githubRepo" to githubRepo
|
"githubRepo" to githubRepo
|
||||||
)
|
)
|
||||||
|
@ -92,5 +76,12 @@ subprojects {
|
||||||
expand(replaceProperties)
|
expand(replaceProperties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
withType<JavaCompile> {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
options.release.set(17)
|
||||||
|
}
|
||||||
|
withType<GenerateModuleMetadata> {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,12 @@
|
||||||
version = 0.0.8
|
version = 0.0.8
|
||||||
group = com.almostreliable.unified
|
group = com.almostreliable.unified
|
||||||
license = LGPL-3.0
|
license = LGPL-3.0
|
||||||
mixinVersion = 0.8.5
|
junitVersion = 5.9.0
|
||||||
|
|
||||||
|
# Runtime Settings
|
||||||
|
extraModsDirectory = extra-mods
|
||||||
|
forgeRecipeViewer = rei
|
||||||
|
fabricRecipeViewer = jei
|
||||||
|
|
||||||
# Common
|
# Common
|
||||||
minecraftVersion = 1.19
|
minecraftVersion = 1.19
|
||||||
|
@ -16,16 +21,15 @@ fabricVersion = 0.58.0+1.19
|
||||||
fabricLoaderVersion = 0.14.9
|
fabricLoaderVersion = 0.14.9
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
extraModsDirectory = extra-mods
|
|
||||||
reiVersion = 9.1.537
|
reiVersion = 9.1.537
|
||||||
jeiVersion = 11+
|
jeiVersion = 11.1.1.239
|
||||||
kubejsVersion = 1900.5.5-build.27
|
kubejsVersion = 1900.5.5-build.27
|
||||||
|
|
||||||
# Mappings
|
# Mappings
|
||||||
mappingsChannel = parchment
|
mappingsChannel = parchment
|
||||||
mappingsVersion = 2022.09.04
|
mappingsVersion = 2022.09.04
|
||||||
|
|
||||||
# Mod options
|
# Mod Info
|
||||||
modId = almostunified
|
modId = almostunified
|
||||||
modName = AlmostUnified
|
modName = AlmostUnified
|
||||||
modAuthor = AlmostReliable
|
modAuthor = AlmostReliable
|
||||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
|
@ -1,26 +1,15 @@
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
|
maven("https://maven.fabricmc.net/")
|
||||||
|
maven("https://maven.minecraftforge.net/")
|
||||||
|
maven("https://maven.architectury.dev/")
|
||||||
|
maven("https://repo.spongepowered.org/repository/maven-public/")
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
maven("https://maven.fabricmc.net/") {
|
mavenCentral()
|
||||||
name = "Fabric"
|
mavenLocal()
|
||||||
}
|
|
||||||
maven("https://repo.spongepowered.org/repository/maven-public/") {
|
|
||||||
name = "Sponge Snapshots"
|
|
||||||
}
|
|
||||||
maven("https://maven.minecraftforge.net") {
|
|
||||||
name = "Forge"
|
|
||||||
}
|
|
||||||
maven("https://maven.parchmentmc.org") {
|
|
||||||
name = "ParchmentMC"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
resolutionStrategy {
|
resolutionStrategy {
|
||||||
eachPlugin {
|
eachPlugin {
|
||||||
// If we request Forge, actually give it the correct artifact.
|
|
||||||
if (requested.id.id == "net.minecraftforge.gradle") {
|
|
||||||
useModule("${requested.id}:ForgeGradle:${requested.version}")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requested.id.id == "org.spongepowered.mixin") {
|
if (requested.id.id == "org.spongepowered.mixin") {
|
||||||
useModule("org.spongepowered:mixingradle:${requested.version}")
|
useModule("org.spongepowered:mixingradle:${requested.version}")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue