diff --git a/CHANGELOG.md b/CHANGELOG.md index d9ebdbf102..0d0e0dac19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - Built in compatability for Better Combat mod ### Changed +- Gave Underlings and Carapacian Pawns the Attack Speed attribute. This influences how fast their attack animations play +- Underlings, Carapacian Pawns, and Consorts now adjust their walk animation speed according to their Movement Speed attribute - Structure Block Registry Processor can now be used for data generated structures through a processor_list - Adjusted the hitbox size for Lotus Flowers - The Lotus Time Capsule now spawns a Lotus Flower when placed diff --git a/src/main/java/com/mraof/minestuck/entity/AnimatedPathfinderMob.java b/src/main/java/com/mraof/minestuck/entity/AnimatedPathfinderMob.java index 1bf10215a6..0e776eb083 100644 --- a/src/main/java/com/mraof/minestuck/entity/AnimatedPathfinderMob.java +++ b/src/main/java/com/mraof/minestuck/entity/AnimatedPathfinderMob.java @@ -6,10 +6,13 @@ import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.level.Level; +import software.bernie.geckolib.core.animatable.GeoAnimatable; +import software.bernie.geckolib.core.animation.AnimationController; import java.util.UUID; @@ -87,12 +90,19 @@ public void unfreezeMob() instance.removeModifier(STATIONARY_MOB_MODIFIER.getId()); } + public void setCurrentAnimation(MobAnimation animation) + { + setCurrentAnimation(animation, 1); + } + + /** * Used to set the entity's animation and action * * @param animation The animation to set, also contains the action to set entityData from + * @param animationSpeed Used to adjust the length of the animation. The higher the number, the shorter the animation plays for */ - public void setCurrentAnimation(MobAnimation animation) + public void setCurrentAnimation(MobAnimation animation, double animationSpeed) { if(animation.freezeMovement()) freezeMob(); @@ -100,6 +110,6 @@ public void setCurrentAnimation(MobAnimation animation) unfreezeMob(); this.entityData.set(CURRENT_ACTION, animation.action().ordinal()); - this.remainingAnimationTicks = animation.animationLength(); + this.remainingAnimationTicks = (int) Math.round(animation.animationLength() / animationSpeed); } } \ No newline at end of file diff --git a/src/main/java/com/mraof/minestuck/entity/ai/MobAnimationPhaseGoal.java b/src/main/java/com/mraof/minestuck/entity/ai/MobAnimationPhaseGoal.java index 292a8d860c..9f56e7e86d 100644 --- a/src/main/java/com/mraof/minestuck/entity/ai/MobAnimationPhaseGoal.java +++ b/src/main/java/com/mraof/minestuck/entity/ai/MobAnimationPhaseGoal.java @@ -25,6 +25,7 @@ public abstract class MobAnimationPhaseGoal 0; + } + /** * Animations that at least one mob uses. The only kind of animation that is likely to occur at the same time as one of these is walking */ diff --git a/src/main/java/com/mraof/minestuck/entity/animation/PhasedMobAnimation.java b/src/main/java/com/mraof/minestuck/entity/animation/PhasedMobAnimation.java index 3e4ef8a9c4..b591c32154 100644 --- a/src/main/java/com/mraof/minestuck/entity/animation/PhasedMobAnimation.java +++ b/src/main/java/com/mraof/minestuck/entity/animation/PhasedMobAnimation.java @@ -1,6 +1,10 @@ package com.mraof.minestuck.entity.animation; import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.Attributes; + +import javax.annotation.Nullable; /** * A supplement to MobAnimation that allows for certain code to be performed at the point where one phase of an animation ends and the other begins. @@ -13,49 +17,66 @@ public class PhasedMobAnimation private final int contactStart; private final int recoveryStart; private final int recoveryEnd; + @Nullable + private final Attribute speedModifyingAttribute; + + public PhasedMobAnimation(MobAnimation animation, int initiationStart, int contactStart, int recoveryStart, int recoveryEnd) + { + this(animation, initiationStart, contactStart, recoveryStart, recoveryEnd, Attributes.ATTACK_SPEED); + } + /** * @param initiationStart not the first frame of animation * @param contactStart the apex of animations, when attacks connect + * @param speedModifyingAttribute the entity attribute responsible for affecting the animation's speed */ - public PhasedMobAnimation(MobAnimation animation, int initiationStart, int contactStart, int recoveryStart) + public PhasedMobAnimation(MobAnimation animation, int initiationStart, int contactStart, int recoveryStart, int recoveryEnd, @Nullable Attribute speedModifyingAttribute) { this.animation = animation; this.initiationStart = initiationStart; - this.contactStart = contactStart; - this.recoveryStart = recoveryStart; - this.recoveryEnd = animation.animationLength(); //recoveryEnd is identical to animationLength in MobAnimation + this.contactStart = contactStart; + this.recoveryStart = recoveryStart; + this.recoveryEnd = recoveryEnd; + this.speedModifyingAttribute = speedModifyingAttribute; } - public Phases getCurrentPhase(int time) + @Nullable + public Attribute getSpeedModifyingAttribute() { - if(time < initiationStart) + return speedModifyingAttribute; + } + + public Phases getCurrentPhase(PathfinderMob entity, int time, double speed) + { + if(time < getInitiationStartTime(speed)) return Phases.ANTICIPATION; - else if(time < contactStart) + else if(time < getContactStartTime(speed)) return Phases.INITIATION; - else if(time < recoveryStart) + else if(time < getRecoveryStartTime(speed)) return Phases.CONTACT; - else if(time < recoveryEnd) + else if(time < getTotalAnimationLength(speed)) return Phases.RECOVERY; else return Phases.NEUTRAL; } - public int getInitiationStartTime() + public int getInitiationStartTime(double speed) { - return initiationStart; + return (int) Math.round(initiationStart / speed); } - public int getContactStartTime() + public int getContactStartTime(double speed) { - return contactStart; + return (int) Math.round(contactStart / speed); } - public int getRecoveryStartTime() + public int getRecoveryStartTime(double speed) { - return recoveryStart; + return (int) Math.round(recoveryStart / speed); } + public MobAnimation getAnimation() { return animation; @@ -64,23 +85,23 @@ public MobAnimation getAnimation() /** * Equivalent to getting recoveryEnd value */ - public int getTotalAnimationLength() + public int getTotalAnimationLength(double speed) { - return recoveryEnd; + return (int) Math.round(recoveryEnd / speed); } /** * Is called every tick to check whether its time to transition to a new phase */ - public void attemptPhaseChange(int time, T entity) + public void attemptPhaseChange(int time, T entity, double speed) { - if(time == getInitiationStartTime()) + if(time == getInitiationStartTime(speed)) entity.setAnimationPhase(Phases.INITIATION, animation.action()); - else if(time == getContactStartTime()) + else if(time == getContactStartTime(speed)) entity.setAnimationPhase(Phases.CONTACT, animation.action()); - else if(time == getRecoveryStartTime()) + else if(time == getRecoveryStartTime(speed)) entity.setAnimationPhase(Phases.RECOVERY, animation.action()); - else if(time >= getTotalAnimationLength()) + else if(time >= getTotalAnimationLength(speed)) entity.setAnimationPhase(Phases.NEUTRAL, animation.action()); } diff --git a/src/main/java/com/mraof/minestuck/entity/carapacian/PawnEntity.java b/src/main/java/com/mraof/minestuck/entity/carapacian/PawnEntity.java index 2f433bb47e..e2d81f9747 100644 --- a/src/main/java/com/mraof/minestuck/entity/carapacian/PawnEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/carapacian/PawnEntity.java @@ -54,7 +54,9 @@ public class PawnEntity extends CarapacianEntity implements RangedAttackMob, Ene private static final MobAnimation TALK_PROPERTIES = new MobAnimation(MobAnimation.Action.TALK, 80, true, false); - public static final PhasedMobAnimation MELEE_ANIMATION = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.MELEE, 18, true, false), 3, 6, 7); + private static final double ATTACK_ANIMATION_SPEED = 2; + + public static final PhasedMobAnimation MELEE_ANIMATION = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.MELEE, 18, true, false), 3, 5, 7, 13); private static final RawAnimation WALK_ANIMATION = RawAnimation.begin().thenLoop("walk"); private static final RawAnimation ARMS_WALKING_ANIMATION = RawAnimation.begin().thenLoop("walkarms"); private static final RawAnimation PUNCH_ANIMATION_1 = RawAnimation.begin().then("punch1", Animation.LoopType.PLAY_ONCE); @@ -87,7 +89,7 @@ public static PawnEntity createDersite(EntityType type, Le public static AttributeSupplier.Builder pawnAttributes() { - return CarapacianEntity.carapacianAttributes().add(Attributes.ATTACK_DAMAGE) + return CarapacianEntity.carapacianAttributes().add(Attributes.ATTACK_DAMAGE).add(Attributes.ATTACK_SPEED, 4) .add(Attributes.MOVEMENT_SPEED, 0.2); } @@ -341,15 +343,16 @@ public String getSpriteType() public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { controllers.add(new AnimationController<>(this, "walkArmsAnimation", PawnEntity::walkArmsAnimation)); - controllers.add(new AnimationController<>(this, "walkAnimation", PawnEntity::walkAnimation)); + controllers.add(new AnimationController<>(this, "walkAnimation", PawnEntity::walkAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 5)); controllers.add(new AnimationController<>(this, "deathAnimation", PawnEntity::deathAnimation)); - controllers.add(new AnimationController<>(this, "swingAnimation", PawnEntity::swingAnimation).setAnimationSpeed(2)); + controllers.add(new AnimationController<>(this, "swingAnimation", PawnEntity::swingAnimation)); controllers.add(new AnimationController<>(this, "talkAnimation", PawnEntity::talkAnimation)); } private static PlayState walkAnimation(AnimationState state) { - if(state.isMoving()) + if(MobAnimation.isEntityMovingHorizontally(state.getAnimatable())) { state.getController().setAnimation(WALK_ANIMATION); return PlayState.CONTINUE; @@ -359,7 +362,7 @@ private static PlayState walkAnimation(AnimationState state) private static PlayState walkArmsAnimation(AnimationState state) { - if(state.isMoving() && !state.getAnimatable().isActive()) + if(MobAnimation.isEntityMovingHorizontally(state.getAnimatable()) && !state.getAnimatable().isActive()) { state.getController().setAnimation(ARMS_WALKING_ANIMATION); return PlayState.CONTINUE; @@ -367,11 +370,11 @@ private static PlayState walkArmsAnimation(AnimationState state) return PlayState.STOP; } - private static PlayState deathAnimation(AnimationState event) + private static PlayState deathAnimation(AnimationState state) { - if(event.getAnimatable().dead) + if(state.getAnimatable().dead) { - event.getController().setAnimation(DIE_ANIMATION); + state.getController().setAnimation(DIE_ANIMATION); return PlayState.CONTINUE; } return PlayState.STOP; @@ -385,6 +388,7 @@ private static PlayState swingAnimation(AnimationState event) return PlayState.CONTINUE; } event.getController().forceAnimationReset(); + event.getController().setAnimationSpeed(MobAnimation.getAttributeAffectedSpeed(event.getAnimatable(), Attributes.ATTACK_SPEED)); //Setting animation speed on stop so it doesn't jump around when attack speed changes mid-attack return PlayState.STOP; } diff --git a/src/main/java/com/mraof/minestuck/entity/underling/BasiliskEntity.java b/src/main/java/com/mraof/minestuck/entity/underling/BasiliskEntity.java index 93307ffb35..04cf4812ff 100644 --- a/src/main/java/com/mraof/minestuck/entity/underling/BasiliskEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/underling/BasiliskEntity.java @@ -29,9 +29,9 @@ @ParametersAreNonnullByDefault public class BasiliskEntity extends UnderlingEntity implements GeoEntity { - public static final PhasedMobAnimation TAIL_SWING_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.SWING, 12, true, false), 2, 4, 6); - public static final PhasedMobAnimation BITE_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.BITE, 10, true, false), 2, 4, 5); - public static final PhasedMobAnimation SHOOT_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.SHOOT, 14, true, true), 1, 4, 6); + public static final PhasedMobAnimation TAIL_SWING_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.SWING, 12, true, false), 1, 2, 3, 6); + public static final PhasedMobAnimation BITE_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.BITE, 10, true, false), 1, 2, 3, 5); + public static final PhasedMobAnimation SHOOT_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.SHOOT, 14, true, true), 1, 4, 6, 7); private static final RawAnimation RUN_ANIMATION = RawAnimation.begin().thenLoop("run"); private static final RawAnimation WALK_ANIMATION = RawAnimation.begin().thenLoop("walk"); private static final RawAnimation DIE_ANIMATION = RawAnimation.begin().then("die", Animation.LoopType.PLAY_ONCE); @@ -79,7 +79,7 @@ public static AttributeSupplier.Builder basiliskAttributes() { return UnderlingEntity.underlingAttributes().add(Attributes.MAX_HEALTH, 85) .add(Attributes.KNOCKBACK_RESISTANCE, 0.6).add(Attributes.MOVEMENT_SPEED, 0.25) - .add(Attributes.ATTACK_DAMAGE, 6); + .add(Attributes.ATTACK_DAMAGE, 6).add(Attributes.ATTACK_SPEED, 0.5); } @Override @@ -223,7 +223,8 @@ public void contactPhaseStart(MobAnimation.Action animation) public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { controllers.add(new AnimationController<>(this, "idleAnimation", BasiliskEntity::idleAnimation)); - controllers.add(new AnimationController<>(this, "walkAnimation", BasiliskEntity::walkAnimation).setAnimationSpeed(0.5)); + controllers.add(new AnimationController<>(this, "walkAnimation", BasiliskEntity::walkAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 3.5)); controllers.add(new AnimationController<>(this, "deathAnimation", BasiliskEntity::deathAnimation)); controllers.add(new AnimationController<>(this, "attackAnimation", BasiliskEntity::attackAnimation)); } @@ -235,7 +236,7 @@ private static PlayState idleAnimation(AnimationState state) private static PlayState walkAnimation(AnimationState state) { - if(!state.getAnimatable().isMovingHorizontally()) + if(!MobAnimation.isEntityMovingHorizontally(state.getAnimatable())) { return PlayState.STOP; } @@ -243,12 +244,11 @@ private static PlayState walkAnimation(AnimationState state) if(state.getAnimatable().isAggressive()) { state.getController().setAnimation(RUN_ANIMATION); - return PlayState.CONTINUE; } else { state.getController().setAnimation(WALK_ANIMATION); - return PlayState.CONTINUE; } + return PlayState.CONTINUE; } private static PlayState deathAnimation(AnimationState state) @@ -280,6 +280,7 @@ private static PlayState attackAnimation(AnimationState state) } state.getController().forceAnimationReset(); + state.getController().setAnimationSpeed(MobAnimation.getAttributeAffectedSpeed(state.getAnimatable(), Attributes.ATTACK_SPEED)); //Setting animation speed on stop so it doesn't jump around when attack speed changes mid-attack return PlayState.STOP; } } diff --git a/src/main/java/com/mraof/minestuck/entity/underling/GiclopsEntity.java b/src/main/java/com/mraof/minestuck/entity/underling/GiclopsEntity.java index 80a2d122a8..f5d5302b42 100644 --- a/src/main/java/com/mraof/minestuck/entity/underling/GiclopsEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/underling/GiclopsEntity.java @@ -30,7 +30,7 @@ @ParametersAreNonnullByDefault public class GiclopsEntity extends UnderlingEntity implements GeoEntity { - public static final PhasedMobAnimation KICK_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.KICK, 40, true, true), 18, 20, 22); + public static final PhasedMobAnimation KICK_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.KICK, 40, true, true), 18, 20, 22, 1); private static final RawAnimation IDLE_ANIMATION = RawAnimation.begin().thenLoop("idle"); private static final RawAnimation WALK_ANIMATION = RawAnimation.begin().thenLoop("walk"); private static final RawAnimation KICK_ANIMATION = RawAnimation.begin().then("kick", Animation.LoopType.PLAY_ONCE); @@ -46,7 +46,7 @@ public static AttributeSupplier.Builder giclopsAttributes() { return UnderlingEntity.underlingAttributes().add(Attributes.MAX_HEALTH, 210) .add(Attributes.KNOCKBACK_RESISTANCE, 0.9).add(Attributes.MOVEMENT_SPEED, 0.20) - .add(Attributes.ATTACK_DAMAGE, 18); + .add(Attributes.ATTACK_DAMAGE, 18).add(Attributes.ATTACK_SPEED, 1); } @Override @@ -169,7 +169,8 @@ public void initiationPhaseStart(MobAnimation.Action animation) public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { controllers.add(new AnimationController<>(this, "idleAnimation", GiclopsEntity::idleAnimation)); - controllers.add(new AnimationController<>(this, "walkAnimation", GiclopsEntity::walkAnimation)); + controllers.add(new AnimationController<>(this, "walkAnimation", GiclopsEntity::walkAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 5)); controllers.add(new AnimationController<>(this, "attackAnimation", GiclopsEntity::attackAnimation)); controllers.add(new AnimationController<>(this, "deathAnimation", GiclopsEntity::deathAnimation)); } @@ -187,7 +188,7 @@ private static PlayState idleAnimation(AnimationState state) private static PlayState walkAnimation(AnimationState state) { - if(state.getAnimatable().isMovingHorizontally()) + if(MobAnimation.isEntityMovingHorizontally(state.getAnimatable())) { state.getController().setAnimation(WALK_ANIMATION); return PlayState.CONTINUE; @@ -206,6 +207,7 @@ private static PlayState attackAnimation(AnimationState state) } state.getController().forceAnimationReset(); + state.getController().setAnimationSpeed(MobAnimation.getAttributeAffectedSpeed(state.getAnimatable(), Attributes.ATTACK_SPEED)); //Setting animation speed on stop so it doesn't jump around when attack speed changes mid-attack return PlayState.STOP; } diff --git a/src/main/java/com/mraof/minestuck/entity/underling/ImpEntity.java b/src/main/java/com/mraof/minestuck/entity/underling/ImpEntity.java index 307b4985fc..b2bc1befd8 100644 --- a/src/main/java/com/mraof/minestuck/entity/underling/ImpEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/underling/ImpEntity.java @@ -30,7 +30,7 @@ @ParametersAreNonnullByDefault public class ImpEntity extends UnderlingEntity implements GeoEntity { - public static final PhasedMobAnimation CLAW_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.CLAW, 8, true, false), 2, 4, 5); + public static final PhasedMobAnimation CLAW_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.CLAW, 8, true, false), 2, 5, 10, 16); private static final RawAnimation IDLE_ANIMATION = RawAnimation.begin().thenLoop("animation.minestuck.imp.idle"); private static final RawAnimation RUN_ANIMATION = RawAnimation.begin().thenLoop("animation.minestuck.imp.run"); private static final RawAnimation WALK_ANIMATION = RawAnimation.begin().thenLoop("animation.minestuck.imp.walk"); @@ -47,7 +47,7 @@ public ImpEntity(EntityType type, Level level) public static AttributeSupplier.Builder impAttributes() { return UnderlingEntity.underlingAttributes().add(Attributes.MAX_HEALTH, 6) - .add(Attributes.MOVEMENT_SPEED, 0.28).add(Attributes.ATTACK_DAMAGE, 2); + .add(Attributes.MOVEMENT_SPEED, 0.28).add(Attributes.ATTACK_DAMAGE, 2).add(Attributes.ATTACK_SPEED, 2); } @Override @@ -129,10 +129,12 @@ public void initiationPhaseStart(MobAnimation.Action animation) public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { controllers.add(new AnimationController<>(this, "idleAnimation", ImpEntity::idleAnimation)); - controllers.add(new AnimationController<>(this, "walkArmsAnimation", ImpEntity::walkArmsAnimation)); - controllers.add(new AnimationController<>(this, "walkAnimation", ImpEntity::walkAnimation).setAnimationSpeed(0.5)); + controllers.add(new AnimationController<>(this, "walkArmsAnimation", ImpEntity::walkArmsAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 1.785)); + controllers.add(new AnimationController<>(this, "walkAnimation", ImpEntity::walkAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 1.785)); controllers.add(new AnimationController<>(this, "deathAnimation", ImpEntity::deathAnimation).setAnimationSpeed(0.7)); - controllers.add(new AnimationController<>(this, "attackAnimation", ImpEntity::attackAnimation).setAnimationSpeed(2)); + controllers.add(new AnimationController<>(this, "attackAnimation", ImpEntity::attackAnimation)); } private static PlayState idleAnimation(AnimationState state) @@ -147,7 +149,7 @@ private static PlayState idleAnimation(AnimationState state) private static PlayState walkAnimation(AnimationState state) { - if(!state.isMoving()) + if(!MobAnimation.isEntityMovingHorizontally(state.getAnimatable())) { return PlayState.STOP; } @@ -155,17 +157,16 @@ private static PlayState walkAnimation(AnimationState state) if(state.getAnimatable().isAggressive()) { state.getController().setAnimation(RUN_ANIMATION); - return PlayState.CONTINUE; } else { state.getController().setAnimation(WALK_ANIMATION); - return PlayState.CONTINUE; } + return PlayState.CONTINUE; } private static PlayState walkArmsAnimation(AnimationState state) { - if(!state.isMoving() || state.getAnimatable().isActive()) + if(!MobAnimation.isEntityMovingHorizontally(state.getAnimatable()) || state.getAnimatable().isActive()) { return PlayState.STOP; } @@ -173,12 +174,11 @@ private static PlayState walkArmsAnimation(AnimationState state) if(state.getAnimatable().isAggressive()) { state.getController().setAnimation(RUNARMS_ANIMATION); - return PlayState.CONTINUE; } else { state.getController().setAnimation(WALKARMS_ANIMATION); - return PlayState.CONTINUE; } + return PlayState.CONTINUE; } private static PlayState deathAnimation(AnimationState state) @@ -199,6 +199,7 @@ private static PlayState attackAnimation(AnimationState state) return PlayState.CONTINUE; } state.getController().forceAnimationReset(); + state.getController().setAnimationSpeed(MobAnimation.getAttributeAffectedSpeed(state.getAnimatable(), Attributes.ATTACK_SPEED)); //Setting animation speed on stop so it doesn't jump around when attack speed changes mid-attack return PlayState.STOP; } } diff --git a/src/main/java/com/mraof/minestuck/entity/underling/LichEntity.java b/src/main/java/com/mraof/minestuck/entity/underling/LichEntity.java index 4517da351e..889c89e279 100644 --- a/src/main/java/com/mraof/minestuck/entity/underling/LichEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/underling/LichEntity.java @@ -29,7 +29,8 @@ @ParametersAreNonnullByDefault public class LichEntity extends UnderlingEntity implements GeoEntity { - public static final PhasedMobAnimation CLAW_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.CLAW, 10, false, false), 5, 6, 7); + + public static final PhasedMobAnimation CLAW_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.CLAW, 10, false, false), 11, 13, 16, 22); private static final RawAnimation IDLE_ANIMATION = RawAnimation.begin().thenLoop("idle"); private static final RawAnimation CLAW_LEGS_ANIMATION = RawAnimation.begin().then("claw_legs", Animation.LoopType.PLAY_ONCE); private static final RawAnimation WALK_ANIMATION = RawAnimation.begin().thenLoop("walk"); @@ -45,7 +46,7 @@ public static AttributeSupplier.Builder lichAttributes() { return UnderlingEntity.underlingAttributes().add(Attributes.MAX_HEALTH, 175) .add(Attributes.KNOCKBACK_RESISTANCE, 0.3).add(Attributes.MOVEMENT_SPEED, 0.25) - .add(Attributes.ATTACK_DAMAGE, 8); + .add(Attributes.ATTACK_DAMAGE, 8).add(Attributes.ATTACK_SPEED, 2.25); } @Override @@ -130,9 +131,10 @@ public void initiationPhaseStart(MobAnimation.Action animation) public void registerControllers(AnimatableManager.ControllerRegistrar controller) { controller.add(new AnimationController<>(this, "idleAnimation", LichEntity::idleAnimation)); - controller.add(new AnimationController<>(this, "walkAnimation", LichEntity::walkAnimation)); + controller.add(new AnimationController<>(this, "walkAnimation", LichEntity::walkAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 4)); controller.add(new AnimationController<>(this, "deathAnimation", LichEntity::deathAnimation)); - controller.add(new AnimationController<>(this, "attackAnimation", LichEntity::attackAnimation).setAnimationSpeed(2.25)); + controller.add(new AnimationController<>(this, "attackAnimation", LichEntity::attackAnimation)); } private static PlayState idleAnimation(AnimationState state) @@ -154,7 +156,7 @@ private static PlayState walkAnimation(AnimationState state) { state.getController().setAnimation(CLAW_LEGS_ANIMATION); return PlayState.CONTINUE; - } else if(!state.isMoving()) + } else if(!MobAnimation.isEntityMovingHorizontally(state.getAnimatable())) { return PlayState.STOP; } else @@ -182,6 +184,7 @@ private static PlayState attackAnimation(AnimationState state) return PlayState.CONTINUE; } state.getController().forceAnimationReset(); + state.getController().setAnimationSpeed(MobAnimation.getAttributeAffectedSpeed(state.getAnimatable(), Attributes.ATTACK_SPEED)); //Setting animation speed on stop so it doesn't jump around when attack speed changes mid-attack return PlayState.STOP; } diff --git a/src/main/java/com/mraof/minestuck/entity/underling/OgreEntity.java b/src/main/java/com/mraof/minestuck/entity/underling/OgreEntity.java index 5ab0df839a..5cfd403d72 100644 --- a/src/main/java/com/mraof/minestuck/entity/underling/OgreEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/underling/OgreEntity.java @@ -27,9 +27,10 @@ @ParametersAreNonnullByDefault public class OgreEntity extends UnderlingEntity { - public static final PhasedMobAnimation RIGHT_PUNCH_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.RIGHT_PUNCH, 22, true, true), 7, 10, 13); - public static final PhasedMobAnimation LEFT_PUNCH_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.LEFT_PUNCH, 22, true, true), 7, 10, 13); - public static final PhasedMobAnimation SLAM_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.SLAM, 30, true, true), 12, 15, 19); + + public static final PhasedMobAnimation RIGHT_PUNCH_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.RIGHT_PUNCH, 22, true, true), 3, 5, 6, 11); + public static final PhasedMobAnimation LEFT_PUNCH_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.LEFT_PUNCH, 22, true, true), 3, 5, 6, 11); + public static final PhasedMobAnimation SLAM_PROPERTIES = new PhasedMobAnimation(new MobAnimation(MobAnimation.Action.SLAM, 30, true, true), 6, 7, 9, 15); public static final RawAnimation WALK_ANIMATION = RawAnimation.begin().thenLoop("walk"); public static final RawAnimation WALKARMS_ANIMATION = RawAnimation.begin().thenLoop("walkarms"); public static final RawAnimation RIGHT_PUNCH_ANIMATION = RawAnimation.begin().then("right_punch", Animation.LoopType.PLAY_ONCE); @@ -47,7 +48,8 @@ public static AttributeSupplier.Builder ogreAttributes() { return UnderlingEntity.underlingAttributes().add(Attributes.MAX_HEALTH, 50) .add(Attributes.KNOCKBACK_RESISTANCE, 0.4).add(Attributes.MOVEMENT_SPEED, 0.22) - .add(Attributes.ATTACK_DAMAGE, 6).add(Attributes.ATTACK_KNOCKBACK, 12); + .add(Attributes.ATTACK_DAMAGE, 6).add(Attributes.ATTACK_KNOCKBACK, 12) + .add(Attributes.ATTACK_SPEED, 0.5); } @Override @@ -122,15 +124,17 @@ public void initiationPhaseStart(MobAnimation.Action animation) @Override public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { - controllers.add(new AnimationController<>(this, "walkArmsAnimation", OgreEntity::walkArmsAnimation).setAnimationSpeed(0.3)); - controllers.add(new AnimationController<>(this, "walkAnimation", OgreEntity::walkAnimation).setAnimationSpeed(0.3)); - controllers.add(new AnimationController<>(this, "attackAnimation", OgreEntity::attackAnimation).setAnimationSpeed(0.5)); + controllers.add(new AnimationController<>(this, "walkArmsAnimation", OgreEntity::walkArmsAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 2.27)); + controllers.add(new AnimationController<>(this, "walkAnimation", OgreEntity::walkAnimation) + .setAnimationSpeedHandler(entity -> MobAnimation.getAttributeAffectedSpeed(entity, Attributes.MOVEMENT_SPEED) * 2.27)); + controllers.add(new AnimationController<>(this, "attackAnimation", OgreEntity::attackAnimation)); controllers.add(new AnimationController<>(this, "deathAnimation", OgreEntity::deathAnimation).setAnimationSpeed(0.85)); } private static PlayState walkAnimation(AnimationState state) { - if(state.getAnimatable().isMovingHorizontally()) + if(MobAnimation.isEntityMovingHorizontally(state.getAnimatable())) { state.getController().setAnimation(WALK_ANIMATION); return PlayState.CONTINUE; @@ -140,7 +144,7 @@ private static PlayState walkAnimation(AnimationState state) private static PlayState walkArmsAnimation(AnimationState state) { - if(state.getAnimatable().isMovingHorizontally() && !state.getAnimatable().isActive()) + if(MobAnimation.isEntityMovingHorizontally(state.getAnimatable()) && !state.getAnimatable().isActive()) { state.getController().setAnimation(WALKARMS_ANIMATION); return PlayState.CONTINUE; @@ -167,6 +171,7 @@ private static PlayState attackAnimation(AnimationState state) } state.getController().forceAnimationReset(); + state.getController().setAnimationSpeed(MobAnimation.getAttributeAffectedSpeed(state.getAnimatable(), Attributes.ATTACK_SPEED)); //Setting animation speed on stop so it doesn't jump around when attack speed changes mid-attack return PlayState.STOP; } diff --git a/src/main/java/com/mraof/minestuck/entity/underling/UnderlingEntity.java b/src/main/java/com/mraof/minestuck/entity/underling/UnderlingEntity.java index 1ad75e3615..c79ff0158e 100644 --- a/src/main/java/com/mraof/minestuck/entity/underling/UnderlingEntity.java +++ b/src/main/java/com/mraof/minestuck/entity/underling/UnderlingEntity.java @@ -401,11 +401,6 @@ protected static void firstKillBonus(Entity killer, EcheladderBonusType type) } } - public boolean isMovingHorizontally() - { - return getDeltaMovement().horizontalDistanceSqr() > 0; - } - protected static class UnderlingData implements SpawnGroupData { public final GristType type;