diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..109db4a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: Build + +on: + push: + branches: + - 'master' + tags: + - 'v*' + pull_request: + branches: + - 'master' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: 21 + + - name: Get data from gradle.properties + id: mod_data + uses: christian-draeger/read-properties@1.1.1 + with: + path: './gradle.properties' + properties: 'mod_id version minecraft_version' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + + - name: Build with Gradle + run: ./gradlew build + + - name: Upload Fabric build + uses: actions/upload-artifact@v7 + with: + name: ${{ steps.mod_data.outputs.mod_id }}-fabric-${{ steps.mod_data.outputs.minecraft_version }}-${{ steps.mod_data.outputs.version }}.jar + path: fabric/build/libs/${{ steps.mod_data.outputs.mod_id }}-fabric-${{ steps.mod_data.outputs.minecraft_version }}-${{ steps.mod_data.outputs.version }}.jar + retention-days: 90 + - name: Upload NeoForge build + uses: actions/upload-artifact@v7 + with: + name: ${{ steps.mod_data.outputs.mod_id }}-neoforge-${{ steps.mod_data.outputs.minecraft_version }}-${{ steps.mod_data.outputs.version }}.jar + path: neoforge/build/libs/${{ steps.mod_data.outputs.mod_id }}-neoforge-${{ steps.mod_data.outputs.minecraft_version }}-${{ steps.mod_data.outputs.version }}.jar + retention-days: 90 \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE similarity index 97% rename from LICENSE.txt rename to LICENSE index 87ed7a2..f288702 100644 --- a/LICENSE.txt +++ b/LICENSE @@ -1,24 +1,7 @@ -Copyright (c) 2026 - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see - - - GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -648,8 +631,8 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} + + Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -662,14 +645,14 @@ the "copyright" line and a pointer to where the full notice is found. GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - {project} Copyright (C) {year} {fullname} + Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -681,12 +664,11 @@ might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see -. +. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. - +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bad1dbc --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +DynamicView Icon + +# Dynamic View + +Dynamic View is a Fabric and NeoForge mod which automatically changes the player's perspective. It has configurable +contexts including: + +- Swimming +- Crawling +- Flying +- Riding \ No newline at end of file diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle index 458be6d..72b8575 100644 --- a/buildSrc/src/main/groovy/multiloader-common.gradle +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -27,21 +27,17 @@ repositories { } exclusiveContent { forRepositories( - maven { - name = 'ParchmentMC' - url = 'https://maven.parchmentmc.org/' - }, - maven { - name = "NeoForge" - url = 'https://maven.neoforged.net/releases' - } + maven { + name = 'ParchmentMC' + url = 'https://maven.parchmentmc.org/' + }, + maven { + name = "NeoForge" + url = 'https://maven.neoforged.net/releases' + } ) filter { includeGroup('org.parchmentmc.data') } } - maven { - name = 'BlameJared' - url = 'https://maven.blamejared.com' - } maven { url "https://maven.shedaniel.me/" } maven { url "https://maven.terraformersmc.com/releases/" } } @@ -99,8 +95,6 @@ processResources { 'description' : project.description, 'neoforge_version' : neoforge_version, 'neoforge_loader_version_range': neoforge_loader_version_range, - "forge_version" : forge_version, - "forge_loader_version_range" : forge_loader_version_range, 'credits' : credits, 'java_version' : java_version, 'modmenu_version' : modmenu_version, diff --git a/common/build.gradle b/common/build.gradle index 5e73c51..4c9afc2 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -51,7 +51,7 @@ def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', Strin } } sourceSets.configureEach { - [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant-> + [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant -> configurations.named("$variant") { attributes { attribute(loaderAttribute, 'common') diff --git a/common/src/main/java/me/collinb/dynamicview/Constants.java b/common/src/main/java/me/collinb/dynamicview/Constants.java index 1817a13..a399002 100644 --- a/common/src/main/java/me/collinb/dynamicview/Constants.java +++ b/common/src/main/java/me/collinb/dynamicview/Constants.java @@ -1,12 +1,11 @@ package me.collinb.dynamicview; -import net.minecraft.client.Minecraft; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Constants { public static final String MOD_ID = "dynamicview"; - public static final String MOD_NAME = "DynamicView"; + public static final String MOD_NAME = "Dynamic View"; public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME); } diff --git a/common/src/main/java/me/collinb/dynamicview/DynamicView.java b/common/src/main/java/me/collinb/dynamicview/DynamicView.java index 2e72cd1..620de26 100644 --- a/common/src/main/java/me/collinb/dynamicview/DynamicView.java +++ b/common/src/main/java/me/collinb/dynamicview/DynamicView.java @@ -1,5 +1,6 @@ package me.collinb.dynamicview; +import me.collinb.dynamicview.camera.CameraAnimation; import me.collinb.dynamicview.config.ModConfig; import me.collinb.dynamicview.platform.Services; import me.shedaniel.autoconfig.AutoConfig; @@ -14,13 +15,13 @@ public class DynamicView { public static void setCameraType(CameraType cameraType) { if (!isCameraDynamic() && getMC().options.getCameraType() != cameraType) { previousCameraType = getMC().options.getCameraType(); - Constants.LOG.info("Setting previousCameraType={}", getMC().options.getCameraType()); + Constants.LOG.debug("Setting previousCameraType={}", getMC().options.getCameraType()); if (cameraType != null) { getMC().options.setCameraType(cameraType); } CameraAnimation.INSTANCE.currentDistance = 0.0f; CameraAnimation.INSTANCE.targetDistance = 4.0f; - Constants.LOG.info("Setting cameraType={}", cameraType); + Constants.LOG.debug("Setting cameraType={}", cameraType); } } @@ -31,7 +32,7 @@ public static void unsetCameraType() { if (config.animationEnabled) { CameraAnimation.INSTANCE.onAnimationComplete = () -> { getMC().options.setCameraType(previousCameraType); - Constants.LOG.info("Resetting cameraType={}", previousCameraType); + Constants.LOG.debug("Resetting cameraType={}", previousCameraType); previousCameraType = null; }; } else { @@ -43,7 +44,7 @@ public static void unsetCameraType() { } public static void init() { - Constants.LOG.info("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.getEnvironmentName()); + Constants.LOG.debug("Hello from Common init on {}! we are currently in a {} environment!", Services.PLATFORM.getPlatformName(), Services.PLATFORM.getEnvironmentName()); } public static void preTick(Minecraft mc) { diff --git a/common/src/main/java/me/collinb/dynamicview/CameraAnimation.java b/common/src/main/java/me/collinb/dynamicview/camera/CameraAnimation.java similarity index 84% rename from common/src/main/java/me/collinb/dynamicview/CameraAnimation.java rename to common/src/main/java/me/collinb/dynamicview/camera/CameraAnimation.java index f853988..05455fa 100644 --- a/common/src/main/java/me/collinb/dynamicview/CameraAnimation.java +++ b/common/src/main/java/me/collinb/dynamicview/camera/CameraAnimation.java @@ -1,9 +1,9 @@ -package me.collinb.dynamicview; +package me.collinb.dynamicview.camera; import me.collinb.dynamicview.config.ModConfig; import me.shedaniel.autoconfig.AutoConfig; -public class CameraAnimation { +public final class CameraAnimation { public static CameraAnimation INSTANCE = new CameraAnimation(); private final ModConfig config; @@ -38,6 +38,11 @@ public void tick() { if (Math.abs(currentDistance - targetDistance) < 0.1f && onAnimationComplete != null) { onAnimationComplete.run(); onAnimationComplete = null; + this.currentDistance = this.targetDistance; } } + + public boolean isCameraAnimating() { + return this.currentDistance != this.targetDistance; + } } diff --git a/common/src/main/java/me/collinb/dynamicview/config/ConfigScreen.java b/common/src/main/java/me/collinb/dynamicview/config/ConfigScreen.java deleted file mode 100644 index 80d9812..0000000 --- a/common/src/main/java/me/collinb/dynamicview/config/ConfigScreen.java +++ /dev/null @@ -1,4 +0,0 @@ -package me.collinb.dynamicview.config; - -public final class ConfigScreen { -} diff --git a/common/src/main/java/me/collinb/dynamicview/config/ModConfig.java b/common/src/main/java/me/collinb/dynamicview/config/ModConfig.java index 2b020c5..d107be7 100644 --- a/common/src/main/java/me/collinb/dynamicview/config/ModConfig.java +++ b/common/src/main/java/me/collinb/dynamicview/config/ModConfig.java @@ -6,7 +6,9 @@ import me.shedaniel.autoconfig.ConfigHolder; import me.shedaniel.autoconfig.annotation.Config; import me.shedaniel.autoconfig.annotation.ConfigEntry; +import me.shedaniel.autoconfig.annotation.ConfigEntry.Gui.EnumHandler.EnumDisplayOption; import me.shedaniel.autoconfig.serializer.GsonConfigSerializer; +import net.minecraft.client.CameraType; @Config(name = Constants.MOD_ID) public class ModConfig implements ConfigData { @@ -15,15 +17,32 @@ public static void init() { } @ConfigEntry.Gui.CollapsibleObject - public EnabledContexts enabledContexts = new EnabledContexts(); - public static class EnabledContexts { - public boolean swimming = true; - public boolean crawling = true; - public boolean flying = true; - public boolean riding = true; + public Contexts contexts = new Contexts(); + + public static class Contexts { + public boolean swimmingEnabled = true; + @ConfigEntry.Gui.EnumHandler(option = EnumDisplayOption.BUTTON) + public CameraType swimmingCamera = CameraType.THIRD_PERSON_BACK; + + public boolean crawlingEnabled = true; + @ConfigEntry.Gui.EnumHandler(option = EnumDisplayOption.BUTTON) + public CameraType crawlingCamera = CameraType.FIRST_PERSON; + + public boolean flyingEnabled = true; + @ConfigEntry.Gui.EnumHandler(option = EnumDisplayOption.BUTTON) + public CameraType flyingCamera = CameraType.THIRD_PERSON_BACK; + + public boolean ridingEnabled = true; + @ConfigEntry.Gui.EnumHandler(option = EnumDisplayOption.BUTTON) + public CameraType ridingCamera = CameraType.THIRD_PERSON_BACK; + } public boolean animationEnabled = true; + + @ConfigEntry.BoundedDiscrete(min = 0, max = 10) public float animationEnterEasing = 0.2f; + + @ConfigEntry.BoundedDiscrete(min = 0, max = 10) public float animationExitEasing = 0.6f; } diff --git a/common/src/main/java/me/collinb/dynamicview/mixin/CameraMixin.java b/common/src/main/java/me/collinb/dynamicview/mixin/CameraMixin.java index 9627df8..7d560dc 100644 --- a/common/src/main/java/me/collinb/dynamicview/mixin/CameraMixin.java +++ b/common/src/main/java/me/collinb/dynamicview/mixin/CameraMixin.java @@ -1,7 +1,7 @@ package me.collinb.dynamicview.mixin; -import me.collinb.dynamicview.CameraAnimation; import me.collinb.dynamicview.DynamicView; +import me.collinb.dynamicview.camera.CameraAnimation; import me.collinb.dynamicview.config.ModConfig; import me.shedaniel.autoconfig.AutoConfig; import net.minecraft.client.Camera; @@ -16,8 +16,11 @@ @Mixin(Camera.class) public abstract class CameraMixin { - @Inject(method = "getMaxZoom", at = @At("HEAD"), cancellable = true) + @Inject(method = "getMaxZoom", at = @At("TAIL"), cancellable = true) private void useSmoothZooming(float pMaxZoom, CallbackInfoReturnable cir) { + if (!CameraAnimation.INSTANCE.isCameraAnimating()) { + return; + } ModConfig config = AutoConfig.getConfigHolder(ModConfig.class).get(); if (DynamicView.isCameraDynamic() && config.animationEnabled) { float partial = getMC().getDeltaTracker().getGameTimeDeltaPartialTick(true); @@ -26,7 +29,9 @@ private void useSmoothZooming(float pMaxZoom, CallbackInfoReturnable cir) CameraAnimation.INSTANCE.previousDistance, CameraAnimation.INSTANCE.currentDistance ); - cir.setReturnValue(smoothDistance); + if (smoothDistance <= cir.getReturnValue()) { + cir.setReturnValue(smoothDistance); + } } } } diff --git a/common/src/main/java/me/collinb/dynamicview/mixin/EntityAccessor.java b/common/src/main/java/me/collinb/dynamicview/mixin/EntityAccessor.java index 23833d2..46f9092 100644 --- a/common/src/main/java/me/collinb/dynamicview/mixin/EntityAccessor.java +++ b/common/src/main/java/me/collinb/dynamicview/mixin/EntityAccessor.java @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.Shadow; @Mixin(Entity.class) -public class EntityAccessor { +public abstract class EntityAccessor { @Shadow @Final protected static EntityDataAccessor DATA_POSE; diff --git a/common/src/main/java/me/collinb/dynamicview/mixin/LocalPlayerMixin.java b/common/src/main/java/me/collinb/dynamicview/mixin/LocalPlayerMixin.java index 75d9a18..7d5a989 100644 --- a/common/src/main/java/me/collinb/dynamicview/mixin/LocalPlayerMixin.java +++ b/common/src/main/java/me/collinb/dynamicview/mixin/LocalPlayerMixin.java @@ -3,7 +3,6 @@ import me.collinb.dynamicview.DynamicView; import me.collinb.dynamicview.config.ModConfig; import me.shedaniel.autoconfig.AutoConfig; -import net.minecraft.client.CameraType; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.world.entity.Entity; @@ -16,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LocalPlayer.class) -public class LocalPlayerMixin { +public abstract class LocalPlayerMixin { @Unique private boolean dynamicView$wasSwimming = false; @@ -24,15 +23,15 @@ public class LocalPlayerMixin { @Inject(method = "startRiding", at = @At("TAIL")) private void startRiding(Entity p_108667_, boolean p_108668_, boolean p_435382_, CallbackInfoReturnable cir) { ModConfig config = AutoConfig.getConfigHolder(ModConfig.class).get(); - if (config.enabledContexts.riding) { - DynamicView.setCameraType(CameraType.THIRD_PERSON_BACK); + if (config.contexts.ridingEnabled) { + DynamicView.setCameraType(config.contexts.ridingCamera); } } @Inject(method = "removeVehicle", at = @At("TAIL")) private void removeVehicle(CallbackInfo ci) { ModConfig config = AutoConfig.getConfigHolder(ModConfig.class).get(); - if (config.enabledContexts.riding) { + if (config.contexts.ridingEnabled) { DynamicView.unsetCameraType(); } } @@ -46,15 +45,15 @@ private void updatePose(EntityDataAccessor pKey, CallbackInfo ci) { LocalPlayer player = (LocalPlayer) (Object) this; if (player.getPose() == Pose.SWIMMING) { - if (player.isSwimming() && config.enabledContexts.swimming) { - DynamicView.setCameraType(CameraType.THIRD_PERSON_BACK); + if (player.isInWater() && config.contexts.swimmingEnabled) { + DynamicView.setCameraType(config.contexts.swimmingCamera); dynamicView$wasSwimming = true; - } else if (config.enabledContexts.crawling) { - DynamicView.setCameraType(CameraType.THIRD_PERSON_BACK); + } else if (!player.isInWater() && config.contexts.crawlingEnabled) { + DynamicView.setCameraType(config.contexts.crawlingCamera); dynamicView$wasSwimming = true; } - } else if (player.getPose() == Pose.FALL_FLYING && config.enabledContexts.flying) { - DynamicView.setCameraType(CameraType.THIRD_PERSON_BACK); + } else if (player.getPose() == Pose.FALL_FLYING && config.contexts.flyingEnabled) { + DynamicView.setCameraType(config.contexts.flyingCamera); dynamicView$wasSwimming = true; } else if (dynamicView$wasSwimming) { DynamicView.unsetCameraType(); diff --git a/common/src/main/java/me/collinb/dynamicview/mixin/MinecraftMixin.java b/common/src/main/java/me/collinb/dynamicview/mixin/MinecraftMixin.java deleted file mode 100644 index 8bcc8a0..0000000 --- a/common/src/main/java/me/collinb/dynamicview/mixin/MinecraftMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.collinb.dynamicview.mixin; - -import me.collinb.dynamicview.Constants; -import net.minecraft.client.Minecraft; -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.CallbackInfo; - -@Mixin(Minecraft.class) -public class MinecraftMixin { - - @Inject(at = @At("TAIL"), method = "") - private void init(CallbackInfo info) { - Constants.LOG.info("This line is printed by the DynamicView common mixin!"); - Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); - } -} diff --git a/common/src/main/resources/assets/dynamicview/lang/en_us.json b/common/src/main/resources/assets/dynamicview/lang/en_us.json index 4105eb3..44ded66 100644 --- a/common/src/main/resources/assets/dynamicview/lang/en_us.json +++ b/common/src/main/resources/assets/dynamicview/lang/en_us.json @@ -1,9 +1,13 @@ { - "text.autoconfig.dynamicview.option.enabledContexts": "Enabled Contexts", - "text.autoconfig.dynamicview.option.enabledContexts.swimming": "Swimming", - "text.autoconfig.dynamicview.option.enabledContexts.crawling": "Crawling", - "text.autoconfig.dynamicview.option.enabledContexts.flying": "Flying", - "text.autoconfig.dynamicview.option.enabledContexts.riding": "Riding", + "text.autoconfig.dynamicview.option.contexts": "Contexts", + "text.autoconfig.dynamicview.option.contexts.swimmingEnabled": "Swimming Enabled", + "text.autoconfig.dynamicview.option.contexts.swimmingCamera": "Swimming Camera", + "text.autoconfig.dynamicview.option.contexts.crawlingEnabled": "Crawling Enabled", + "text.autoconfig.dynamicview.option.contexts.crawlingCamera": "Crawling Camera", + "text.autoconfig.dynamicview.option.contexts.flyingEnabled": "Flying Enabled", + "text.autoconfig.dynamicview.option.contexts.flyingCamera": "Flying Camera", + "text.autoconfig.dynamicview.option.contexts.ridingEnabled": "Riding Enabled", + "text.autoconfig.dynamicview.option.contexts.ridingCamera": "Riding Camera", "text.autoconfig.dynamicview.option.animationEnabled": "Enable Zoom Animation", "text.autoconfig.dynamicview.option.animationEnterEasing": "Animation Enter Easing", "text.autoconfig.dynamicview.option.animationExitEasing": "Animation Exit Easing" diff --git a/common/src/main/resources/dynamicview.mixins.json b/common/src/main/resources/dynamicview.mixins.json index dc0228f..8e9f2f7 100644 --- a/common/src/main/resources/dynamicview.mixins.json +++ b/common/src/main/resources/dynamicview.mixins.json @@ -7,8 +7,7 @@ "client": [ "CameraMixin", "EntityAccessor", - "LocalPlayerMixin", - "MinecraftMixin" + "LocalPlayerMixin" ], "server": [], "injectors": { diff --git a/common/src/main/resources/icon.png b/common/src/main/resources/icon.png new file mode 100644 index 0000000..6208d69 Binary files /dev/null and b/common/src/main/resources/icon.png differ diff --git a/fabric/build.gradle b/fabric/build.gradle index 91a3154..1372688 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -11,11 +11,14 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" - modApi "com.terraformersmc:modmenu:${project.modmenu_version}" + modImplementation("com.terraformersmc:modmenu:${modmenu_version}") { + exclude module: "fabric-api" + } modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") { exclude(group: "net.fabricmc.fabric-api") } + include "me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}" } loom { @@ -51,7 +54,7 @@ def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', Strin } } sourceSets.configureEach { - [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant-> + [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant -> configurations.named("$variant") { attributes { attribute(loaderAttribute, 'fabric') diff --git a/fabric/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java b/fabric/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java deleted file mode 100644 index b2e6282..0000000 --- a/fabric/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.collinb.dynamicview.mixin; - -import me.collinb.dynamicview.Constants; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.TitleScreen; -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.CallbackInfo; - -@Mixin(TitleScreen.class) -public class MixinTitleScreen { - - @Inject(at = @At("HEAD"), method = "init()V") - private void init(CallbackInfo info) { - Constants.LOG.info("This line is printed by the DynamicView mixin from Fabric!"); - Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); - } -} diff --git a/fabric/src/main/resources/dynamicview.fabric.mixins.json b/fabric/src/main/resources/dynamicview.fabric.mixins.json index e635a28..9f0dc84 100644 --- a/fabric/src/main/resources/dynamicview.fabric.mixins.json +++ b/fabric/src/main/resources/dynamicview.fabric.mixins.json @@ -5,9 +5,7 @@ "refmap": "${mod_id}.refmap.json", "compatibilityLevel": "JAVA_21", "mixins": [], - "client": [ - "MixinTitleScreen" - ], + "client": [], "server": [], "injectors": { "defaultRequire": 1 diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 9553858..5d938a4 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -12,7 +12,7 @@ "sources": "https://github.com/collin-b1/DynamicView" }, "license": "${license}", - "icon": "${mod_id}.png", + "icon": "icon.png", "environment": "*", "entrypoints": { "client": [ diff --git a/forge/build.gradle b/forge/build.gradle deleted file mode 100644 index c52bc7d..0000000 --- a/forge/build.gradle +++ /dev/null @@ -1,100 +0,0 @@ -plugins { - id 'multiloader-loader' - id 'net.minecraftforge.gradle' version '[6.0.24,6.2)' - id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' - id 'idea' -} -base { - archivesName = "${mod_name}-forge-${minecraft_version}" -} -mixin { - config("${mod_id}.mixins.json") - config("${mod_id}.forge.mixins.json") -} -jar { - manifest { - attributes["MixinConfigs"] = "${mod_id}.mixins.json,${mod_id}.forge.mixins.json" - } -} - -minecraft { - mappings channel: 'official', version: minecraft_version - - copyIdeResources = true //Calls processResources when in dev - - reobf = false // Forge 1.20.6+ uses official mappings at runtime, so we shouldn't reobf from official to SRG - - // Automatically enable forge AccessTransformers if the file exists - // This location is hardcoded in Forge and can not be changed. - // https://github.com/MinecraftForge/MinecraftForge/blob/be1698bb1554f9c8fa2f58e32b9ab70bc4385e60/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java#L123 - // Forge still uses SRG names during compile time, so we cannot use the common AT's - def at = file('src/main/resources/META-INF/accesstransformer.cfg') - if (at.exists()) { - accessTransformer = at - } - - runs { - client { - workingDirectory file('runs/client') - ideaModule "${rootProject.name}.${project.name}.main" - taskName 'Client' - mods { - modClientRun { - source sourceSets.main - } - } - } - - data { - workingDirectory file('runs/data') - ideaModule "${rootProject.name}.${project.name}.main" - args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') - taskName 'Data' - mods { - modDataRun { - source sourceSets.main - } - } - } - } -} - -sourceSets.main.resources.srcDir 'src/generated/resources' - -dependencies { - minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - annotationProcessor("org.spongepowered:mixin:0.8.5-SNAPSHOT:processor") -} - -publishing { - publications { - mavenJava(MavenPublication) { - fg.component(it) - } - } -} - -sourceSets.each { - def dir = layout.buildDirectory.dir("sourcesSets/$it.name") - it.output.resourcesDir = dir - it.java.destinationDirectory = dir -} - -// Implement mcgradleconventions loader attribute -def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', String) -['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements'].each { variant -> - configurations.named("$variant") { - attributes { - attribute(loaderAttribute, 'forge') - } - } -} -sourceSets.configureEach { - [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName].each { variant-> - configurations.named("$variant") { - attributes { - attribute(loaderAttribute, 'forge') - } - } - } -} diff --git a/forge/src/main/java/me/collinb/dynamicview/DynamicViewForge.java b/forge/src/main/java/me/collinb/dynamicview/DynamicViewForge.java deleted file mode 100644 index 60f8c20..0000000 --- a/forge/src/main/java/me/collinb/dynamicview/DynamicViewForge.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.collinb.dynamicview; - -import me.collinb.dynamicview.config.ModConfig; -import net.minecraft.client.Minecraft; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.event.TickEvent; - -import net.minecraftforge.eventbus.api.listener.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -@Mod(Constants.MOD_ID) -public class DynamicViewForge { - - public DynamicViewForge() { - DynamicView.init(); - } - - @Mod.EventBusSubscriber(modid = Constants.MOD_ID, value = Dist.CLIENT) - public static class ClientEvents { - - @SubscribeEvent - public static void onClientTick(TickEvent.ClientTickEvent event) { - DynamicView.preTick(Minecraft.getInstance()); - } - } -} diff --git a/forge/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java b/forge/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java deleted file mode 100644 index d052078..0000000 --- a/forge/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.collinb.dynamicview.mixin; - -import me.collinb.dynamicview.Constants; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.TitleScreen; -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.CallbackInfo; - -@Mixin(TitleScreen.class) -public class MixinTitleScreen { - - @Inject(at = @At("HEAD"), method = "init()V") - private void init(CallbackInfo info) { - Constants.LOG.info("This line is printed by the DynamicView mixin from Forge!"); - Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); - } -} diff --git a/forge/src/main/java/me/collinb/dynamicview/platform/ForgePlatformHelper.java b/forge/src/main/java/me/collinb/dynamicview/platform/ForgePlatformHelper.java deleted file mode 100644 index be7ecbf..0000000 --- a/forge/src/main/java/me/collinb/dynamicview/platform/ForgePlatformHelper.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.collinb.dynamicview.platform; - -import me.collinb.dynamicview.platform.services.IPlatformHelper; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.loading.FMLLoader; - -public class ForgePlatformHelper implements IPlatformHelper { - - @Override - public String getPlatformName() { - return "Forge"; - } - - @Override - public boolean isModLoaded(String modId) { - return ModList.get().isLoaded(modId); - } - - @Override - public boolean isDevelopmentEnvironment() { - return !FMLLoader.isProduction(); - } -} diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml deleted file mode 100644 index ad7590b..0000000 --- a/forge/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,27 +0,0 @@ -modLoader = "javafml" #mandatory -loaderVersion = "${forge_loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See https://files.minecraftforge.net/ for a list of versions. -license = "${license}" # Review your options at https://choosealicense.com/. -#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional -clientSideOnly=true #optional -[[mods]] #mandatory -modId = "${mod_id}" #mandatory -version = "${version}" #mandatory -displayName = "${mod_name}" #mandatory -#updateJSONURL="https://change.me.example.invalid/updates.json" #optional, see https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/ -#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional, displayed in the mod UI -logoFile = "${mod_id}.png" #optional -credits = "${credits}" #optional -authors = "${mod_author}" #optional -description = '''${description}''' #mandatory Supports multiline text -[[dependencies."${mod_id}"]] #optional -modId = "forge" #mandatory -mandatory = true #mandatory -versionRange = "[${forge_version},)" #mandatory -ordering = "NONE" # The order that this dependency should load in relation to your mod, required to be either 'BEFORE' or 'AFTER' if the dependency is not mandatory -side = "BOTH" # Side this dependency is applied on - 'BOTH', 'CLIENT' or 'SERVER' -[[dependencies."${mod_id}"]] -modId = "minecraft" -mandatory = true -versionRange = "${minecraft_version_range}" -ordering = "NONE" -side = "BOTH" diff --git a/forge/src/main/resources/META-INF/services/me.collinb.dynamicview.platform.services.IPlatformHelper b/forge/src/main/resources/META-INF/services/me.collinb.dynamicview.platform.services.IPlatformHelper deleted file mode 100644 index a03ccb5..0000000 --- a/forge/src/main/resources/META-INF/services/me.collinb.dynamicview.platform.services.IPlatformHelper +++ /dev/null @@ -1 +0,0 @@ -me.collinb.dynamicview.platform.ForgePlatformHelper diff --git a/forge/src/main/resources/dynamicview.forge.mixins.json b/forge/src/main/resources/dynamicview.forge.mixins.json deleted file mode 100644 index 56d14bd..0000000 --- a/forge/src/main/resources/dynamicview.forge.mixins.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "me.collinb.dynamicview.mixin", - "compatibilityLevel": "JAVA_18", - "mixins": [], - "client": [ - "MixinTitleScreen" - ], - "server": [], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/gradle.properties b/gradle.properties index a223eee..22c52bc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,41 +1,31 @@ # Important Notes: # Every field you add must be added to the root build.gradle expandProps map. # Project -version=1.0-SNAPSHOT +version=1.0.0 group=me.collinb java_version=21 - # Common minecraft_version=1.21.11 -mod_name=DynamicView +mod_name=Dynamic View mod_author=collin-b1 mod_id=dynamicview license=GPL-3.0 credits= -description=Dynamically switch player view +description=Automatically switches player perspective in specific contexts. minecraft_version_range=[1.21.11, 1.22) neo_form_version=1.21.11-20251209.172050 - # The version of ParchmentMC that is used, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions parchment_minecraft=1.21.10 parchment_version=2025.10.12 - # Fabric, see https://fabricmc.net/develop/ for new versions fabric_version=0.139.5+1.21.11 fabric_loader_version=0.18.2 - -# Forge, see https://files.minecraftforge.net/net/minecraftforge/forge/ for new versions -forge_version=61.0.1 -forge_loader_version_range=[61,) - # NeoForge, see https://projects.neoforged.net/neoforged/neoforge for new versions neoforge_version=21.11.3-beta neoforge_loader_version_range=[4,) - # Configs modmenu_version=17.0.0-beta.2 cloth_config_version=21.11.153 - # Gradle org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d4081da..bad7c24 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 55d3997..7bcc18c 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -53,7 +53,7 @@ def loaderAttribute = Attribute.of('io.github.mcgradleconventions.loader', Strin } } sourceSets.configureEach { - [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName, it.getTaskName(null, 'jarJar')].each { variant-> + [it.compileClasspathConfigurationName, it.runtimeClasspathConfigurationName, it.getTaskName(null, 'jarJar')].each { variant -> configurations.named("$variant") { attributes { attribute(loaderAttribute, 'neoforge') diff --git a/neoforge/src/main/java/me/collinb/dynamicview/DynamicViewNeoForge.java b/neoforge/src/main/java/me/collinb/dynamicview/DynamicViewNeoForge.java index 632d984..3a7ec42 100644 --- a/neoforge/src/main/java/me/collinb/dynamicview/DynamicViewNeoForge.java +++ b/neoforge/src/main/java/me/collinb/dynamicview/DynamicViewNeoForge.java @@ -5,7 +5,6 @@ import net.minecraft.client.Minecraft; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.EventPriority; -import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.EventBusSubscriber; diff --git a/neoforge/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java b/neoforge/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java deleted file mode 100644 index a3009cf..0000000 --- a/neoforge/src/main/java/me/collinb/dynamicview/mixin/MixinTitleScreen.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.collinb.dynamicview.mixin; - -import me.collinb.dynamicview.Constants; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.TitleScreen; -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.CallbackInfo; - -@Mixin(TitleScreen.class) -public class MixinTitleScreen { - - @Inject(at = @At("HEAD"), method = "init()V") - private void init(CallbackInfo info) { - Constants.LOG.info("This line is printed by the DynamicView mixin from NeoForge!"); - Constants.LOG.info("MC Version: {}", Minecraft.getInstance().getVersionType()); - } -} diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index a476356..cdd0a53 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -8,7 +8,7 @@ version = "${version}" #mandatory displayName = "${mod_name}" #mandatory #updateJSONURL="https://change.me.example.invalid/updates.json" #optional, see https://docs.neoforged.net/docs/misc/updatechecker/ #displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional, displayed in the mod UI -logoFile = "${mod_id}.png" #optional +logoFile = "icon.png" #optional credits = "${credits}" #optional authors = "${mod_author}" #optional description = '''${description}''' #mandatory Supports multiline text diff --git a/neoforge/src/main/resources/dynamicview.neoforge.mixins.json b/neoforge/src/main/resources/dynamicview.neoforge.mixins.json index fffc3f0..9ea9ca7 100644 --- a/neoforge/src/main/resources/dynamicview.neoforge.mixins.json +++ b/neoforge/src/main/resources/dynamicview.neoforge.mixins.json @@ -4,9 +4,7 @@ "package": "me.collinb.dynamicview.mixin", "compatibilityLevel": "JAVA_21", "mixins": [], - "client": [ - "MixinTitleScreen" - ], + "client": [], "server": [], "injectors": { "defaultRequire": 1 diff --git a/settings.gradle b/settings.gradle index 8942572..181e16e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,27 +26,15 @@ pluginManagement { includeGroupAndSubgroups("org.spongepowered") } } - exclusiveContent { - forRepository { - maven { - name = 'Forge' - url = uri('https://maven.minecraftforge.net') - } - } - filter { - includeGroupAndSubgroups('net.minecraftforge') - } - } } } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } // This should match the folder name of the project, or else IDEA may complain (see https://youtrack.jetbrains.com/issue/IDEA-317606) rootProject.name = 'DynamicView' include('common') include('fabric') -include('neoforge') -include('forge') +include('neoforge') \ No newline at end of file