From 135dea1e60a53a591a6ea1e609e1d4084a87240e Mon Sep 17 00:00:00 2001 From: LostInLinearPast <1283411677@qq.com> Date: Mon, 8 Dec 2025 08:52:04 +0800 Subject: [PATCH] version 0.1.4 --- build.gradle | 2 + gradle.properties | 2 +- .../sccore/animation/data/AnimationData.java | 158 +++++++++++++++++- .../animation/data/GenericAnimationData.java | 100 +---------- .../sccore/animation/data/Ride.java | 2 +- .../sccore/animation/data/util/AnimJson.java | 31 +++- .../animation/data/util/RawAnimJson.java | 109 +++--------- .../event/client/CameraAnglesModify.java | 70 -------- .../animation/event/client/CameraModify.java | 103 ++++++++++++ .../animation/service/AnimationService.java | 26 --- .../animation/service/IAnimationService.java | 4 +- .../animation/utils/AnimationUtils.java | 68 +++++++- .../example/animation/ModAnimation.java | 9 +- .../sccore/mixin/animation/MixinEntity.java | 2 +- .../mixin/animation/client/MixinEntity.java | 4 +- .../animation/client/MixinHumanoidModel.java | 4 +- .../resources/META-INF/accesstransformer.cfg | 1 + 17 files changed, 396 insertions(+), 299 deletions(-) delete mode 100644 src/main/java/com/linearpast/sccore/animation/event/client/CameraAnglesModify.java create mode 100644 src/main/java/com/linearpast/sccore/animation/event/client/CameraModify.java create mode 100644 src/main/resources/META-INF/accesstransformer.cfg diff --git a/build.gradle b/build.gradle index 1916a64..c3eb257 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,8 @@ java { minecraft { mappings channel: mapping_channel, version: mapping_version + accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + copyIdeResources = true runs { diff --git a/gradle.properties b/gradle.properties index fb0ce7b..14060d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mapping_version=2023.09.03-1.20.1 mod_id=sccore mod_name=SnowyCrescentCore mod_license=GNU AGPL 3.0 -mod_version=1.20.1-0.1.3 +mod_version=1.20.1-0.1.4 mod_group_id=com.linearpast mod_authors=LostInLinearPast mod_description=A lib about capability and player animator. diff --git a/src/main/java/com/linearpast/sccore/animation/data/AnimationData.java b/src/main/java/com/linearpast/sccore/animation/data/AnimationData.java index 7001f4b..e049273 100644 --- a/src/main/java/com/linearpast/sccore/animation/data/AnimationData.java +++ b/src/main/java/com/linearpast/sccore/animation/data/AnimationData.java @@ -17,17 +17,50 @@ import java.util.List; public class AnimationData implements INBTSerializable { protected ResourceLocation key; + private float camYaw; + private float camPitch; + private float camRoll; + private int camComputePriority; + private Vec3 camPosOffset = new Vec3(0.0F, 0.0F, 0.0F); + private boolean camPosOffsetRelative; + private @Nullable GenericAnimationData.LyingType lyingType; protected @Nullable Ride ride; + public enum LyingType { + RIGHT("RIGHT", 0), + LEFT("LEFT", 1), + FRONT("FRONT", 2), + BACK("BACK", 3); + private final String name; + private final int id; + LyingType(String name, int id) { + this.name = name; + this.id = id; + } + + public String getName() { + return name; + } + + public int getId() { + return id; + } + + @Nullable + public static LyingType getLyingType(int id) { + for (LyingType type : LyingType.values()) { + if (type.id == id) { + return type; + } + } + return null; + } + } + public ResourceLocation getKey() { return key; } - public AnimationData withRide(Ride ride) { - this.ride = ride; - return this; - } - @Nullable @OnlyIn(Dist.CLIENT) public KeyframeAnimation getAnimation() { @@ -38,10 +71,112 @@ public class AnimationData implements INBTSerializable { return ride; } + public void setLyingType(@Nullable LyingType lyingType) { + this.lyingType = lyingType; + } + + public float getCamRoll() { + return camRoll; + } + + public float getCamPitch() { + return camPitch; + } + + public float getCamYaw() { + return camYaw; + } + + public int getCamComputePriority() { + return camComputePriority; + } + + public boolean isCamPosOffsetRelative() { + return camPosOffsetRelative; + } + + public Vec3 getCamPosOffset() { + return camPosOffset; + } + + public @Nullable GenericAnimationData.LyingType getLyingType() { + return lyingType; + } + + public AnimationData withRide(Ride ride) { + this.ride = ride; + return this; + } + + public AnimationData withCamYaw(float camYaw) { + this.camYaw = camYaw; + return this; + } + + public AnimationData withCamPitch(float camPitch) { + this.camPitch = camPitch; + return this; + } + + public AnimationData withCamRoll(float camRoll) { + this.camRoll = camRoll; + return this; + } + + public AnimationData withCamComputePriority(int camPosPriority) { + this.camComputePriority = camPosPriority; + return this; + } + + public AnimationData addCamPosOffset(Vec3 camPosOffset) { + this.camPosOffset = this.camPosOffset.add(camPosOffset); + return this; + } + + public AnimationData setCamPosOffset(Vec3 camPosOffset) { + this.camPosOffset = camPosOffset; + return this; + } + + public AnimationData withCamPosOffsetRelative(boolean camPosOffsetRelative) { + this.camPosOffsetRelative = camPosOffsetRelative; + return this; + } + + public AnimationData withLyingType(@Nullable AnimationData.LyingType lyingType) { + this.lyingType = lyingType; + if(lyingType == null) return this; + this.camPosOffset.add(0, -1.3f, 0); + this.camPitch = -90.0f; + switch (lyingType) { + case RIGHT -> { + this.camRoll = 90.0f; + this.camYaw = 90.0f; + } + case LEFT -> { + this.camRoll = -90.0f; + this.camYaw = -90.0f; + } + case BACK -> this.camPitch = 90.0f; + } + return this; + } + @Override public CompoundTag serializeNBT() { CompoundTag tag = new CompoundTag(); tag.putString("key", key.toString()); + tag.putInt("priority", camComputePriority); + if(lyingType != null) tag.putInt("lyingType", lyingType.getId()); + tag.putFloat("camYaw", camYaw); + tag.putFloat("camPitch", camPitch); + tag.putFloat("camRoll", camRoll); + CompoundTag camOffset = new CompoundTag(); + camOffset.putDouble("x", camPosOffset.x); + camOffset.putDouble("y", camPosOffset.y); + camOffset.putDouble("z", camPosOffset.z); + camOffset.putBoolean("relative", camPosOffsetRelative); + tag.put("camOffset", camOffset); if (ride != null) { CompoundTag rideTag = new CompoundTag(); Vec3 offset = ride.getOffset(); @@ -66,6 +201,19 @@ public class AnimationData implements INBTSerializable { public void deserializeNBT(CompoundTag nbt) { String string = nbt.getString("key"); this.key = new ResourceLocation(string); + this.camComputePriority = nbt.getInt("priority"); + if(nbt.contains("lyingType")) this.lyingType = LyingType.getLyingType(nbt.getInt("lyingType")); + else this.lyingType = null; + this.camYaw = nbt.getFloat("camYaw"); + this.camPitch = nbt.getFloat("camPitch"); + this.camRoll = nbt.getFloat("camRoll"); + CompoundTag camOffset = nbt.getCompound("camOffset"); + this.camPosOffset = new Vec3( + camOffset.getDouble("x"), + camOffset.getDouble("y"), + camOffset.getDouble("z") + ); + this.camPosOffsetRelative = camOffset.getBoolean("relative"); try { if(nbt.contains("ride")) { CompoundTag rideTag = nbt.getCompound("ride"); diff --git a/src/main/java/com/linearpast/sccore/animation/data/GenericAnimationData.java b/src/main/java/com/linearpast/sccore/animation/data/GenericAnimationData.java index 2f881fd..f658b78 100644 --- a/src/main/java/com/linearpast/sccore/animation/data/GenericAnimationData.java +++ b/src/main/java/com/linearpast/sccore/animation/data/GenericAnimationData.java @@ -8,11 +8,6 @@ import java.util.regex.Pattern; public class GenericAnimationData extends AnimationData { private @Nullable String name; private float heightModifier = 1.0f; - private float camYaw; - private float camPitch; - private float camRoll; - private float camY; - private @Nullable GenericAnimationData.LyingType lyingType; GenericAnimationData(ResourceLocation key) { this.key = key; @@ -23,81 +18,22 @@ public class GenericAnimationData extends AnimationData { return new GenericAnimationData(name); } - public enum LyingType { - RIGHT("RIGHT"), - LEFT("LEFT"), - FRONT("FRONT"), - BACK("BACK"); - private final String name; - LyingType(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Nullable - public static LyingType getLyingType(String name) { - for (LyingType type : LyingType.values()) { - if (type.name.equals(name)) { - return type; - } - } - return null; - } - } - - public GenericAnimationData withLyingType(@Nullable GenericAnimationData.LyingType lyingType) { - this.lyingType = lyingType; - if(lyingType == null) return this; - this.camY = -1.3f; - this.camPitch = -90.0f; - this.heightModifier = 0.3f; - switch (lyingType) { - case RIGHT -> { - this.camRoll = 90.0f; - this.camYaw = 90.0f; - } - case LEFT -> { - this.camRoll = -90.0f; - this.camYaw = -90.0f; - } - case BACK -> this.camPitch = 90.0f; - } - return this; - } - public GenericAnimationData withHeightModifier(float heightModifier) { this.heightModifier = heightModifier; return this; } - public GenericAnimationData withCamYaw(float camYaw) { - this.camYaw = camYaw; - return this; - } - - public GenericAnimationData withCamPitch(float camPitch) { - this.camPitch = camPitch; - return this; - } - - public GenericAnimationData withCamRoll(float camRoll) { - this.camRoll = camRoll; - return this; - } - - public GenericAnimationData withCamY(float camY) { - this.camY = camY; - return this; - } - public GenericAnimationData withRide(Ride ride) { this.ride = ride; return this; } + @Override + public GenericAnimationData withLyingType(@Nullable LyingType lyingType) { + this.heightModifier = 0.3f; + return (GenericAnimationData) super.withLyingType(lyingType); + } + public GenericAnimationData withName(String name) { String regex = "^[a-zA-Z0-9_-]+$"; Pattern pattern = Pattern.compile(regex); @@ -110,30 +46,6 @@ public class GenericAnimationData extends AnimationData { return this; } - public void setLyingType(@Nullable LyingType lyingType) { - this.lyingType = lyingType; - } - - public float getCamRoll() { - return camRoll; - } - - public float getCamPitch() { - return camPitch; - } - - public float getCamYaw() { - return camYaw; - } - - public @Nullable GenericAnimationData.LyingType getLyingType() { - return lyingType; - } - - public float getCamY() { - return camY; - } - public float getHeightModifier() { return heightModifier; } diff --git a/src/main/java/com/linearpast/sccore/animation/data/Ride.java b/src/main/java/com/linearpast/sccore/animation/data/Ride.java index 7ff963a..ad7538e 100644 --- a/src/main/java/com/linearpast/sccore/animation/data/Ride.java +++ b/src/main/java/com/linearpast/sccore/animation/data/Ride.java @@ -8,7 +8,7 @@ import java.util.List; public class Ride { private final List componentAnimations = new ArrayList<>(); - private Vec3 offset = Vec3.ZERO; + private Vec3 offset = new Vec3(0.0D, 0.0D, 0.0D); private int existTick; private float xRot; private float yRot; diff --git a/src/main/java/com/linearpast/sccore/animation/data/util/AnimJson.java b/src/main/java/com/linearpast/sccore/animation/data/util/AnimJson.java index b92fb01..8d5c0bb 100644 --- a/src/main/java/com/linearpast/sccore/animation/data/util/AnimJson.java +++ b/src/main/java/com/linearpast/sccore/animation/data/util/AnimJson.java @@ -2,6 +2,7 @@ package com.linearpast.sccore.animation.data.util; import com.google.gson.*; import com.linearpast.sccore.SnowyCrescentCore; +import com.linearpast.sccore.animation.data.AnimationData; import com.linearpast.sccore.animation.data.GenericAnimationData; import com.linearpast.sccore.animation.data.Ride; import net.minecraft.resources.ResourceLocation; @@ -20,10 +21,12 @@ public class AnimJson { private static final String Name = "name"; private static final String LyingType = "lyingType"; private static final String HeightModifier = "heightModifier"; - private static final String CamY = "camY"; private static final String CamPitch = "camPitch"; private static final String CamRoll = "camRoll"; private static final String CamYaw = "camYaw"; + private static final String CamPosOffset = "camPosOffset"; + private static final String Relative = "relative"; + private static final String Priority = "priority"; private static final String WithRide = "withRide"; private static final String Offset = "offset"; private static final String XRot = "xRot"; @@ -62,9 +65,16 @@ public class AnimJson { JsonObject json = originElement.getAsJsonObject(); GenericAnimationData animation = GenericAnimationData.create(new ResourceLocation(json.get(Key).getAsString())); if(json.has(Name)) animation.withName(json.get(Name).getAsString()); - if(json.has(LyingType)) animation.withLyingType(GenericAnimationData.LyingType.valueOf(json.get(LyingType).getAsString())); + if(json.has(LyingType)) animation.withLyingType(AnimationData.LyingType.valueOf(json.get(LyingType).getAsString())); + JsonObject camOffset = json.get(CamPosOffset).getAsJsonObject(); animation.withHeightModifier(json.get(HeightModifier).getAsFloat()) - .withCamY(json.get(CamY).getAsFloat()) + .withCamComputePriority(json.get(Priority).getAsInt()) + .setCamPosOffset(new Vec3( + camOffset.get("x").getAsDouble(), + camOffset.get("y").getAsDouble(), + camOffset.get("z").getAsDouble() + )) + .withCamPosOffsetRelative(camOffset.get(Relative).getAsBoolean()) .withCamPitch(json.get(CamPitch).getAsFloat()) .withCamRoll(json.get(CamRoll).getAsFloat()) .withCamYaw(json.get(CamYaw).getAsFloat()); @@ -116,11 +126,14 @@ public class AnimJson { public static Path syntaxExample(Path directory) throws Exception { ResourceLocation exampleLocation = new ResourceLocation(SnowyCrescentCore.MODID, Writer.example); - GenericAnimationData example = GenericAnimationData.create(exampleLocation) + GenericAnimationData example = (GenericAnimationData) GenericAnimationData + .create(exampleLocation) .withName(Writer.example) .withLyingType(GenericAnimationData.LyingType.RIGHT) .withHeightModifier(0.3f) - .withCamY(-1.3f) + .setCamPosOffset(new Vec3(0.0f, -1.3f, 0.0f)) + .withCamComputePriority(0) + .withCamPosOffsetRelative(false) .withCamPitch(-90.0f) .withCamRoll(90.0f) .withCamYaw(90.0f) @@ -160,9 +173,15 @@ public class AnimJson { ResourceLocation key = animation.getKey(); json.addProperty(Key, key.toString()); if (animation.getName() != null) json.addProperty(Name, animation.getName()); + json.addProperty(Priority, animation.getCamComputePriority()); if (animation.getLyingType() != null) json.addProperty(LyingType, animation.getLyingType().getName()); json.addProperty(HeightModifier, animation.getHeightModifier()); - json.addProperty(CamY, animation.getCamY()); + JsonObject camOffset = new JsonObject(); + camOffset.addProperty("x", animation.getCamPosOffset().x); + camOffset.addProperty("y", animation.getCamPosOffset().y); + camOffset.addProperty("z", animation.getCamPosOffset().z); + camOffset.addProperty(Relative, animation.isCamPosOffsetRelative()); + json.add(CamPosOffset, camOffset); json.addProperty(CamPitch, animation.getCamPitch()); json.addProperty(CamRoll, animation.getCamRoll()); json.addProperty(CamYaw, animation.getCamYaw()); diff --git a/src/main/java/com/linearpast/sccore/animation/data/util/RawAnimJson.java b/src/main/java/com/linearpast/sccore/animation/data/util/RawAnimJson.java index 2c5d973..a0514e0 100644 --- a/src/main/java/com/linearpast/sccore/animation/data/util/RawAnimJson.java +++ b/src/main/java/com/linearpast/sccore/animation/data/util/RawAnimJson.java @@ -1,22 +1,26 @@ package com.linearpast.sccore.animation.data.util; import com.google.gson.*; -import com.linearpast.sccore.SnowyCrescentCore; +import com.linearpast.sccore.animation.data.AnimationData; import com.linearpast.sccore.animation.data.RawAnimationData; import com.linearpast.sccore.animation.data.Ride; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.FileWriter; -import java.nio.file.Files; import java.nio.file.Path; public class RawAnimJson { private static final String Key = "key"; + private static final String LyingType = "lyingType"; + private static final String CamPitch = "camPitch"; + private static final String CamRoll = "camRoll"; + private static final String CamYaw = "camYaw"; + private static final String CamPosOffset = "camPosOffset"; + private static final String Relative = "relative"; + private static final String Priority = "priority"; private static final String WithRide = "withRide"; private static final String Offset = "offset"; private static final String XRot = "xRot"; @@ -38,12 +42,12 @@ public class RawAnimJson { this.originElement = originElement; } - public static Reader stream(Path path) throws Exception { - return new Reader(path); + public static RawAnimJson.Reader stream(Path path) throws Exception { + return new RawAnimJson.Reader(path); } - public static Reader stream(JsonElement jsonElement) { - return new Reader(jsonElement); + public static RawAnimJson.Reader stream(JsonElement jsonElement) { + return new RawAnimJson.Reader(jsonElement); } public RawAnimationData parse() { @@ -54,7 +58,18 @@ public class RawAnimJson { try { JsonObject json = originElement.getAsJsonObject(); RawAnimationData animation = RawAnimationData.create(new ResourceLocation(json.get(Key).getAsString())); - + if(json.has(LyingType)) animation.withLyingType(AnimationData.LyingType.valueOf(json.get(LyingType).getAsString())); + JsonObject camOffset = json.get(CamPosOffset).getAsJsonObject(); + animation.withCamComputePriority(json.get(Priority).getAsInt()) + .setCamPosOffset(new Vec3( + camOffset.get("x").getAsDouble(), + camOffset.get("y").getAsDouble(), + camOffset.get("z").getAsDouble() + )) + .withCamPosOffsetRelative(camOffset.get(Relative).getAsBoolean()) + .withCamPitch(json.get(CamPitch).getAsFloat()) + .withCamRoll(json.get(CamRoll).getAsFloat()) + .withCamYaw(json.get(CamYaw).getAsFloat()); if(json.has(WithRide)){ Ride ride = Ride.create(); JsonObject withRide = json.get(WithRide).getAsJsonObject(); @@ -83,80 +98,4 @@ public class RawAnimJson { } } } - - public static class Writer { - private static final String example = "example"; - private final @Nullable Path file; - private final RawAnimationData animation; - Writer(@Nullable Path file, RawAnimationData animation) { - this.animation = animation; - this.file = file; - } - - public static Writer stream(Path path, RawAnimationData animation) { - return new Writer(path, animation); - } - - public static Writer stream(RawAnimationData animation) { - return new Writer(null, animation); - } - - public static Path syntaxExample(Path directory) throws Exception { - ResourceLocation exampleLocation = new ResourceLocation(SnowyCrescentCore.MODID, Writer.example); - RawAnimationData example = RawAnimationData.create(exampleLocation) - .withRide(Ride.create() - .withOffset(new Vec3(0.0f, 1.0f, 0.0f)) - .withExistTick(200) - .withXRot(180) - .withYRot(0) - .addComponentAnimation(exampleLocation) - ); - Writer writer = stream(directory, example); - return writer.syntax(); - } - - public Path syntax() throws Exception { - if(file == null) throw new NullPointerException("file is null"); - Path modIdPath = file.resolve(animation.getKey().getNamespace()); - Path resultPath = modIdPath.resolve(animation.getKey().getPath() + ".anim.json"); - if(resultPath.toFile().exists()) return resultPath; - if(!Files.exists(modIdPath)) Files.createDirectories(modIdPath); - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - try (FileWriter writer = new FileWriter(resultPath.toFile())) { - gson.toJson(toJson(), writer); - return resultPath; - } - } - - - public JsonElement toJson() { - JsonObject json = new JsonObject(); - ResourceLocation key = animation.getKey(); - json.addProperty(Key, key.toString()); - Ride ride = animation.getRide(); - if(ride != null) { - JsonObject jsonRide = new JsonObject(); - JsonObject jsonOffset = new JsonObject(); - Vec3 offset = ride.getOffset(); - jsonOffset.addProperty("x", offset.x); - jsonOffset.addProperty("y", offset.y); - jsonOffset.addProperty("z", offset.z); - jsonRide.add(Offset, jsonOffset); - jsonRide.addProperty(XRot, ride.getXRot()); - jsonRide.addProperty(YRot, ride.getYRot()); - jsonRide.addProperty(ExistTick, ride.getExistTick()); - - if(!ride.getComponentAnimations().isEmpty()) { - JsonArray jsonComponents = new JsonArray(); - ride.getComponentAnimations().forEach(component -> - jsonComponents.add(component.toString()) - ); - jsonRide.add(ComponentsAnimation, jsonComponents); - } - json.add(WithRide, jsonRide); - } - return json; - } - - } } diff --git a/src/main/java/com/linearpast/sccore/animation/event/client/CameraAnglesModify.java b/src/main/java/com/linearpast/sccore/animation/event/client/CameraAnglesModify.java deleted file mode 100644 index 3072dc6..0000000 --- a/src/main/java/com/linearpast/sccore/animation/event/client/CameraAnglesModify.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.linearpast.sccore.animation.event.client; - -import com.linearpast.sccore.animation.capability.AnimationDataCapability; -import com.linearpast.sccore.animation.capability.inter.IAnimationCapability; -import com.linearpast.sccore.animation.data.GenericAnimationData; -import com.linearpast.sccore.animation.service.AnimationService; -import dev.kosmx.playerAnim.core.util.MathHelper; -import net.minecraft.client.Minecraft; -import net.minecraft.client.player.LocalPlayer; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.ViewportEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; - -import java.util.Comparator; - -@OnlyIn(Dist.CLIENT) -public class CameraAnglesModify { - private static float targetYaw = 0.0F; - private static float targetPitch = 0.0F; - private static float targetRoll = 0.0F; - private static float currentYaw = 0.0F; - private static float currentPitch = 0.0F; - private static float currentRoll = 0.0F; - - @SubscribeEvent - public static void changeCameraView(ViewportEvent.ComputeCameraAngles event){ - Minecraft minecraft = Minecraft.getInstance(); - - if (minecraft.options.getCameraType().isFirstPerson()) { - LocalPlayer player = minecraft.player; - if (player != null) { - IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); - if(data == null) return; - GenericAnimationData animation = null; - try { - animation = data.getAnimations().values().stream() - .map(AnimationService.INSTANCE::getAnimation) - .min(Comparator.comparingDouble(anim -> { - if (anim == null) return 1.0f; - return anim.getHeightModifier(); - })).orElse(null); - }catch (Exception ignored){} - - - if(animation != null) { - targetPitch = animation.getCamPitch(); - targetYaw = animation.getCamYaw(); - targetRoll = animation.getCamRoll(); - } else { - targetYaw = 0.0F; - targetPitch = 0.0F; - targetRoll = 0.0F; - } - } - float var3 = Minecraft.getInstance().getDeltaFrameTime(); - float var4 = var3 / 5.0F; - if (var4 == 0.0F) { - var4 = 0.0022857143F; - } - - currentPitch = MathHelper.lerp(var4, currentPitch, targetPitch); - currentYaw = MathHelper.lerp(var4, currentYaw, targetYaw); - currentRoll = MathHelper.lerp(var4, currentRoll, targetRoll); - event.setPitch(event.getPitch() + currentPitch); - event.setYaw(event.getYaw() + currentYaw); - event.setRoll(event.getRoll() + currentRoll); - } - } -} diff --git a/src/main/java/com/linearpast/sccore/animation/event/client/CameraModify.java b/src/main/java/com/linearpast/sccore/animation/event/client/CameraModify.java new file mode 100644 index 0000000..23a186c --- /dev/null +++ b/src/main/java/com/linearpast/sccore/animation/event/client/CameraModify.java @@ -0,0 +1,103 @@ +package com.linearpast.sccore.animation.event.client; + +import com.linearpast.sccore.animation.capability.AnimationDataCapability; +import com.linearpast.sccore.animation.capability.inter.IAnimationCapability; +import com.linearpast.sccore.animation.data.AnimationData; +import com.linearpast.sccore.animation.utils.AnimationUtils; +import dev.kosmx.playerAnim.core.util.MathHelper; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.ViewportEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +@OnlyIn(Dist.CLIENT) +public class CameraModify { + private static float targetYaw = 0.0F; + private static float targetPitch = 0.0F; + private static float targetRoll = 0.0F; + private static float currentYaw = 0.0F; + private static float currentPitch = 0.0F; + private static float currentRoll = 0.0F; + + @SubscribeEvent + public static void changeCameraView(ViewportEvent.ComputeCameraAngles event){ + Camera camera = event.getCamera(); + Entity entity = camera.getEntity(); + Minecraft minecraft = Minecraft.getInstance(); + if (entity == minecraft.player && minecraft.options.getCameraType().isFirstPerson()) { + LocalPlayer player = minecraft.player; + if (player != null) { + IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); + if(data == null) return; + AnimationData animation = AnimationUtils.getPredicateAnimationData(animationData -> { + float camYaw = animationData.getCamYaw(); + float camPitch = animationData.getCamPitch(); + float camRoll = animationData.getCamRoll(); + return !(camYaw == camPitch && camPitch == camRoll && camYaw == 0); + }); + + if(animation != null) { + targetPitch = animation.getCamPitch(); + targetYaw = animation.getCamYaw(); + targetRoll = animation.getCamRoll(); + } else { + targetYaw = 0.0F; + targetPitch = 0.0F; + targetRoll = 0.0F; + } + } + float var3 = Minecraft.getInstance().getDeltaFrameTime(); + float var4 = var3 / 5.0F; + if (var4 == 0.0F) { + var4 = 0.0022857143F; + } + + currentPitch = MathHelper.lerp(var4, currentPitch, targetPitch); + currentYaw = MathHelper.lerp(var4, currentYaw, targetYaw); + currentRoll = MathHelper.lerp(var4, currentRoll, targetRoll); + event.setPitch(event.getPitch() + currentPitch); + event.setYaw(event.getYaw() + currentYaw); + event.setRoll(event.getRoll() + currentRoll); + } + } + + @SubscribeEvent + public static void changeCameraPos(ViewportEvent.ComputeCameraAngles event) { + Camera camera = event.getCamera(); + Entity entity = camera.getEntity(); + Minecraft minecraft = Minecraft.getInstance(); + if(entity == minecraft.player && minecraft.options.getCameraType().isFirstPerson()) { + LocalPlayer player = minecraft.player; + + AnimationData animation = AnimationUtils.getPredicateAnimationData(animationData -> + !animationData.getCamPosOffset().multiply(1,0,1).equals(Vec3.ZERO) + ); + if(animation != null) { + Vec3 camPosOffset = animation.getCamPosOffset(); + if(animation.isCamPosOffsetRelative()) { + float yRot = player.yBodyRotO + (player.yBodyRot - player.yBodyRotO) * minecraft.getPartialTick(); + float bodyAngel = -(yRot + 90) * ((float)Math.PI / 180F); + double cos = Math.cos(bodyAngel); + double sin = Math.sin(bodyAngel); + double x = camPosOffset.x; + double z = camPosOffset.z; + camera.position = player.getEyePosition(minecraft.getPartialTick()).add( + sin * x + cos * z, + camPosOffset.y, + cos * x - sin * z + ); + } else { + if(camPosOffset.distanceToSqr(Vec3.ZERO) <= 10.0 * 10.0 * 10.0) { + camera.position = player.getEyePosition(minecraft.getPartialTick()) + .add(camPosOffset); + } + } + } + } + } +} diff --git a/src/main/java/com/linearpast/sccore/animation/service/AnimationService.java b/src/main/java/com/linearpast/sccore/animation/service/AnimationService.java index f4f4c5c..654a3b1 100644 --- a/src/main/java/com/linearpast/sccore/animation/service/AnimationService.java +++ b/src/main/java/com/linearpast/sccore/animation/service/AnimationService.java @@ -28,32 +28,6 @@ import java.util.Set; public class AnimationService implements IAnimationService { public static final AnimationService INSTANCE = new AnimationService(); - /** - * Get the LyingType when there are animations which playing on player.
- * And It will return the first which be found. - * @param player Target player - * @return The first LyingType it find. - */ - @Nullable - public GenericAnimationData.LyingType getSideView(Player player) { - return ANIMATION_RUNNER.testLoadedAndCall(() -> { - IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); - if(data == null) return null; - GenericAnimationData.LyingType lyingType = null; - for (ResourceLocation value : data.getAnimations().values()) { - GenericAnimationData animation = getAnimation(value); - if(animation == null) return null; - GenericAnimationData.LyingType type = animation.getLyingType(); - if(type == null) continue; - switch (type) { - case FRONT,BACK -> {} - case LEFT,RIGHT -> lyingType = animation.getLyingType(); - } - } - return lyingType; - }); - } - /** * Get the HeightModifier when there are animations which playing on player.
* And It will return the first which be found. diff --git a/src/main/java/com/linearpast/sccore/animation/service/IAnimationService.java b/src/main/java/com/linearpast/sccore/animation/service/IAnimationService.java index 4f390f2..c609004 100644 --- a/src/main/java/com/linearpast/sccore/animation/service/IAnimationService.java +++ b/src/main/java/com/linearpast/sccore/animation/service/IAnimationService.java @@ -3,7 +3,7 @@ package com.linearpast.sccore.animation.service; import com.linearpast.sccore.animation.data.AnimationData; import com.linearpast.sccore.animation.entity.AnimationRideEntity; import com.linearpast.sccore.animation.event.PlayerTickEvent; -import com.linearpast.sccore.animation.event.client.CameraAnglesModify; +import com.linearpast.sccore.animation.event.client.CameraModify; import com.linearpast.sccore.animation.event.client.ClientPlayerEvent; import com.linearpast.sccore.animation.event.client.EntityRendererRegisterEvent; import com.linearpast.sccore.animation.event.create.AnimationEvent; @@ -63,7 +63,7 @@ public interface IAnimationService + * And It will return the first which be found. + * @param player Target player + * @return The first LyingType it find. + */ + @Nullable + public static GenericAnimationData.LyingType getSideView(Player player) { + return IAnimationService.ANIMATION_RUNNER.testLoadedAndCall(() -> { + IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); + RawAnimationDataCapability rawData = RawAnimationDataCapability.getCapability(player).orElse(null); + if(data == null) return null; + if(rawData == null) return null; + + Map.Entry animations = null; + ArrayList resourceLocations = new ArrayList<>(); + resourceLocations.addAll(data.getAnimations().values()); + resourceLocations.addAll(rawData.getAnimations().values()); + for (ResourceLocation value : resourceLocations) { + AnimationData animation = AnimationApi.getDataHelper().getAnimationData(value); + if(animation == null) return null; + AnimationData.LyingType type = animation.getLyingType(); + if(type == null) continue; + switch (type) { + case FRONT,BACK -> {} + case LEFT,RIGHT -> { + if(animations == null || animations.getKey() < animation.getCamComputePriority()) { + animations = new AbstractMap.SimpleEntry<>(animation.getCamComputePriority(), type); + } + } + } + } + return animations == null ? null : animations.getValue(); + }); + } + + @Nullable + @OnlyIn(Dist.CLIENT) + public static AnimationData getPredicateAnimationData(Predicate predicate) { + return IAnimationService.ANIMATION_RUNNER.testLoadedAndCall(() -> { + LocalPlayer player = Minecraft.getInstance().player; + if(player == null) return null; + IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); + RawAnimationDataCapability rawData = RawAnimationDataCapability.getCapability(player).orElse(null); + if(data == null) return null; + if(rawData == null) return null; + + Map.Entry animations = null; + ArrayList resourceLocations = new ArrayList<>(); + resourceLocations.addAll(data.getAnimations().values()); + resourceLocations.addAll(rawData.getAnimations().values()); + for (ResourceLocation value : resourceLocations) { + AnimationData animation = AnimationApi.getDataHelper().getAnimationData(value); + if(animation == null) return null; + if(!predicate.test(animation)) continue; + animations = new AbstractMap.SimpleEntry<>(animation.getCamComputePriority(), animation); + } + return animations == null ? null : animations.getValue(); + }); + } } diff --git a/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java b/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java index 0ab85e5..23521c5 100644 --- a/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java +++ b/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java @@ -7,6 +7,7 @@ import com.linearpast.sccore.animation.event.create.AnimationRegisterEvent; import com.linearpast.sccore.animation.service.AnimationService; import com.linearpast.sccore.example.animation.event.ExamplePlayerAttackEvent; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.loading.FMLEnvironment; @@ -53,10 +54,14 @@ public class ModAnimation { // GenericAnimationData amSTL = GenericAnimationData.create(AmStandToLying) // .withName("Stand-to-Lying") // .withLyingType(GenericAnimationData.LyingType.FRONT); - GenericAnimationData waltzGentleman = GenericAnimationData.create(WaltzGentleman) + GenericAnimationData waltzGentleman = (GenericAnimationData) GenericAnimationData + .create(WaltzGentleman) .withName("Waltz-Gentleman") + .addCamPosOffset(new Vec3(0.0,0.0,1.0)) + .withCamPosOffsetRelative(true) .withRide(Ride.create().addComponentAnimation(WaltzLady)); - GenericAnimationData waltzLady = GenericAnimationData.create(WaltzLady) + GenericAnimationData waltzLady = (GenericAnimationData) GenericAnimationData + .create(WaltzLady) .withName("Waltz-Lady") .withCamYaw(180) .withRide(Ride.create().addComponentAnimation(WaltzGentleman)); diff --git a/src/main/java/com/linearpast/sccore/mixin/animation/MixinEntity.java b/src/main/java/com/linearpast/sccore/mixin/animation/MixinEntity.java index 117c733..51e12d9 100644 --- a/src/main/java/com/linearpast/sccore/mixin/animation/MixinEntity.java +++ b/src/main/java/com/linearpast/sccore/mixin/animation/MixinEntity.java @@ -35,7 +35,7 @@ public abstract class MixinEntity { for (ResourceLocation value : data.getAnimations().values()) { GenericAnimationData animation = AnimationService.INSTANCE.getAnimation(value); if(animation == null) continue; - float animationCamY = animation.getCamY(); + float animationCamY = (float) animation.getCamPosOffset().y; if(camYModifier == null) camYModifier = animationCamY; camYModifier = Math.min(camYModifier, animationCamY); } diff --git a/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinEntity.java b/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinEntity.java index 0084562..872a0da 100644 --- a/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinEntity.java +++ b/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinEntity.java @@ -1,7 +1,7 @@ package com.linearpast.sccore.mixin.animation.client; import com.linearpast.sccore.animation.data.GenericAnimationData; -import com.linearpast.sccore.animation.service.AnimationService; +import com.linearpast.sccore.animation.utils.AnimationUtils; import net.minecraft.client.Minecraft; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -36,7 +36,7 @@ public abstract class MixinEntity { private void turnPosePlayer(double pYRot, double pXRot, CallbackInfo ci) { Entity self = Entity.class.cast(this); if(self instanceof Player player){ - GenericAnimationData.LyingType lyingType = AnimationService.INSTANCE.getSideView(player); + GenericAnimationData.LyingType lyingType = AnimationUtils.getSideView(player); if(lyingType != null && Minecraft.getInstance().options.getCameraType().isFirstPerson()) { float f = (float)pXRot * 0.15F; float f1 = (float)pYRot * 0.15F; diff --git a/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinHumanoidModel.java b/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinHumanoidModel.java index 9c6da5e..fb65e84 100644 --- a/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinHumanoidModel.java +++ b/src/main/java/com/linearpast/sccore/mixin/animation/client/MixinHumanoidModel.java @@ -1,7 +1,7 @@ package com.linearpast.sccore.mixin.animation.client; import com.linearpast.sccore.animation.data.GenericAnimationData; -import com.linearpast.sccore.animation.service.AnimationService; +import com.linearpast.sccore.animation.utils.AnimationUtils; import net.minecraft.client.model.AgeableListModel; import net.minecraft.client.model.ArmedModel; import net.minecraft.client.model.HeadedModel; @@ -26,7 +26,7 @@ public abstract class MixinHumanoidModel extends Ageable ) private void modifyHeadRot(T pEntity, float pLimbSwing, float pLimbSwingAmount, float pAgeInTicks, float pNetHeadYaw, float pHeadPitch, CallbackInfo ci){ if(pEntity instanceof Player player){ - GenericAnimationData.LyingType lyingType = AnimationService.INSTANCE.getSideView(player); + GenericAnimationData.LyingType lyingType = AnimationUtils.getSideView(player); if(lyingType != null) { float pitch = pHeadPitch - 90.0f; float yaw = pNetHeadYaw * -1.0f; diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..a6d0e63 --- /dev/null +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1 @@ +public net.minecraft.client.Camera f_90552_ # position \ No newline at end of file