diff --git a/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java b/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java index 03cee53..303f685 100644 --- a/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java +++ b/core/src/main/java/software/bernie/geckolib3/core/builder/Animation.java @@ -5,9 +5,12 @@ package software.bernie.geckolib3.core.builder; -import java.io.Serializable; +import java.io.*; import java.util.ArrayList; +import java.util.Base64; import java.util.List; + +import org.apache.commons.lang3.SerializationUtils; import software.bernie.geckolib3.core.builder.ILoopType.EDefaultLoopTypes; import software.bernie.geckolib3.core.keyframe.BoneAnimation; import software.bernie.geckolib3.core.keyframe.EventKeyFrame; @@ -29,4 +32,21 @@ public Animation() { this.particleKeyFrames = new ArrayList(); this.customInstructionKeyframes = new ArrayList(); } + + public static Animation copy(Animation animation) { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(animation); + objectOutputStream.flush(); + String serialized = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()); + + byte[] data = Base64.getDecoder().decode(serialized); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + return (Animation) objectInputStream.readObject(); + } catch (Exception e) { + return animation; + } + } } diff --git a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java index c4145d9..e54b6a7 100644 --- a/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java +++ b/src/main/java/software/bernie/geckolib3/core/controller/AnimationController.java @@ -212,11 +212,12 @@ public void setAnimation(AnimationBuilder builder) { // Convert the list of animation names to the actual list, keeping track of the // loop boolean along the way LinkedList animations = builder.getRawAnimationList().stream().map((rawAnimation) -> { - Animation animation = model.getAnimation(rawAnimation.animationName, animatable); - if (animation == null) { + Animation originalAnimation = model.getAnimation(rawAnimation.animationName, animatable); + if (originalAnimation == null) { System.out.printf("Could not load animation: %s. Is it missing?", rawAnimation.animationName); encounteredError.set(true); } + Animation animation = Animation.copy(originalAnimation); if (animation != null && rawAnimation.loopType != null) { animation.loop = rawAnimation.loopType; } @@ -392,17 +393,17 @@ public void process(double tick, AnimationEvent event, List modelRende HashMap> boneSnapshotCollection, MolangParser parser, boolean crashWhenCantFindBone) { parser.setValue("query.life_time", tick / 20); - if (currentAnimation != null) { - IAnimatableModel model = getModel(this.animatable); - if (model != null) { - Animation animation = model.getAnimation(currentAnimation.animationName, this.animatable); - if (animation != null) { - ILoopType loop = currentAnimation.loop; - currentAnimation = animation; - currentAnimation.loop = loop; - } - } - } +// if (currentAnimation != null) { +// IAnimatableModel model = getModel(this.animatable); +// if (model != null) { +// Animation animation = Animation.copy(model.getAnimation(currentAnimation.animationName, this.animatable)); +// if (animation != null) { +// ILoopType loop = currentAnimation.loop; +// currentAnimation = animation; +// currentAnimation.loop = loop; +// } +// } +// } createInitialQueues(modelRendererList); @@ -452,7 +453,7 @@ public void process(double tick, AnimationEvent event, List modelRende // Handle transitioning to a different animation (or just starting one) if (animationState == AnimationState.Transitioning) { // Just started transitioning, so set the current animation to the first one - if (tick == 0 || isJustStarting) { + if (this.justStartedTransition) { justStartedTransition = false; this.currentAnimation = animationQueue.poll(); resetEventKeyFrames(); @@ -525,6 +526,10 @@ public void process(double tick, AnimationEvent event, List modelRende } else if (getAnimationState() == AnimationState.Running) { // Actually run the animation processCurrentAnimation(tick, actualTick, parser, crashWhenCantFindBone); + if (getAnimationState() == AnimationState.Transitioning) { + saveSnapshotsForAnimation(this.currentAnimation, boneSnapshotCollection); + this.currentAnimation = this.animationQueue.poll(); + } } } @@ -567,28 +572,21 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse assert currentAnimation != null; // Animation has ended if (tick >= currentAnimation.animationLength) { - resetEventKeyFrames(); - // If the current animation is set to loop, keep it as the current animation and // just start over if (!currentAnimation.loop.isRepeatingAfterEnd()) { // Pull the next animation from the queue setAllStopping(); - Animation peek = animationQueue.peek(); - if (peek == null) { + Animation nextAnimation = animationQueue.peek(); + if (nextAnimation == null) { // No more animations left, stop the animation controller this.animationState = AnimationState.Stopped; return; - } else { - // Otherwise, set the state to transitioning and start transitioning to the next - // animation next frame - this.animationState = AnimationState.Transitioning; - shouldResetTick = true; - currentAnimation = this.animationQueue.peek(); } } else { if (currentAnimation.loop == ILoopType.EDefaultLoopTypes.LOOP) { // Reset the adjusted tick so the next animation starts at tick 0 + resetEventKeyFrames(); shouldResetTick = true; tick = adjustTick(actualTick); } else { @@ -681,8 +679,13 @@ private void processCurrentAnimation(double tick, double actualTick, MolangParse } //} - if (this.transitionLengthTicks == 0 && shouldResetTick && this.animationState == AnimationState.Transitioning) { - this.currentAnimation = animationQueue.poll(); + if (tick >= currentAnimation.animationLength && !currentAnimation.loop.isRepeatingAfterEnd()) { + Animation nextAnimation = animationQueue.peek(); + if (nextAnimation != null) { + this.animationState = AnimationState.Transitioning; + shouldResetTick = true; + adjustTick(actualTick); + } } }