/* * Derived from Epic Fight (https://github.com/Epic-Fight/epicfight) * by the Epic Fight Team, licensed under GPLv3. * Modifications © 2026 TiedUp! Remake Contributors, distributed under GPLv3. */ package com.tiedup.remake.rig; import com.mojang.logging.LogUtils; import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.rig.anim.Animator; import com.tiedup.remake.rig.anim.ServerAnimator; import com.tiedup.remake.rig.patch.LivingEntityPatch; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.loading.FMLEnvironment; import org.slf4j.Logger; import java.util.function.Function; /** * Remplace {@code yesman.epicfight.main.EpicFightMod} + {@code EpicFightSharedConstants} * du fork upstream. Expose les singletons nécessaires au runtime RIG : * * * *

Pattern lazy method-ref : {@code ClientAnimator::getAnimator} n'est chargé * que si {@link #isPhysicalClient()} est true. Sur serveur dedié, la classe * client n'est jamais référencée, donc jamais chargée → pas de * {@code NoClassDefFoundError}.

*/ public final class TiedUpRigConstants { public static final String MODID = TiedUpMod.MOD_ID; public static final Logger LOGGER = LogUtils.getLogger(); /** Détection dev env (Gradle runClient) — utilisé pour les logs debug EF. */ public static final boolean IS_DEV_ENV = !FMLEnvironment.production; /** Durée d'un tick MC en secondes (20 TPS). */ public static final float A_TICK = 1.0F / 20.0F; /** Durée de transition inter-animation par défaut (en secondes — 0.15s = 3 ticks). */ public static final float GENERAL_ANIMATION_TRANSITION_TIME = 0.15F; /** Nombre max de joints supportés par une armature (limite matrice pool). */ public static final int MAX_JOINTS = 128; /** * Factory lazy : crée un Animator approprié au side runtime courant. * Client → {@link com.tiedup.remake.rig.anim.client.ClientAnimator#getAnimator} * Server → {@link ServerAnimator#getAnimator} (forké verbatim EF) * *

Pattern lazy method-ref : {@code ClientAnimator::getAnimator} n'est * chargé que si {@link #isPhysicalClient()} est true. Sur serveur dédié, * la classe client n'est jamais référencée, donc jamais chargée → pas de * {@code NoClassDefFoundError}.

*/ public static final Function, Animator> ANIMATOR_PROVIDER = isPhysicalClient() ? com.tiedup.remake.rig.anim.client.ClientAnimator::getAnimator : ServerAnimator::getAnimator; private TiedUpRigConstants() {} public static ResourceLocation identifier(String path) { return ResourceLocation.fromNamespaceAndPath(MODID, path); } /** Alias d'{@link #identifier(String)} — équivalent TiedUpRigConstants.prefix upstream. */ public static ResourceLocation prefix(String path) { return identifier(path); } public static boolean isPhysicalClient() { return FMLEnvironment.dist == Dist.CLIENT; } /** * En dev env : log un message + throw l'exception fournie. * En prod : log WARN seulement. Équivalent EF {@code TiedUpRigConstants.stacktraceIfDevSide}. */ public static void stacktraceIfDevSide( String message, java.util.function.Function exceptionFactory ) { if (IS_DEV_ENV) { throw exceptionFactory.apply(message); } else { LOGGER.warn(message); } } /** * En dev env : log via le consumer + throw l'exception. * En prod : log seulement. Équivalent EF {@code EpicFightMod.logAndStacktraceIfDevSide}. */ public static void logAndStacktraceIfDevSide( java.util.function.BiConsumer logAction, String message, java.util.function.Function exceptionFactory ) { logAndStacktraceIfDevSide(logAction, message, exceptionFactory, message); } public static void logAndStacktraceIfDevSide( java.util.function.BiConsumer logAction, String message, java.util.function.Function exceptionFactory, String stackTraceMessage ) { logAction.accept(LOGGER, message); if (IS_DEV_ENV) { Throwable t = exceptionFactory.apply(stackTraceMessage); if (t instanceof RuntimeException re) throw re; if (t instanceof Error err) throw err; throw new RuntimeException(t); } } }