client animation offset by network delay
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
e9257784c6
commit
d15ba2445a
BIN
assets/Audio/weapons/collisions/FleshWeaponHit1.wav
Normal file
BIN
assets/Audio/weapons/collisions/FleshWeaponHit1.wav
Normal file
Binary file not shown.
@ -580,6 +580,8 @@ Walk tree
|
||||
Slow down strafe movement somehow
|
||||
Better creature damage sfx
|
||||
Audio debugging
|
||||
Play animations offset by network delay
|
||||
- Attack animation
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
@ -172,6 +172,20 @@ public class AudioEngine {
|
||||
LoggerInterface.loggerAudio.INFO(audioType.getExtension() + " support: " + AudioSystem.isFileTypeSupported(audioType));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the support formats
|
||||
* @return The list of file extensions
|
||||
*/
|
||||
public List<String> getSupportedFormats(){
|
||||
List<String> rVal = new LinkedList<String>();
|
||||
for(AudioFileFormat.Type audioType : AudioSystem.getAudioFileTypes()){
|
||||
if(AudioSystem.isFileTypeSupported(audioType)){
|
||||
rVal.add(audioType.getExtension());
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the orientation of the listener based on the global player camera
|
||||
|
||||
@ -22,7 +22,7 @@ public class HitboxAudioService {
|
||||
* Default audio files to play. Eventually should probably refactor into service that determines audio based on materials
|
||||
*/
|
||||
static String[] defaultHitboxAudio = new String[]{
|
||||
"Audio/weapons/collisions/FleshWeaponHit1.ogg",
|
||||
"Audio/weapons/collisions/FleshWeaponHit1.wav",
|
||||
// "Audio/weapons/collisions/Massive Punch B.wav",
|
||||
// "Audio/weapons/collisions/Massive Punch C.wav",
|
||||
};
|
||||
|
||||
@ -475,7 +475,7 @@ public class Globals {
|
||||
"/Audio/weapons/swordUnsheath1.ogg",
|
||||
"/Audio/weapons/swoosh-03.ogg",
|
||||
"/Audio/movement/Equip A.wav",
|
||||
"/Audio/weapons/collisions/FleshWeaponHit1.ogg",
|
||||
"/Audio/weapons/collisions/FleshWeaponHit1.wav",
|
||||
"/Audio/weapons/collisions/Massive Punch A.wav",
|
||||
"/Audio/weapons/collisions/Massive Punch B.wav",
|
||||
"/Audio/weapons/collisions/Massive Punch C.wav",
|
||||
|
||||
@ -31,6 +31,9 @@ public class StateTransitionUtil {
|
||||
//tracks if this is the server or not
|
||||
boolean isServer;
|
||||
|
||||
//If set to true on client, will account for delay between client and server when starting animations
|
||||
boolean accountForSync = false;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
* @param states
|
||||
@ -70,6 +73,14 @@ public class StateTransitionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the client will account for delay over network or not
|
||||
* @param accountForSync true if account for delay, false otherwise
|
||||
*/
|
||||
public void setAccountForSync(boolean accountForSync){
|
||||
this.accountForSync = accountForSync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates a given state
|
||||
* @param stateEnum The enum for the state
|
||||
@ -98,7 +109,8 @@ public class StateTransitionUtil {
|
||||
* @param parent The parent entity
|
||||
* @param state The state
|
||||
*/
|
||||
private static void simulateClientState(Entity parent, StateTransitionUtilItem state){
|
||||
private void simulateClientState(Entity parent, StateTransitionUtilItem state){
|
||||
boolean shouldPlayFirstPerson = false;
|
||||
Actor actor = EntityUtils.getActor(parent);
|
||||
if(actor != null){
|
||||
|
||||
@ -113,6 +125,15 @@ public class StateTransitionUtil {
|
||||
audioData = state.getAudio.get();
|
||||
}
|
||||
|
||||
//
|
||||
//Calculate offset to start the animation at
|
||||
double animationOffset = 0.0001;
|
||||
if(this.accountForSync){
|
||||
int delay = Globals.clientConnection.getDelay();
|
||||
double simFrameTime = Globals.timekeeper.getSimFrameTime();
|
||||
animationOffset = delay * simFrameTime;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//Play main animation
|
||||
@ -122,24 +143,35 @@ public class StateTransitionUtil {
|
||||
state.onComplete.run();
|
||||
state.startedAnimation = false;
|
||||
} else if(!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animation)){
|
||||
//play animation, audio, etc, for state
|
||||
if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson() && animation != null){
|
||||
//first person
|
||||
//play first person audio
|
||||
if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false);
|
||||
}
|
||||
} else {
|
||||
//play third person audio
|
||||
if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false, EntityUtils.getPosition(parent));
|
||||
}
|
||||
}
|
||||
|
||||
if(animation != null){
|
||||
actor.playAnimation(animation,true);
|
||||
//
|
||||
//if it isn't looping, only play on first go around
|
||||
if(state.loop || !state.startedAnimation){
|
||||
|
||||
|
||||
//
|
||||
//play audio
|
||||
if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson() && animation != null){
|
||||
//first person
|
||||
//play first person audio
|
||||
if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false);
|
||||
}
|
||||
} else {
|
||||
//play third person audio
|
||||
if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false, EntityUtils.getPosition(parent));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//play animation
|
||||
if(animation != null){
|
||||
actor.playAnimation(animation,true);
|
||||
shouldPlayFirstPerson = true;
|
||||
}
|
||||
actor.incrementAnimationTime(animationOffset);
|
||||
}
|
||||
actor.incrementAnimationTime(0.0001);
|
||||
state.startedAnimation = true;
|
||||
} else if(state.animation == null && state.onComplete != null){
|
||||
state.onComplete.run();
|
||||
@ -149,8 +181,8 @@ public class StateTransitionUtil {
|
||||
//
|
||||
//Play animation in first person
|
||||
//
|
||||
if(animation != null){
|
||||
FirstPersonTree.conditionallyPlayAnimation(parent, animation);
|
||||
if(shouldPlayFirstPerson && animation != null){
|
||||
FirstPersonTree.conditionallyPlayAnimation(parent, animation, animationOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,7 +192,7 @@ public class StateTransitionUtil {
|
||||
* @param parent The parent entity
|
||||
* @param state The state
|
||||
*/
|
||||
private static void simulateServerState(Entity parent, StateTransitionUtilItem state){
|
||||
private void simulateServerState(Entity parent, StateTransitionUtilItem state){
|
||||
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||
if(poseActor != null){
|
||||
|
||||
@ -185,11 +217,14 @@ public class StateTransitionUtil {
|
||||
state.onComplete.run();
|
||||
state.startedAnimation = false;
|
||||
} else if(!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animation)){
|
||||
//play animation for state
|
||||
if(animation != null){
|
||||
poseActor.playAnimation(animation);
|
||||
//if it isn't looping, only play on first go around
|
||||
if(state.loop || !state.startedAnimation){
|
||||
//play animation for state
|
||||
if(animation != null){
|
||||
poseActor.playAnimation(animation);
|
||||
}
|
||||
poseActor.incrementAnimationTime(0.0001);
|
||||
}
|
||||
poseActor.incrementAnimationTime(0.0001);
|
||||
state.startedAnimation = true;
|
||||
}
|
||||
}
|
||||
@ -299,6 +334,9 @@ public class StateTransitionUtil {
|
||||
//The function to fire on completion (ie to transition to the next state)
|
||||
Runnable onComplete;
|
||||
|
||||
//Controls whether the state transition util should loop or not
|
||||
boolean loop = true;
|
||||
|
||||
//Tracks whether the animation has been played or not
|
||||
boolean startedAnimation = false;
|
||||
|
||||
@ -315,6 +353,24 @@ public class StateTransitionUtil {
|
||||
this.animation = animation;
|
||||
this.audioData = audioData;
|
||||
this.onComplete = onComplete;
|
||||
if(this.onComplete != null){
|
||||
this.loop = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private StateTransitionUtilItem(
|
||||
Object stateEnum,
|
||||
TreeDataAnimation animation,
|
||||
TreeDataAudio audioData,
|
||||
boolean loop
|
||||
){
|
||||
this.stateEnum = stateEnum;
|
||||
this.animation = animation;
|
||||
this.audioData = audioData;
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -330,6 +386,24 @@ public class StateTransitionUtil {
|
||||
this.getAnimation = getAnimation;
|
||||
this.getAudio = getAudio;
|
||||
this.onComplete = onComplete;
|
||||
if(this.onComplete != null){
|
||||
this.loop = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for supplier type
|
||||
*/
|
||||
private StateTransitionUtilItem(
|
||||
Object stateEnum,
|
||||
Supplier<TreeDataAnimation> getAnimation,
|
||||
Supplier<TreeDataAudio> getAudio,
|
||||
boolean loop
|
||||
){
|
||||
this.stateEnum = stateEnum;
|
||||
this.getAnimation = getAnimation;
|
||||
this.getAudio = getAudio;
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -355,6 +429,30 @@ public class StateTransitionUtil {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a supplier-based approach. This takes suppliers that will provide animation data on demand.
|
||||
* This decouples the animations from the initialization of the tree.
|
||||
* The intended usecase is if the animation could change based on some state in the tree.
|
||||
* @param stateEnum The enum value for this state
|
||||
* @param getAnimationData The supplier for the animation data. If it is null, it will not play any animation
|
||||
* @param getAudio The supplier for path to an audio file to play on starting the animation. If null, no audio will be played
|
||||
* @param loop Sets whether the animation should loop or not
|
||||
* @return
|
||||
*/
|
||||
public static StateTransitionUtilItem create(
|
||||
Object stateEnum,
|
||||
Supplier<TreeDataAnimation> getAnimation,
|
||||
Supplier<TreeDataAudio> getAudio,
|
||||
boolean loop
|
||||
){
|
||||
return new StateTransitionUtilItem(
|
||||
stateEnum,
|
||||
getAnimation,
|
||||
getAudio,
|
||||
loop
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a state transition based on tree data for the state
|
||||
* @param stateEnum The enum value for this state in particular in the tree
|
||||
@ -385,6 +483,37 @@ public class StateTransitionUtil {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a state transition based on tree data for the state
|
||||
* @param stateEnum The enum value for this state in particular in the tree
|
||||
* @param treeData The tree data for this state
|
||||
* @param loop Controls whether the state loops its animation or not
|
||||
* @return The item for the transition util
|
||||
*/
|
||||
public static StateTransitionUtilItem create(
|
||||
Object stateEnum,
|
||||
TreeDataState treeData,
|
||||
boolean loop
|
||||
){
|
||||
StateTransitionUtilItem rVal = null;
|
||||
if(treeData != null){
|
||||
rVal = new StateTransitionUtilItem(
|
||||
stateEnum,
|
||||
treeData.getAnimation(),
|
||||
treeData.getAudioData(),
|
||||
loop
|
||||
);
|
||||
} else {
|
||||
rVal = new StateTransitionUtilItem(
|
||||
stateEnum,
|
||||
(TreeDataAnimation)null,
|
||||
null,
|
||||
loop
|
||||
);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
}
|
||||
|
||||
//the current state of the tree
|
||||
@SyncedField
|
||||
@SyncedField(serverSendTransitionPacket = true)
|
||||
AttackTreeState state;
|
||||
|
||||
//the current state of drifting caused by the tree
|
||||
@ -126,7 +126,7 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
return state.getAudioData();
|
||||
}
|
||||
},
|
||||
null
|
||||
false
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.HOLD,
|
||||
@ -152,7 +152,7 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
return state.getAudioData();
|
||||
}
|
||||
},
|
||||
null
|
||||
true
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.ATTACK,
|
||||
@ -178,7 +178,7 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
return state.getAudioData();
|
||||
}
|
||||
},
|
||||
null
|
||||
false
|
||||
),
|
||||
StateTransitionUtilItem.create(
|
||||
AttackTreeState.COOLDOWN,
|
||||
@ -204,9 +204,10 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
return state.getAudioData();
|
||||
}
|
||||
},
|
||||
null
|
||||
false
|
||||
),
|
||||
});
|
||||
this.stateTransitionUtil.setAccountForSync(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -668,4 +669,17 @@ public class ClientAttackTree implements BehaviorTree {
|
||||
public void setCurrentMoveId(String currentMoveId){
|
||||
this.currentMoveId = currentMoveId;
|
||||
}
|
||||
/**
|
||||
* <p> (Initially) Automatically Generated </p>
|
||||
* <p>
|
||||
* Performs a state transition on a client state variable.
|
||||
* Will be triggered when a server performs a state change.
|
||||
* </p>
|
||||
* @param newState The new value of the state
|
||||
*/
|
||||
public void transitionState(AttackTreeState newState){
|
||||
this.stateTransitionUtil.reset();
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ import org.joml.Vector3f;
|
||||
*/
|
||||
public class ServerAttackTree implements BehaviorTree {
|
||||
|
||||
@SyncedField
|
||||
@SyncedField(serverSendTransitionPacket = true)
|
||||
//the state of the attack tree
|
||||
AttackTreeState state;
|
||||
|
||||
@ -220,6 +220,7 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Trying to start attacking tree, but current move does not have windup or attack states defined!"));
|
||||
}
|
||||
this.stateTransitionUtil.reset();
|
||||
//intuit can hold from presence of windup anim
|
||||
currentMoveCanHold = currentMove.getHoldState() != null;
|
||||
//clear collided list
|
||||
@ -601,7 +602,7 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
public void setState(AttackTreeState state){
|
||||
this.state = state;
|
||||
int value = ClientAttackTree.getAttackTreeStateEnumAsShort(state);
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID, FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID, value));
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructServerNotifyBTreeTransitionMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID, FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID, value));
|
||||
}
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
|
||||
@ -93,6 +93,16 @@ public class FirstPersonTree implements BehaviorTree {
|
||||
* @param animationName the name of the animation
|
||||
*/
|
||||
public void playAnimation(String animationName, int priority){
|
||||
this.playAnimation(animationName, priority, 0.0001);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays an animation if it exists
|
||||
* @param animationName the name of the animation
|
||||
* @param priority The priority to play the animation with
|
||||
* @param offset The offset to start the animation at
|
||||
*/
|
||||
public void playAnimation(String animationName, int priority, double offset){
|
||||
if(Globals.firstPersonEntity != null){
|
||||
Actor actor = EntityUtils.getActor(Globals.firstPersonEntity);
|
||||
if(
|
||||
@ -100,7 +110,7 @@ public class FirstPersonTree implements BehaviorTree {
|
||||
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(animationName) != null)
|
||||
){
|
||||
actor.playAnimation(animationName,priority);
|
||||
actor.incrementAnimationTime(0.0001);
|
||||
actor.incrementAnimationTime(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,6 +120,15 @@ public class FirstPersonTree implements BehaviorTree {
|
||||
* @param animationName the name of the animation
|
||||
*/
|
||||
public void playAnimation(TreeDataAnimation animation){
|
||||
this.playAnimation(animation, 0.0001);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays an animation if it exists
|
||||
* @param animationName the name of the animation
|
||||
* @param offset The offset to start the animation at
|
||||
*/
|
||||
public void playAnimation(TreeDataAnimation animation, double offset){
|
||||
if(Globals.firstPersonEntity != null){
|
||||
Actor actor = EntityUtils.getActor(Globals.firstPersonEntity);
|
||||
if(
|
||||
@ -117,7 +136,7 @@ public class FirstPersonTree implements BehaviorTree {
|
||||
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(animation.getNameFirstPerson()) != null)
|
||||
){
|
||||
actor.playAnimation(animation, false);
|
||||
actor.incrementAnimationTime(0.0001);
|
||||
actor.incrementAnimationTime(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,12 +163,22 @@ public class FirstPersonTree implements BehaviorTree {
|
||||
* @param animationName the name of the animation
|
||||
* @param priority The priority of the animation
|
||||
*/
|
||||
public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority){
|
||||
public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority, double offset){
|
||||
if(entity != null && entity == Globals.playerEntity && FirstPersonTree.hasTree(Globals.firstPersonEntity)){
|
||||
FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animationName, priority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the entity has a first person tree, plays the provided animation
|
||||
* @param entity The entity
|
||||
* @param animationName the name of the animation
|
||||
* @param priority The priority of the animation
|
||||
*/
|
||||
public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority){
|
||||
FirstPersonTree.conditionallyPlayAnimation(entity, animationName, priority, 0.0001);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the entity has a first person tree, plays the provided animation
|
||||
* @param entity The entity
|
||||
@ -160,6 +189,18 @@ public class FirstPersonTree implements BehaviorTree {
|
||||
FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the entity has a first person tree, plays the provided animation
|
||||
* @param entity The entity
|
||||
* @param animationName the name of the animation
|
||||
* @param offset The offset to start the animation at
|
||||
*/
|
||||
public static void conditionallyPlayAnimation(Entity entity, TreeDataAnimation animation, double offset){
|
||||
if(entity != null && entity == Globals.playerEntity && FirstPersonTree.hasTree(Globals.firstPersonEntity)){
|
||||
FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animation,offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the entity has a first person tree, interrupts the provided animation
|
||||
|
||||
@ -42,6 +42,11 @@ public class ImGuiAudio {
|
||||
ImGui.text("Listener location: " + Globals.audioEngine.getListener().getPosition());
|
||||
ImGui.text("Listener eye vector: " + Globals.audioEngine.getListener().getEyeVector());
|
||||
ImGui.text("Listener up vector: " + Globals.audioEngine.getListener().getUpVector());
|
||||
if(ImGui.collapsingHeader("Supported (Java-loaded) formats")){
|
||||
for(String extension : Globals.audioEngine.getSupportedFormats()){
|
||||
ImGui.text(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
//only active children
|
||||
if(ImGui.collapsingHeader("Mapped Virtual Sources")){
|
||||
|
||||
@ -204,6 +204,14 @@ public class ClientNetworking implements Runnable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the delay across the connection
|
||||
* @return The delay
|
||||
*/
|
||||
public int getDelay(){
|
||||
return (int)(lastPongTime - lastPingTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -245,6 +245,14 @@ public class ClientSynchronizationManager {
|
||||
*/
|
||||
private void transitionBTree(Entity entity, int bTreeId, SynchronizationMessage message){
|
||||
switch(bTreeId){
|
||||
case BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID: {
|
||||
switch(message.getfieldId()){
|
||||
case FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID:{
|
||||
ClientAttackTree tree = ClientAttackTree.getClientAttackTree(entity);
|
||||
tree.transitionState(ClientAttackTree.getAttackTreeStateShortAsEnum((short)message.getbTreeValue()));
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: {
|
||||
switch(message.getfieldId()){
|
||||
case FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID:{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user