updating
This commit is contained in:
parent
98067cbba9
commit
761a841b2c
@ -161,6 +161,8 @@ dependencies {
|
||||
runtimeOnly fg.deobf("blank:tetracelium-1.20.1-1.3.1")
|
||||
runtimeOnly fg.deobf("blank:supplementaries-1.20-3.1.36")
|
||||
compileOnly fg.deobf("vazkii.botania:Botania:1.20.1-450-FORGE:api")
|
||||
runtimeOnly fg.deobf("blank:autohud-8.7+1.20.1-forge")
|
||||
runtimeOnly fg.deobf("blank:forgeskyboxes-0.0.2-1.20.2-new")
|
||||
// Compile-only hints for Registrate types used in mixin signatures
|
||||
compileOnly fg.deobf("com.tterrag.registrate:Registrate:MC1.20-1.3.11")
|
||||
// Example mod dependency using a mod jar from ./libs with a flat dir repository
|
||||
|
||||
@ -52,6 +52,42 @@ public class Ccccc {
|
||||
@SubscribeEvent
|
||||
public static void onClientSetup(FMLClientSetupEvent event) {
|
||||
LOGGER.debug("Client setup complete for {} (user: {})", MODID, Minecraft.getInstance().getUser().getName());
|
||||
|
||||
// Initialize AutoHUD compatibility for Botania if both mods are present and enabled
|
||||
event.enqueueWork(() -> {
|
||||
initializeAutoHudBotaniaCompat();
|
||||
});
|
||||
}
|
||||
|
||||
private static void initializeAutoHudBotaniaCompat() {
|
||||
try {
|
||||
// Check if config allows AutoHUD-Botania compatibility
|
||||
if (!Config.isEnabled(io.lampnet.ccccc.config.Tweak.COMPAT_AUTOHUD_BOTANIA)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if both AutoHUD and Botania are loaded
|
||||
if (!isModLoaded("autohud") || !isModLoaded("botania")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the compatibility
|
||||
io.lampnet.ccccc.compat.AutoHudBotaniaCompat compat = new io.lampnet.ccccc.compat.AutoHudBotaniaCompat();
|
||||
compat.init();
|
||||
|
||||
LOGGER.info("AutoHUD-Botania compatibility initialized successfully");
|
||||
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to initialize AutoHUD-Botania compatibility: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isModLoaded(String modId) {
|
||||
try {
|
||||
return net.minecraftforge.fml.ModList.get().isLoaded(modId);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
package io.lampnet.ccccc.compat;
|
||||
|
||||
/**
|
||||
* AutoHUD compatibility provider for Botania
|
||||
* Uses reflection to integrate with AutoHUD's component system like the experience bar
|
||||
*/
|
||||
public class AutoHudBotaniaCompat {
|
||||
|
||||
public String modId() {
|
||||
return "botania";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize AutoHUD compatibility for Botania's mana bar
|
||||
* This follows AutoHUD's API pattern but uses reflection due to compile-time dependencies
|
||||
*/
|
||||
public void init() {
|
||||
try {
|
||||
// Create a component for Botania's mana bar that behaves like the experience bar
|
||||
// This will be controlled by AutoHud.targetStatusBars like other status bar elements
|
||||
Class<?> componentClass = Class.forName("mod.crend.autohud.component.Component");
|
||||
Class<?> autoHudClass = Class.forName("mod.crend.autohud.AutoHud");
|
||||
Class<?> componentsClass = Class.forName("mod.crend.autohud.component.Components");
|
||||
|
||||
// Get the Component.builder method
|
||||
java.lang.reflect.Method builderMethod = componentClass.getMethod("builder", String.class, String.class);
|
||||
Object builder = builderMethod.invoke(null, "botania", "mana");
|
||||
|
||||
// Chain builder methods: isTargeted(() -> AutoHud.targetStatusBars)
|
||||
java.lang.reflect.Field targetStatusBarsField = autoHudClass.getField("targetStatusBars");
|
||||
java.util.function.Supplier<Boolean> targetSupplier = () -> {
|
||||
try {
|
||||
return targetStatusBarsField.getBoolean(null);
|
||||
} catch (Exception e) {
|
||||
return true; // Fallback to showing
|
||||
}
|
||||
};
|
||||
|
||||
Class<?> builderClass = builder.getClass();
|
||||
java.lang.reflect.Method isTargetedMethod = builderClass.getMethod("isTargeted", java.util.function.Supplier.class);
|
||||
builder = isTargetedMethod.invoke(builder, targetSupplier);
|
||||
|
||||
// Add config (use experience config since mana bar is similar)
|
||||
java.lang.reflect.Method configMethod = autoHudClass.getMethod("config");
|
||||
Object config = configMethod.invoke(null);
|
||||
java.lang.reflect.Method experienceMethod = config.getClass().getMethod("experience");
|
||||
Object experienceConfig = experienceMethod.invoke(config);
|
||||
|
||||
java.lang.reflect.Method configBuilderMethod = builderClass.getMethod("config", Object.class);
|
||||
builder = configBuilderMethod.invoke(builder, experienceConfig);
|
||||
|
||||
// Mark as in main HUD
|
||||
java.lang.reflect.Method inMainHudMethod = builderClass.getMethod("inMainHud");
|
||||
builder = inMainHudMethod.invoke(builder);
|
||||
|
||||
// Set state to always show when player has Botania items (simplified)
|
||||
java.util.function.Function<Object, Boolean> stateFunction = player -> true; // Simplified - always show
|
||||
java.lang.reflect.Method stateMethod = builderClass.getMethod("state", java.util.function.Function.class);
|
||||
builder = stateMethod.invoke(builder, stateFunction);
|
||||
|
||||
// Build the component
|
||||
java.lang.reflect.Method buildMethod = builderClass.getMethod("build");
|
||||
Object manaBarComponent = buildMethod.invoke(builder);
|
||||
|
||||
// Add to Experience component stack
|
||||
java.lang.reflect.Field experienceField = componentsClass.getField("Experience");
|
||||
Object experienceComponent = experienceField.get(null);
|
||||
java.lang.reflect.Method addStackComponentMethod = experienceComponent.getClass().getMethod("addStackComponent", Object.class);
|
||||
addStackComponentMethod.invoke(experienceComponent, manaBarComponent);
|
||||
|
||||
System.out.println("Botania AutoHUD compatibility initialized successfully");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to initialize Botania AutoHUD compatibility: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick state - simplified since we're using the experience component as base
|
||||
*/
|
||||
public void tickState(Object player) {
|
||||
// Component synchronization is handled automatically by AutoHUD's component system
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,21 @@ import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
|
||||
public enum Tweak {
|
||||
// PREVENT_PALLETE_LOG_SPAM(
|
||||
// "prevent_pallet_log_spam",
|
||||
// TweakCategory.CLIENT,
|
||||
// TweakGroup.NONE,
|
||||
// true,
|
||||
// "Palette permutations no longer fail on mods that aren't installed"
|
||||
// ),
|
||||
FIX_FORGESKYBOXES(
|
||||
"fix_forgeskyboxes",
|
||||
TweakCategory.BUGFIX,
|
||||
TweakGroup.NONE,
|
||||
true,
|
||||
"Fix Forge Skyboxes not loading",
|
||||
"forgeskyboxes"
|
||||
),
|
||||
MIXIN_RESPITEFUL_FLUIDS(
|
||||
"fix_respiteful_fluids_registration",
|
||||
TweakCategory.BUGFIX,
|
||||
@ -344,7 +359,7 @@ public enum Tweak {
|
||||
TweakGroup.NONE,
|
||||
true,
|
||||
"Tetra Structures generate in mountainous biomes",
|
||||
"tetra"
|
||||
"tetra", "tectonic"
|
||||
),
|
||||
TETRA_ENSCORCELLATION_COMPAT(
|
||||
"compat_tetra_ensorcellation",
|
||||
@ -369,6 +384,14 @@ public enum Tweak {
|
||||
true,
|
||||
"Supplementaries Hat Stand can wear Simple Hats",
|
||||
"supplementaries", "simplehats"
|
||||
),
|
||||
COMPAT_AUTOHUD_BOTANIA(
|
||||
"compat_autohud_botania",
|
||||
TweakCategory.COMPATIBILITY,
|
||||
TweakGroup.NONE,
|
||||
true,
|
||||
"AutoHUD registers Botania bars",
|
||||
"autohud", "botania"
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
@ -8,14 +8,19 @@ import java.util.Set;
|
||||
|
||||
import io.lampnet.ccccc.Config;
|
||||
import io.lampnet.ccccc.config.Tweak;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public final class CccccMixinPlugin implements IMixinConfigPlugin {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String RESPITEFUL_FLUIDS_RESOURCE = "plus/dragons/respiteful/entries/RespitefulFluids.class";
|
||||
private static final String TETRACELIUM_RESOURCE = "se/mickelus/tetracelium/TetraceliumMod.class";
|
||||
|
||||
private static final String BOTANIA_RESOURCE = "vazkii/botania/api/BotaniaAPI.class";
|
||||
private static final String JEI_MARKER_RESOURCE = "mezz/jei/forge/JustEnoughItems.class";
|
||||
private static final String SUPPLEMENTARIES_RESOURCE = "net/mehvahdjukaar/supplementaries/Supplementaries.class";
|
||||
private static final String SIMPLEHATS_RESOURCE = "fonnymunkey/simplehats/SimpleHats.class";
|
||||
private static final String FORGESKYBOXES_RESOURCE = "com/foopy/forgeskyboxes/FabricSkyBoxesClient.class";
|
||||
|
||||
@Override
|
||||
public void onLoad(final String mixinPackage) {
|
||||
@ -31,6 +36,9 @@ public final class CccccMixinPlugin implements IMixinConfigPlugin {
|
||||
final String respitefulMixin = "io.lampnet.ccccc.mixin.respiteful.RespitefulFluidsMixin";
|
||||
final String tetraceliumBotaniaMixin = "io.lampnet.ccccc.mixin.tetracelium.TetraceliumBotaniaMixin";
|
||||
final String supplementariesHatsMixin = "io.lampnet.ccccc.mixin.supplementaries.SupplementariesHatsMixin";
|
||||
|
||||
final String palettedPermutationsMixin = "io.lampnet.ccccc.mixin.client.PalettedPermutationsMixin";
|
||||
final String forgeskyboxesMixin = "io.lampnet.ccccc.mixin.forgeskyboxes.ForgeSkyboxesMixin";
|
||||
|
||||
if (respitefulMixin.equals(mixinClassName)) {
|
||||
boolean allowRespitefulByConfig = isRespitefulMixinEnabledSafe();
|
||||
@ -49,6 +57,18 @@ public final class CccccMixinPlugin implements IMixinConfigPlugin {
|
||||
final boolean resourcesPresent = areAllResourcesPresent(SUPPLEMENTARIES_RESOURCE, SIMPLEHATS_RESOURCE);
|
||||
return allowSupplementariesHatsByConfig && resourcesPresent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (palettedPermutationsMixin.equals(mixinClassName)) {
|
||||
boolean enabledByConfig = isPaletteLogSpamFixEnabledSafe();
|
||||
return enabledByConfig;
|
||||
}
|
||||
|
||||
if (forgeskyboxesMixin.equals(mixinClassName)) {
|
||||
boolean enabledByConfig = isForgeSkyboxesMixinEnabledSafe();
|
||||
return enabledByConfig;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -116,6 +136,25 @@ public final class CccccMixinPlugin implements IMixinConfigPlugin {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static boolean isPaletteLogSpamFixEnabledSafe() {
|
||||
try {
|
||||
// return Config.isEnabled(Tweak.PREVENT_PALLETE_LOG_SPAM);
|
||||
return false;
|
||||
} catch (final Throwable throwable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isForgeSkyboxesMixinEnabledSafe() {
|
||||
try {
|
||||
return Config.isEnabled(Tweak.FIX_FORGESKYBOXES);
|
||||
} catch (final Throwable throwable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
package io.lampnet.ccccc.mixin.client;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
|
||||
/**
|
||||
* Mixin to intercept PalettedPermutations and prevent loading palette images
|
||||
* from mods that aren't installed, which causes console log spam.
|
||||
*/
|
||||
@Mixin(value = net.minecraft.client.renderer.texture.atlas.sources.PalettedPermutations.class)
|
||||
public class PalettedPermutationsMixin {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Intercept the method that processes individual palette images using SRG name
|
||||
* This method is called during palette processing where the actual error occurs
|
||||
* Only affects palette-related resources from uninstalled mods
|
||||
*/
|
||||
@Inject(method = "m_266592_", at = @At("HEAD"), cancellable = true, require = 0, remap = false)
|
||||
private static void preventPaletteProcessingFromUninstalledMods_srg(ResourceManager resourceManager, ResourceLocation paletteLocation, CallbackInfoReturnable<?> cir) {
|
||||
|
||||
if (paletteLocation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String namespace = paletteLocation.getNamespace();
|
||||
final String path = paletteLocation.getPath();
|
||||
|
||||
// Only intercept palette-related resources (more specific check)
|
||||
if (!path.contains("trims/color_palettes/")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip check for minecraft namespace - always allow vanilla resources
|
||||
if ("minecraft".equals(namespace)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the mod is actually loaded
|
||||
if (!isModLoadedSafe(namespace)) {
|
||||
// Mod is not installed, return null to prevent error spam
|
||||
// This prevents the FileNotFoundException but allows other resource processing to continue
|
||||
cir.setReturnValue(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Safe method to check if a mod is loaded without throwing exceptions
|
||||
*/
|
||||
private static boolean isModLoadedSafe(final String modId) {
|
||||
try {
|
||||
final ModList modList = ModList.get();
|
||||
if (modList != null && modId != null && !modId.isEmpty()) {
|
||||
return modList.isLoaded(modId);
|
||||
}
|
||||
} catch (final Throwable ignored) {
|
||||
// If we can't determine mod status, allow loading to prevent breaking existing functionality
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
package io.lampnet.ccccc.mixin.forgeskyboxes;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Pseudo
|
||||
@Mixin(targets = "com.foopy.forgeskyboxes.FabricSkyBoxesClient", remap = false)
|
||||
public class ForgeSkyboxesMixin {
|
||||
|
||||
@Redirect(method = "onInitializeClient",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;m_91391_()Ljava/util/concurrent/CompletableFuture;"),
|
||||
remap = false)
|
||||
private java.util.concurrent.CompletableFuture<?> ccccc$removeResourcePackReload(Minecraft minecraft) {
|
||||
// Do nothing - removing the resource pack reload call
|
||||
return java.util.concurrent.CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
@ -8,9 +8,11 @@
|
||||
"mixins": [
|
||||
"respiteful.RespitefulFluidsMixin",
|
||||
"tetracelium.TetraceliumBotaniaMixin",
|
||||
"supplementaries.SupplementariesHatsMixin"
|
||||
"supplementaries.SupplementariesHatsMixin",
|
||||
"forgeskyboxes.ForgeSkyboxesMixin"
|
||||
],
|
||||
"client": [
|
||||
"client.PalettedPermutationsMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user