simple animation state transition util
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				studiorailgun/Renderer/pipeline/head There was a failure building this commit
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	studiorailgun/Renderer/pipeline/head There was a failure building this commit
				
			This commit is contained in:
		
							parent
							
								
									5f56f0d742
								
							
						
					
					
						commit
						6c3dcec01c
					
				| @ -290,9 +290,8 @@ | |||||||
|                 "variants": [ |                 "variants": [ | ||||||
|                     { |                     { | ||||||
|                         "variantId": "blockWeaponRight", |                         "variantId": "blockWeaponRight", | ||||||
|                         "windUpAnimation" : "Jump", |  | ||||||
|                         "mainAnimation" : "Fall", |                         "mainAnimation" : "Fall", | ||||||
|                         "cooldownAnimation" : "Land", |                         "mainFirstPersonAnimation" : "HoldItemR2HBlock", | ||||||
|                         "defaults" : [ |                         "defaults" : [ | ||||||
|                             { |                             { | ||||||
|                                 "equipPoint" : "handRight", |                                 "equipPoint" : "handRight", | ||||||
|  | |||||||
| @ -454,6 +454,7 @@ Devtools for updating first person attachment rotations | |||||||
| 
 | 
 | ||||||
| (07/26/2024) | (07/26/2024) | ||||||
| Viewmodel equipped item rotates inverted to bone rotation | Viewmodel equipped item rotates inverted to bone rotation | ||||||
|  | Visually block | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # TODO | # TODO | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import electrosphere.engine.Globals; | |||||||
| import electrosphere.logger.LoggerInterface; | import electrosphere.logger.LoggerInterface; | ||||||
| import electrosphere.util.FileUtils; | import electrosphere.util.FileUtils; | ||||||
| 
 | 
 | ||||||
|  | import org.joml.Vector3d; | ||||||
| import org.joml.Vector3f; | import org.joml.Vector3f; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -33,6 +34,17 @@ public class AudioUtils { | |||||||
|         return rVal; |         return rVal; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Plays a audio at a given audio file path at a given position | ||||||
|  |      * @param audioFile The audio file's path | ||||||
|  |      * @param position The position to play it at | ||||||
|  |      * @param loops If true, loops the source | ||||||
|  |      * @return The audio source | ||||||
|  |      */ | ||||||
|  |     protected static AudioSource playAudioAtLocation(String audioFile, Vector3d position, boolean loops){ | ||||||
|  |         return playAudioAtLocation(audioFile,new Vector3f((float)position.x,(float)position.y,(float)position.z),loops); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Plays an audio file |      * Plays an audio file | ||||||
|      * @param audioFile The audio file path |      * @param audioFile The audio file path | ||||||
|  | |||||||
| @ -0,0 +1,352 @@ | |||||||
|  | package electrosphere.entity.btree; | ||||||
|  | 
 | ||||||
|  | import java.util.function.Supplier; | ||||||
|  | 
 | ||||||
|  | import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; | ||||||
|  | import electrosphere.engine.Globals; | ||||||
|  | import electrosphere.entity.Entity; | ||||||
|  | import electrosphere.entity.EntityUtils; | ||||||
|  | import electrosphere.entity.state.client.firstPerson.FirstPersonTree; | ||||||
|  | import electrosphere.renderer.actor.Actor; | ||||||
|  | import electrosphere.server.poseactor.PoseActor; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * For a lot of behavior trees, there are states where we simply want to play an animation (ie a cooldown) | ||||||
|  |  * Those states can be registered with this utility object | ||||||
|  |  * When you simulate that specific state in the tree, instead ccall the simulation function from this handler | ||||||
|  |  * It will handle playing the animation in first and third person, playing audio, and transitioning to the next state once the animation has completed | ||||||
|  |  */ | ||||||
|  | public class StateTransitionUtil { | ||||||
|  |      | ||||||
|  |     //The list of simplified states within this util object | ||||||
|  |     StateTransitionUtilItem[] states; | ||||||
|  | 
 | ||||||
|  |     //The parent entity | ||||||
|  |     Entity parent; | ||||||
|  | 
 | ||||||
|  |     //tracks if this is the server or not | ||||||
|  |     boolean isServer; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Private constructor | ||||||
|  |      * @param states | ||||||
|  |      */ | ||||||
|  |     private StateTransitionUtil(Entity entity, boolean isServer, StateTransitionUtilItem[] states){ | ||||||
|  |         this.states = states; | ||||||
|  |         this.parent = entity; | ||||||
|  |         this.isServer = isServer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates a state transition util | ||||||
|  |      * @param entity The entity | ||||||
|  |      * @param states The states | ||||||
|  |      * @return The util object | ||||||
|  |      */ | ||||||
|  |     public static StateTransitionUtil create(Entity entity, boolean isServer, StateTransitionUtilItem[] states){ | ||||||
|  |         StateTransitionUtil rVal = new StateTransitionUtil(entity,isServer,states); | ||||||
|  | 
 | ||||||
|  |         //error checking | ||||||
|  |         if(!isServer && Globals.clientSceneWrapper.getScene().getEntityFromId(entity.getId()) == null){ | ||||||
|  |             throw new IllegalArgumentException("Tried to create state transition util with isServer=false and passed in a server entity"); | ||||||
|  |         } else if(isServer && Globals.clientSceneWrapper.getScene().getEntityFromId(entity.getId()) != null){ | ||||||
|  |             throw new IllegalArgumentException("Tried to create state transition util with isServer=true and passed in a client entity"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         return rVal; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Should be called every time the natural state progression is interrupted (ie if you call start() or stop()) | ||||||
|  |      */ | ||||||
|  |     public void reset(){ | ||||||
|  |         for(StateTransitionUtilItem state : states){ | ||||||
|  |             state.startedAnimation = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Simulates a given state | ||||||
|  |      * @param stateEnum The enum for the state | ||||||
|  |      */ | ||||||
|  |     public void simulate(Object stateEnum){ | ||||||
|  |         StateTransitionUtilItem state = null; | ||||||
|  |         for(StateTransitionUtilItem targetState : states){ | ||||||
|  |             if(targetState.stateEnum == stateEnum){ | ||||||
|  |                 state = targetState; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if(state == null){ | ||||||
|  |             throw new IllegalArgumentException("Trying to simulate state that is not registered with this util object"); | ||||||
|  |         } else { | ||||||
|  |             if(this.isServer){ | ||||||
|  |                 simulateServerState(this.parent,state); | ||||||
|  |             } else { | ||||||
|  |                 simulateClientState(this.parent,state); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Runs animation logic for client tree | ||||||
|  |      * @param parent The parent entity | ||||||
|  |      * @param state The state | ||||||
|  |      */ | ||||||
|  |     private static void simulateClientState(Entity parent, StateTransitionUtilItem state){ | ||||||
|  |         Actor actor = EntityUtils.getActor(parent); | ||||||
|  |         if(actor != null){ | ||||||
|  |             //determine the third person animation to play | ||||||
|  |             String animationToPlay = state.thirdPersonAnimation; | ||||||
|  |             if(animationToPlay == null && state.getThirdPersonAnimation != null){ | ||||||
|  |                 animationToPlay = state.getThirdPersonAnimation.get(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             //determine the first person animation to play | ||||||
|  |             String firstPersonAnimation = state.firstPersonAnimation; | ||||||
|  |             if(firstPersonAnimation == null && state.getFirstPersonAnimation != null){ | ||||||
|  |                 firstPersonAnimation = state.getFirstPersonAnimation.get(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             //Main simulation | ||||||
|  |             if(!actor.isPlayingAnimation() && state.onComplete != null && state.startedAnimation == true){ | ||||||
|  |                 //state transition if this isn't set to loop | ||||||
|  |                 state.onComplete.run(); | ||||||
|  |                 state.startedAnimation = false; | ||||||
|  |             } else if(!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay)){ | ||||||
|  |                 //play animation, audio, etc, for state | ||||||
|  |                 if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson()){ | ||||||
|  |                     //first person | ||||||
|  |                     //play first person audio | ||||||
|  |                     if(state.audioPath != null){ | ||||||
|  |                         Globals.virtualAudioSourceManager.createVirtualAudioSource(state.audioPath, VirtualAudioSourceType.CREATURE, false); | ||||||
|  |                     } | ||||||
|  |                     FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, firstPersonAnimation); | ||||||
|  |                 } else { | ||||||
|  |                     //play third person audio | ||||||
|  |                     if(state.audioPath != null){ | ||||||
|  |                         Globals.virtualAudioSourceManager.createVirtualAudioSource(state.audioPath, VirtualAudioSourceType.CREATURE, false, EntityUtils.getPosition(parent)); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 actor.playAnimation(animationToPlay,1); | ||||||
|  |                 actor.incrementAnimationTime(0.0001); | ||||||
|  |                 state.startedAnimation = true; | ||||||
|  |             } else if(animationToPlay == null && state.onComplete != null){ | ||||||
|  |                 state.onComplete.run(); | ||||||
|  |                 state.startedAnimation = false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Runs animation logic for server tree | ||||||
|  |      * @param parent The parent entity | ||||||
|  |      * @param state The state | ||||||
|  |      */ | ||||||
|  |     private static void simulateServerState(Entity parent, StateTransitionUtilItem state){ | ||||||
|  |         PoseActor poseActor = EntityUtils.getPoseActor(parent); | ||||||
|  |         if(poseActor != null){ | ||||||
|  |             //determine the third person animation to play | ||||||
|  |             String animationToPlay = state.thirdPersonAnimation; | ||||||
|  |             if(animationToPlay == null && state.getThirdPersonAnimation != null){ | ||||||
|  |                 animationToPlay = state.getThirdPersonAnimation.get(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             //Main simulation | ||||||
|  |             if(!poseActor.isPlayingAnimation() && state.onComplete != null && state.startedAnimation == true){ | ||||||
|  |                 //state transition if this isn't set to loop | ||||||
|  |                 state.onComplete.run(); | ||||||
|  |                 state.startedAnimation = false; | ||||||
|  |             } else if(animationToPlay != null && (!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay))){ | ||||||
|  |                 //play animation for state | ||||||
|  |                 poseActor.playAnimation(animationToPlay,1); | ||||||
|  |                 poseActor.incrementAnimationTime(0.0001); | ||||||
|  |                 state.startedAnimation = true; | ||||||
|  |             } else if(animationToPlay == null && state.onComplete != null){ | ||||||
|  |                 state.onComplete.run(); | ||||||
|  |                 state.startedAnimation = false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * A parameter used to construct a StateTransitionUtil | ||||||
|  |      */ | ||||||
|  |     public static class StateTransitionUtilItem { | ||||||
|  | 
 | ||||||
|  |         //The enum value for this state | ||||||
|  |         Object stateEnum; | ||||||
|  | 
 | ||||||
|  |         //T1he animation to play in first person | ||||||
|  |         String firstPersonAnimation; | ||||||
|  | 
 | ||||||
|  |         //Gets the first person animation's name | ||||||
|  |         Supplier<String> getFirstPersonAnimation; | ||||||
|  |          | ||||||
|  |         //The animation to play in third person | ||||||
|  |         String thirdPersonAnimation; | ||||||
|  | 
 | ||||||
|  |         //Gets the third person animation's name | ||||||
|  |         Supplier<String> getThirdPersonAnimation; | ||||||
|  |          | ||||||
|  |         //The audio path | ||||||
|  |         String audioPath; | ||||||
|  | 
 | ||||||
|  |         //The function to fire on completion (ie to transition to the next state) | ||||||
|  |         Runnable onComplete; | ||||||
|  | 
 | ||||||
|  |         //Tracks whether the animation has been played or not | ||||||
|  |         boolean startedAnimation = false; | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param firstPersonAnimation The animation to play in first person. If this is null, it will not play any animation in first person. | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          * @param audioPath The audio path to play when the animation starts. If this is null, it will not play any audio. | ||||||
|  |          * @param onComplete The function to fire on completion (ie to transition to the next state). If this is null, the animation and audio will be looped on completion. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             String firstPersonAnimation, | ||||||
|  |             String thirdPersonAnimation, | ||||||
|  |             String audioPath, | ||||||
|  |             Runnable onComplete | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.firstPersonAnimation = firstPersonAnimation; | ||||||
|  |             this.thirdPersonAnimation = thirdPersonAnimation; | ||||||
|  |             this.audioPath = audioPath; | ||||||
|  |             this.onComplete = onComplete; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param firstPersonAnimation The animation to play in first person. If this is null, it will not play any animation in first person. | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          * @param onComplete The function to fire on completion (ie to transition to the next state). If this is null, the animation and audio will be looped on completion. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             String firstPersonAnimation, | ||||||
|  |             String thirdPersonAnimation, | ||||||
|  |             Runnable onComplete | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.firstPersonAnimation = firstPersonAnimation; | ||||||
|  |             this.thirdPersonAnimation = thirdPersonAnimation; | ||||||
|  |             this.onComplete = onComplete; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param firstPersonAnimation The animation to play in first person. If this is null, it will not play any animation in first person. | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          * @param audioPath The audio path to play when the animation starts. If this is null, it will not play any audio. | ||||||
|  |          * @param onComplete The function to fire on completion (ie to transition to the next state). If this is null, the animation and audio will be looped on completion. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             Supplier<String> getFirstPersonAnimation, | ||||||
|  |             Supplier<String> getThirdPersonAnimation, | ||||||
|  |             String audioPath, | ||||||
|  |             Runnable onComplete | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.getFirstPersonAnimation = getFirstPersonAnimation; | ||||||
|  |             this.getThirdPersonAnimation = getThirdPersonAnimation; | ||||||
|  |             this.audioPath = audioPath; | ||||||
|  |             this.onComplete = onComplete; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param firstPersonAnimation The animation to play in first person. If this is null, it will not play any animation in first person. | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          * @param onComplete The function to fire on completion (ie to transition to the next state). If this is null, the animation and audio will be looped on completion. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             Supplier<String> getFirstPersonAnimation, | ||||||
|  |             Supplier<String> getThirdPersonAnimation, | ||||||
|  |             Runnable onComplete | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.getFirstPersonAnimation = getFirstPersonAnimation; | ||||||
|  |             this.getThirdPersonAnimation = getThirdPersonAnimation; | ||||||
|  |             this.onComplete = onComplete; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          * @param onComplete The function to fire on completion (ie to transition to the next state). If this is null, the animation and audio will be looped on completion. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             Supplier<String> getThirdPersonAnimation, | ||||||
|  |             Runnable onComplete | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.getThirdPersonAnimation = getThirdPersonAnimation; | ||||||
|  |             this.onComplete = onComplete; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param firstPersonAnimation The animation to play in first person. If this is null, it will not play any animation in first person. | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             Supplier<String> getFirstPersonAnimation, | ||||||
|  |             Supplier<String> getThirdPersonAnimation | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.getFirstPersonAnimation = getFirstPersonAnimation; | ||||||
|  |             this.getThirdPersonAnimation = getThirdPersonAnimation; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             Supplier<String> getThirdPersonAnimation | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.getThirdPersonAnimation = getThirdPersonAnimation; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Constructor | ||||||
|  |          * @param stateEnum The enum value for this state | ||||||
|  |          * @param thirdPersonAnimation The animation to play in third person. If this is null, it will not play any animation in third person. | ||||||
|  |          * @param onComplete The function to fire on completion (ie to transition to the next state). If this is null, the animation and audio will be looped on completion. | ||||||
|  |          */ | ||||||
|  |         public StateTransitionUtilItem( | ||||||
|  |             Object stateEnum, | ||||||
|  |             String thirdPersonAnimation, | ||||||
|  |             Runnable onComplete | ||||||
|  |             ){ | ||||||
|  |             this.stateEnum = stateEnum; | ||||||
|  |             this.thirdPersonAnimation = thirdPersonAnimation; | ||||||
|  |             this.onComplete = onComplete; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -4,15 +4,15 @@ package electrosphere.entity.state.block; | |||||||
| import electrosphere.engine.Globals; | import electrosphere.engine.Globals; | ||||||
| import electrosphere.entity.Entity; | import electrosphere.entity.Entity; | ||||||
| import electrosphere.entity.EntityDataStrings; | import electrosphere.entity.EntityDataStrings; | ||||||
| import electrosphere.entity.EntityUtils; |  | ||||||
| import electrosphere.entity.btree.BehaviorTree; | import electrosphere.entity.btree.BehaviorTree; | ||||||
|  | import electrosphere.entity.btree.StateTransitionUtil; | ||||||
|  | import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; | ||||||
| import electrosphere.game.data.creature.type.block.BlockSystem; | import electrosphere.game.data.creature.type.block.BlockSystem; | ||||||
| import electrosphere.net.synchronization.BehaviorTreeIdEnums; | import electrosphere.net.synchronization.BehaviorTreeIdEnums; | ||||||
| 
 | 
 | ||||||
| import electrosphere.net.synchronization.annotation.SyncedField; | import electrosphere.net.synchronization.annotation.SyncedField; | ||||||
| import electrosphere.net.synchronization.annotation.SynchronizableEnum; | import electrosphere.net.synchronization.annotation.SynchronizableEnum; | ||||||
| import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; | import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; | ||||||
| import electrosphere.renderer.actor.Actor; |  | ||||||
| 
 | 
 | ||||||
| @SynchronizedBehaviorTree(name = "clientBlockTree", isServer = false, correspondingTree="serverBlockTree") | @SynchronizedBehaviorTree(name = "clientBlockTree", isServer = false, correspondingTree="serverBlockTree") | ||||||
| /** | /** | ||||||
| @ -43,50 +43,45 @@ public class ClientBlockTree implements BehaviorTree { | |||||||
|     //The data for block animations |     //The data for block animations | ||||||
|     BlockSystem blockSystem; |     BlockSystem blockSystem; | ||||||
| 
 | 
 | ||||||
|  |     //The state transition util | ||||||
|  |     StateTransitionUtil stateTransitionUtil; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Constructor |      * Constructor | ||||||
|      */ |      */ | ||||||
|     private ClientBlockTree(Entity parent, BlockSystem blockSystem){ |     private ClientBlockTree(Entity parent, BlockSystem blockSystem){ | ||||||
|         this.parent = parent; |         this.parent = parent; | ||||||
|         this.blockSystem = blockSystem; |         this.blockSystem = blockSystem; | ||||||
|  |         this.stateTransitionUtil = StateTransitionUtil.create(parent, false, new StateTransitionUtilItem[]{ | ||||||
|  |             new StateTransitionUtilItem( | ||||||
|  |                 BlockState.WIND_UP, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getWindUpFirstPersonAnimation();}, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getWindUpAnimation();} | ||||||
|  |             ), | ||||||
|  |             new StateTransitionUtilItem( | ||||||
|  |                 BlockState.BLOCKING, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getMainFirstPersonAnimation();}, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getMainAnimation();} | ||||||
|  |             ), | ||||||
|  |             new StateTransitionUtilItem( | ||||||
|  |                 BlockState.COOLDOWN, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getCooldownFirstPersonAnimation();}, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getCooldownAnimation();} | ||||||
|  |             ), | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void simulate(float deltaTime) { |     public void simulate(float deltaTime) { | ||||||
|         Actor actor = EntityUtils.getActor(parent); |  | ||||||
|         switch(state){ |         switch(state){ | ||||||
|             case WIND_UP: { |             case WIND_UP: { | ||||||
|                 if(actor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){ |                 this.stateTransitionUtil.simulate(BlockState.WIND_UP); | ||||||
|                     String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getWindUpAnimation(); |  | ||||||
|                     if( |  | ||||||
|                         !actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay) |  | ||||||
|                     ){ |  | ||||||
|                         actor.playAnimation(animationToPlay,1); |  | ||||||
|                         actor.incrementAnimationTime(0.0001); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } break; |             } break; | ||||||
|             case BLOCKING: { |             case BLOCKING: { | ||||||
|                 if(actor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){ |                 this.stateTransitionUtil.simulate(BlockState.BLOCKING); | ||||||
|                     String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getMainAnimation(); |  | ||||||
|                     if( |  | ||||||
|                         !actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay) |  | ||||||
|                     ){ |  | ||||||
|                         actor.playAnimation(animationToPlay,1); |  | ||||||
|                         actor.incrementAnimationTime(0.0001); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } break; |             } break; | ||||||
|             case COOLDOWN: { |             case COOLDOWN: { | ||||||
|                 if(actor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){ |                 this.stateTransitionUtil.simulate(BlockState.COOLDOWN); | ||||||
|                     String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getCooldownAnimation(); |  | ||||||
|                     if( |  | ||||||
|                         !actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay) |  | ||||||
|                     ){ |  | ||||||
|                         actor.playAnimation(animationToPlay,1); |  | ||||||
|                         actor.incrementAnimationTime(0.0001); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } break; |             } break; | ||||||
|             case NOT_BLOCKING: { |             case NOT_BLOCKING: { | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,12 +5,12 @@ import electrosphere.net.synchronization.FieldIdEnums; | |||||||
| import electrosphere.engine.Globals; | import electrosphere.engine.Globals; | ||||||
| import electrosphere.entity.Entity; | import electrosphere.entity.Entity; | ||||||
| import electrosphere.entity.EntityDataStrings; | import electrosphere.entity.EntityDataStrings; | ||||||
| import electrosphere.entity.EntityUtils; |  | ||||||
| import electrosphere.entity.btree.BehaviorTree; | import electrosphere.entity.btree.BehaviorTree; | ||||||
|  | import electrosphere.entity.btree.StateTransitionUtil; | ||||||
|  | import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; | ||||||
| import electrosphere.net.synchronization.BehaviorTreeIdEnums; | import electrosphere.net.synchronization.BehaviorTreeIdEnums; | ||||||
| 
 | 
 | ||||||
| import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils; | import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils; | ||||||
| import electrosphere.server.poseactor.PoseActor; |  | ||||||
| import electrosphere.net.parser.net.message.SynchronizationMessage; | import electrosphere.net.parser.net.message.SynchronizationMessage; | ||||||
| 
 | 
 | ||||||
| import electrosphere.server.datacell.utils.DataCellSearchUtils; | import electrosphere.server.datacell.utils.DataCellSearchUtils; | ||||||
| @ -38,18 +38,38 @@ public class ServerBlockTree implements BehaviorTree { | |||||||
|     //The data for block animations |     //The data for block animations | ||||||
|     BlockSystem blockSystem; |     BlockSystem blockSystem; | ||||||
| 
 | 
 | ||||||
|  |     //The state transition util | ||||||
|  |     StateTransitionUtil stateTransitionUtil; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Constructor |      * Constructor | ||||||
|      */ |      */ | ||||||
|     private ServerBlockTree(Entity parent, BlockSystem blockSystem){ |     private ServerBlockTree(Entity parent, BlockSystem blockSystem){ | ||||||
|         this.parent = parent; |         this.parent = parent; | ||||||
|         this.blockSystem = blockSystem; |         this.blockSystem = blockSystem; | ||||||
|  |         this.stateTransitionUtil = StateTransitionUtil.create(parent, true, new StateTransitionUtilItem[]{ | ||||||
|  |             new StateTransitionUtilItem( | ||||||
|  |                 BlockState.WIND_UP, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getWindUpAnimation();}, | ||||||
|  |                 () -> {this.setState(BlockState.BLOCKING);} | ||||||
|  |             ), | ||||||
|  |             new StateTransitionUtilItem( | ||||||
|  |                 BlockState.BLOCKING, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getMainAnimation();} | ||||||
|  |             ), | ||||||
|  |             new StateTransitionUtilItem( | ||||||
|  |                 BlockState.COOLDOWN, | ||||||
|  |                 () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getCooldownAnimation();}, | ||||||
|  |                 () -> {this.setState(BlockState.NOT_BLOCKING);} | ||||||
|  |             ), | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Starts the block tree |      * Starts the block tree | ||||||
|      */ |      */ | ||||||
|     public void start(){ |     public void start(){ | ||||||
|  |         this.stateTransitionUtil.reset(); | ||||||
|         setState(BlockState.WIND_UP); |         setState(BlockState.WIND_UP); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -57,45 +77,21 @@ public class ServerBlockTree implements BehaviorTree { | |||||||
|      * Stops the block tree |      * Stops the block tree | ||||||
|      */ |      */ | ||||||
|     public void stop(){ |     public void stop(){ | ||||||
|  |         this.stateTransitionUtil.reset(); | ||||||
|         setState(BlockState.COOLDOWN); |         setState(BlockState.COOLDOWN); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void simulate(float deltaTime) { |     public void simulate(float deltaTime) { | ||||||
|         PoseActor poseActor = EntityUtils.getPoseActor(parent); |  | ||||||
|         switch(state){ |         switch(state){ | ||||||
|             case WIND_UP: { |             case WIND_UP: { | ||||||
|                 if(poseActor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){ |                 this.stateTransitionUtil.simulate(BlockState.WIND_UP); | ||||||
|                     String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getWindUpAnimation(); |  | ||||||
|                     if( |  | ||||||
|                         !poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) |  | ||||||
|                     ){ |  | ||||||
|                         poseActor.playAnimation(animationToPlay,1); |  | ||||||
|                         poseActor.incrementAnimationTime(0.0001); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } break; |             } break; | ||||||
|             case BLOCKING: { |             case BLOCKING: { | ||||||
|                 if(poseActor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){ |                 this.stateTransitionUtil.simulate(BlockState.BLOCKING); | ||||||
|                     String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getMainAnimation(); |  | ||||||
|                     if( |  | ||||||
|                         !poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) |  | ||||||
|                     ){ |  | ||||||
|                         poseActor.playAnimation(animationToPlay,1); |  | ||||||
|                         poseActor.incrementAnimationTime(0.0001); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } break; |             } break; | ||||||
|             case COOLDOWN: { |             case COOLDOWN: { | ||||||
|                 if(poseActor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){ |                 this.stateTransitionUtil.simulate(BlockState.COOLDOWN); | ||||||
|                     String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getCooldownAnimation(); |  | ||||||
|                     if( |  | ||||||
|                         !poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) |  | ||||||
|                     ){ |  | ||||||
|                         poseActor.playAnimation(animationToPlay,1); |  | ||||||
|                         poseActor.incrementAnimationTime(0.0001); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } break; |             } break; | ||||||
|             case NOT_BLOCKING: { |             case NOT_BLOCKING: { | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -21,6 +21,15 @@ public class BlockVariant { | |||||||
|     //the animation to play when cooling down |     //the animation to play when cooling down | ||||||
|     String cooldownAnimation; |     String cooldownAnimation; | ||||||
| 
 | 
 | ||||||
|  |     //the animation to play in first person when winding up | ||||||
|  |     String windUpFirstPersonAnimation; | ||||||
|  | 
 | ||||||
|  |     //the main animation to play in first person while blocking | ||||||
|  |     String mainFirstPersonAnimation; | ||||||
|  | 
 | ||||||
|  |     //the animation to play in first person when cooling down | ||||||
|  |     String cooldownFirstPersonAnimation; | ||||||
|  | 
 | ||||||
|     //the list of default equipment cases that this variant should be used for |     //the list of default equipment cases that this variant should be used for | ||||||
|     List<VariantDefaults> defaults; |     List<VariantDefaults> defaults; | ||||||
| 
 | 
 | ||||||
| @ -56,6 +65,30 @@ public class BlockVariant { | |||||||
|         return cooldownAnimation; |         return cooldownAnimation; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * The animation to play in first person when winding up | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     public String getWindUpFirstPersonAnimation(){ | ||||||
|  |         return windUpFirstPersonAnimation; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * The main animation to play in first person while blocking | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     public String getMainFirstPersonAnimation(){ | ||||||
|  |         return mainFirstPersonAnimation; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * The animation to play in first person when cooling down | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     public String getCooldownFirstPersonAnimation(){ | ||||||
|  |         return cooldownFirstPersonAnimation; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * the list of default equipment cases that this variant should be used for |      * the list of default equipment cases that this variant should be used for | ||||||
|      * @return |      * @return | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user