Skip to content

Commit

Permalink
port to neoforge 1.20.4
Browse files Browse the repository at this point in the history
  • Loading branch information
TexBlock committed Sep 15, 2024
1 parent 0ac7a49 commit d29ec0b
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 148 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# Animatica
A Minecraft mod for the Fabric mod loader intended to load the MCPatcher/OptiFine [animated texture format](https://github.com/sp614x/optifine/blob/master/OptiFineDoc/doc/custom_animations.txt). <br/>
# Animatica Foxified
Animatica unofficial NeoForge port.

A Minecraft mod for the NeoForge intended to load the MCPatcher/OptiFine [animated texture format](https://github.com/sp614x/optifine/blob/master/OptiFineDoc/doc/custom_animations.txt). <br/>
## What resource packs does this support?
Animatica adds support for resource packs that use **custom animated textures** <br/>
Animatica Foxified adds support for resource packs that use **custom animated textures** <br/>
This includes:
- Animated GUI textures
- Animated entity textures
- Animated block entity textures
- Animated armor textures
- Other animated textures (Animated blocks and items are a vanilla feature)
## Animatica DOES NOT support:
## Animatica Foxified DOES NOT support:
- Fully Custom GUI ([OptiGUI for Fabric](https://www.curseforge.com/minecraft/mc-mods/optigui))
- Custom entity models ([CEM for Fabric](https://www.curseforge.com/minecraft/mc-mods/custom-entity-models-cem))
- Custom entity model part animations in 3D ([CEM for Fabric](https://www.curseforge.com/minecraft/mc-mods/custom-entity-models-cem))
- Any other MCPatcher/OptiFine resource pack feature such as connected textures, etc

**These features WILL NEVER be implemented in Animatica.** <br/>
### Animatica is ONLY for ANIMATED TEXTURES.
### Animatica Foxified is ONLY for ANIMATED TEXTURES.
11 changes: 7 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version '1.6-SNAPSHOT'
id "dev.architectury.loom" version "1.7-SNAPSHOT"
}

sourceCompatibility = JavaVersion.VERSION_17
Expand All @@ -10,20 +10,23 @@ version = project.mod_version
group = project.maven_group

repositories {
maven { url "https://maven.neoforged.net/releases/" }
maven { url "https://maven.blamejared.com" }
}

dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
neoForge "net.neoforged:neoforge:${project.neoforge_version}"

modCompileOnly("org.embeddedt:embeddium-1.20.4:0.3.26-beta.189+mc1.20.4")
}

processResources {
inputs.property "version", project.version

filesMatching("fabric.mod.json") {
filesMatching("META-INF/mods.toml") {
expand "version": project.version
}
}
Expand Down
9 changes: 4 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
org.gradle.jvmargs=-Xmx1G

loom.platform=neoforge

minecraft_version=1.20.4
yarn_mappings=1.20.4+build.3
loader_version=0.15.11

# Fabric API
fabric_version=0.97.1+1.20.4
neoforge_version=20.4.237

mod_version = 0.6.1+1.20.4
mod_version = 0.0.1+1.20.4
maven_group = io.github.foundationgames
archives_base_name = animatica

2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
7 changes: 3 additions & 4 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
maven { url "https://maven.fabricmc.net/" }
maven { url "https://maven.architectury.dev/" }
maven { url "https://maven.neoforged.net/releases/" }
gradlePluginPortal()
}
}
46 changes: 36 additions & 10 deletions src/main/java/io/github/foundationgames/animatica/Animatica.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,51 @@

import io.github.foundationgames.animatica.animation.AnimationLoader;
import io.github.foundationgames.animatica.config.AnimaticaConfig;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.IExtensionPoint;
import net.neoforged.fml.ModList;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.TickEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.embeddedt.embeddium.api.OptionPageConstructionEvent;
import org.embeddedt.embeddium.client.gui.options.StandardOptions;

public class Animatica implements ClientModInitializer {
@Mod(Animatica.NAMESPACE)
public class Animatica {
public static final Logger LOG = LogManager.getLogger("Animatica");
public static final String NAMESPACE = "animatica";

public static final AnimaticaConfig CONFIG = new AnimaticaConfig();
public Animatica(IEventBus modEventBus) {
if (FMLLoader.getDist().isClient()) {
NeoForge.EVENT_BUS.addListener(EventPriority.HIGHEST, TickEvent.ClientTickEvent.class, event -> {
if (event.phase == TickEvent.Phase.START) {
AnimationLoader.INSTANCE.tickTextures();
}
});

@Override
public void onInitializeClient() {
ClientTickEvents.START_CLIENT_TICK.register(client -> AnimationLoader.INSTANCE.tickTextures());
modEventBus.addListener(RegisterClientReloadListenersEvent.class, event -> {
event.registerReloadListener(AnimationLoader.INSTANCE);
});

ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(AnimationLoader.INSTANCE);
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AnimaticaConfig.SPEC);
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> IExtensionPoint.DisplayTest.IGNORESERVERONLY, (a, b) -> true));

if (ModList.get().isLoaded("embeddium")) {
OptionPageConstructionEvent.BUS.addListener(event -> {
if (event.getId().matches(StandardOptions.Pages.GENERAL)) {
event.addGroup(AnimaticaConfig.EmbeddiumExtendedConfig.getAnimatedTextures());
}
});
}
}
}

public static Identifier id(String path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
Expand Down Expand Up @@ -37,7 +38,8 @@ public static Optional<AnimatedTexture> tryCreate(ResourceManager resources, Ide
return Optional.empty();
}

public AnimatedTexture(ResourceManager resources, List<AnimationMeta> metas, NativeImage image) throws IOException {
@SuppressWarnings("resource")
public AnimatedTexture(ResourceManager resources, @NotNull List<AnimationMeta> metas, @NotNull NativeImage image) throws IOException {
super(new NativeImage(image.getFormat(), image.getWidth(), image.getHeight(), true));

this.anims = new Animation[metas.size()];
Expand Down Expand Up @@ -143,7 +145,7 @@ public static class Animation implements AutoCloseable {
private boolean changed = true;

// Assembles all animation phases for one texture animation being baked
public Animation(AnimationMeta meta, ResourceManager resources) throws IOException {
public Animation(@NotNull AnimationMeta meta, @NotNull ResourceManager resources) throws IOException {
this.targetX = meta.targetX();
this.targetY = meta.targetY();
this.width = meta.width();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import com.mojang.blaze3d.systems.RenderSystem;
import io.github.foundationgames.animatica.Animatica;
import io.github.foundationgames.animatica.config.AnimaticaConfig;
import io.github.foundationgames.animatica.util.Flags;
import io.github.foundationgames.animatica.util.exception.PropertyParseException;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.minecraft.client.MinecraftClient;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.SynchronousResourceReloader;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;

Expand All @@ -21,7 +22,7 @@
import java.util.Set;
import java.util.function.BiConsumer;

public final class AnimationLoader implements SimpleSynchronousResourceReloadListener {
public final class AnimationLoader implements SynchronousResourceReloader {
public static final String[] ANIM_PATHS = {
"animatica/anim",
"mcpatcher/anim",
Expand Down Expand Up @@ -57,17 +58,12 @@ public void tickTextures() {
}
}

@Override
public Identifier getFabricId() {
return ID;
}

@Override
public void reload(ResourceManager manager) {
this.animatedTextures.clear();
this.animationIds.clear();

if (!Animatica.CONFIG.animatedTextures) {
if (!AnimaticaConfig.ANIMATED_TEXTURES.get()) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import io.github.foundationgames.animatica.util.exception.PropertyParseException;
import net.minecraft.util.Identifier;
import net.minecraft.util.InvalidIdentifierException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.util.HashSet;
import java.util.Map;
Expand All @@ -18,7 +20,8 @@ public record AnimationMeta(
int interpolationDelay, Map<Integer, Integer> frameMapping,
Map<Integer, Integer> frameDurations
) {
public static AnimationMeta of(Identifier file, Properties properties) throws PropertyParseException {
@Contract("_, _ -> new")
public static @NotNull AnimationMeta of(Identifier file, Properties properties) throws PropertyParseException {
Identifier source;
Identifier target;
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,87 +1,68 @@
package io.github.foundationgames.animatica.config;

import io.github.foundationgames.animatica.Animatica;
import net.fabricmc.loader.api.FabricLoader;
import me.jellysquid.mods.sodium.client.gui.options.OptionFlag;
import me.jellysquid.mods.sodium.client.gui.options.OptionGroup;
import me.jellysquid.mods.sodium.client.gui.options.OptionImpact;
import me.jellysquid.mods.sodium.client.gui.options.OptionImpl;
import me.jellysquid.mods.sodium.client.gui.options.control.TickBoxControl;
import me.jellysquid.mods.sodium.client.gui.options.storage.SodiumOptionsStorage;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.SimpleOption;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
import net.minecraft.text.Text;
import net.neoforged.neoforge.common.ModConfigSpec;

public class AnimaticaConfig {
public static String ANIMATED_TEXTURES_KEY = "animated_textures";

public static final String FILE_NAME = "animatica.properties";

private final SimpleOption<Boolean> animatedTexturesOption;
public boolean animatedTextures;

public AnimaticaConfig() {
try {
load();
} catch (IOException e) {
Animatica.LOG.error("Error loading config during initialization!", e);
}

this.animatedTexturesOption = SimpleOption.ofBoolean(
"option.animatica.animated_textures",
this.animatedTextures,
value -> {
this.animatedTextures = value;
try {
this.save();
} catch (IOException e) { Animatica.LOG.error("Error saving config while changing in game!", e); }
MinecraftClient.getInstance().reloadResources();
}
);
}

public void writeTo(Properties properties) {
properties.put(ANIMATED_TEXTURES_KEY, Boolean.toString(animatedTextures));
}

public void readFrom(Properties properties) {
this.animatedTextures = boolFrom(properties.getProperty(ANIMATED_TEXTURES_KEY), true);
private static final ModConfigSpec.Builder BUILDER;
public static final ModConfigSpec.BooleanValue ANIMATED_TEXTURES;
public static final ModConfigSpec SPEC;

static {
BUILDER = new ModConfigSpec.Builder();
BUILDER.push("animatica");
ANIMATED_TEXTURES = BUILDER.translation("option.animatica.animated_textures").define("animated_textures", true);
SPEC = BUILDER.build();
}

public Path getFile() throws IOException {
var file = FabricLoader.getInstance().getConfigDir().resolve(FILE_NAME);
if (!Files.exists(file)) {
Files.createFile(file);
public static class VanillaExtendedConfig {
private static final SimpleOption<Boolean> animatedTexturesOption;

static {
animatedTexturesOption = SimpleOption.ofBoolean(
"option.animatica.animated_textures",
AnimaticaConfig.ANIMATED_TEXTURES.getAsBoolean(),
value -> {
AnimaticaConfig.ANIMATED_TEXTURES.set(value);
MinecraftClient.getInstance().reloadResources();
}
);
}

return file;
}

public SimpleOption<Boolean> getAnimatedTexturesOption() {
return animatedTexturesOption;
}

public void save() throws IOException {
var file = getFile();
var properties = new Properties();

writeTo(properties);

try (var out = Files.newOutputStream(file)) {
properties.store(out, "Configuration file for Animatica");
public static SimpleOption<Boolean> getAnimatedTexturesOption() {
return animatedTexturesOption;
}
}

public void load() throws IOException {
var file = getFile();
var properties = new Properties();

try (var in = Files.newInputStream(file)) {
properties.load(in);
public static class EmbeddiumExtendedConfig {
private static final SodiumOptionsStorage sodiumOpts = new SodiumOptionsStorage();
private static final OptionGroup animatedTextures;

static {
animatedTextures = OptionGroup.createBuilder()
.setId(Animatica.id("animated_textures"))
.add(OptionImpl.createBuilder(Boolean.TYPE, sodiumOpts)
.setName(Text.translatable("option.animatica.animated_textures"))
.setTooltip(Text.of(""))
.setControl(TickBoxControl::new)
.setBinding((sodiumGameOptions, aBoolean) -> AnimaticaConfig.ANIMATED_TEXTURES.set(aBoolean), sodiumGameOptions -> AnimaticaConfig.ANIMATED_TEXTURES.get())
.setImpact(OptionImpact.VARIES)
.setFlags(new OptionFlag[]{OptionFlag.REQUIRES_ASSET_RELOAD})
.build()
).build();
}

readFrom(properties);
}

private static boolean boolFrom(String s, boolean defaultVal) {
return s == null ? defaultVal : "true".equals(s);
public static OptionGroup getAnimatedTextures() {
return animatedTextures;
}
}
}
Loading

0 comments on commit d29ec0b

Please sign in to comment.