state interrupts and transition packets
This commit is contained in:
parent
d319f05a2e
commit
2c42de3882
@ -113,6 +113,16 @@
|
||||
"bTreeValue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "ServerNotifyBTreeTransition",
|
||||
"description" : "Packet from the server to the client notifying the client that it should transition a btree from one state to another",
|
||||
"data" : [
|
||||
"entityId",
|
||||
"bTreeId",
|
||||
"fieldId",
|
||||
"bTreeValue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "AttachTree",
|
||||
"description" : "Attaches a btree to an entity on the client",
|
||||
|
||||
@ -191,6 +191,87 @@ public class StateTransitionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts a given state
|
||||
* @param stateEnum The state enum
|
||||
*/
|
||||
public void interrupt(Object stateEnum){
|
||||
StateTransitionUtilItem state = null;
|
||||
for(StateTransitionUtilItem targetState : states){
|
||||
if(targetState.stateEnum == stateEnum){
|
||||
state = targetState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(state == null){
|
||||
LoggerInterface.loggerEngine.DEBUG("Skipping state " + stateEnum + " because there is not a state registered to that enum value!");
|
||||
} else {
|
||||
if(this.isServer){
|
||||
interruptServerState(this.parent,state);
|
||||
} else {
|
||||
interruptClientState(this.parent,state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts animation logic for client tree
|
||||
* @param parent The parent entity
|
||||
* @param state The state
|
||||
*/
|
||||
private static void interruptClientState(Entity parent, StateTransitionUtilItem state){
|
||||
Actor actor = EntityUtils.getActor(parent);
|
||||
if(actor != null){
|
||||
|
||||
//get the animation to play
|
||||
TreeDataAnimation animation = state.animation;
|
||||
if(state.getAnimation != null && state.getAnimation.get() != null){
|
||||
animation = state.getAnimation.get();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//Interrupt main animation
|
||||
//
|
||||
if(animation != null && actor.isPlayingAnimation() && actor.isPlayingAnimation(animation)){
|
||||
actor.interruptAnimation(animation, true);
|
||||
}
|
||||
|
||||
//
|
||||
//Interrupt animation in first person
|
||||
//
|
||||
if(animation != null){
|
||||
FirstPersonTree.conditionallyInterruptAnimation(Globals.firstPersonEntity, animation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts animation logic for server tree
|
||||
* @param parent The parent entity
|
||||
* @param state The state
|
||||
*/
|
||||
private static void interruptServerState(Entity parent, StateTransitionUtilItem state){
|
||||
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||
if(poseActor != null){
|
||||
|
||||
//get the animation to play
|
||||
TreeDataAnimation animation = state.animation;
|
||||
if(state.getAnimation != null && state.getAnimation.get() != null){
|
||||
animation = state.getAnimation.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Interrupt main animation
|
||||
//
|
||||
if(animation != null && poseActor.isPlayingAnimation() && poseActor.isPlayingAnimation(animation)){
|
||||
poseActor.interruptAnimation(animation, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A parameter used to construct a StateTransitionUtil
|
||||
*/
|
||||
|
||||
@ -31,7 +31,7 @@ public class ClientBlockTree implements BehaviorTree {
|
||||
NOT_BLOCKING,
|
||||
}
|
||||
|
||||
@SyncedField
|
||||
@SyncedField(serverSendTransitionPacket = true)
|
||||
BlockState state = BlockState.NOT_BLOCKING; //the current state
|
||||
|
||||
//the parent entity to this tree
|
||||
@ -74,6 +74,31 @@ public class ClientBlockTree implements BehaviorTree {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* <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(BlockState newState){
|
||||
this.setState(newState);
|
||||
switch(newState){
|
||||
case WIND_UP: {
|
||||
} break;
|
||||
case BLOCKING: {
|
||||
this.stateTransitionUtil.interrupt(BlockState.WIND_UP);
|
||||
} break;
|
||||
case COOLDOWN: {
|
||||
this.stateTransitionUtil.interrupt(BlockState.BLOCKING);
|
||||
} break;
|
||||
case NOT_BLOCKING: {
|
||||
this.stateTransitionUtil.interrupt(BlockState.COOLDOWN);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simulate(float deltaTime) {
|
||||
switch(state){
|
||||
|
||||
@ -26,7 +26,7 @@ import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||
*/
|
||||
public class ServerBlockTree implements BehaviorTree {
|
||||
|
||||
@SyncedField
|
||||
@SyncedField(serverSendTransitionPacket = true)
|
||||
BlockState state = BlockState.NOT_BLOCKING; //the current state of the tree
|
||||
|
||||
//the parent entity to this tree
|
||||
@ -152,7 +152,7 @@ public class ServerBlockTree implements BehaviorTree {
|
||||
public void setState(BlockState state){
|
||||
this.state = state;
|
||||
int value = ClientBlockTree.getBlockStateEnumAsShort(state);
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID, FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID, value));
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructServerNotifyBTreeTransitionMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID, FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID, value));
|
||||
}
|
||||
/**
|
||||
* <p> (initially) Automatically generated </p>
|
||||
|
||||
@ -27,6 +27,7 @@ public class SynchronizationProtocol implements ClientProtocolTemplate<Synchroni
|
||||
case UPDATECLIENTLONGSTATE:
|
||||
case ATTACHTREE:
|
||||
case DETATCHTREE:
|
||||
case SERVERNOTIFYBTREETRANSITION:
|
||||
Globals.clientSynchronizationManager.pushMessage(message);
|
||||
break;
|
||||
case LOADSCENE:
|
||||
|
||||
@ -371,6 +371,11 @@ SYNCHRONIZATION_MESSAGE,
|
||||
rVal = SynchronizationMessage.parseClientRequestBTreeActionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION:
|
||||
if(SynchronizationMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = SynchronizationMessage.parseServerNotifyBTreeTransitionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE:
|
||||
if(SynchronizationMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = SynchronizationMessage.parseAttachTreeMessage(byteBuffer);
|
||||
|
||||
@ -15,6 +15,7 @@ public class SynchronizationMessage extends NetworkMessage {
|
||||
UPDATECLIENTFLOATSTATE,
|
||||
UPDATECLIENTDOUBLESTATE,
|
||||
CLIENTREQUESTBTREEACTION,
|
||||
SERVERNOTIFYBTREETRANSITION,
|
||||
ATTACHTREE,
|
||||
DETATCHTREE,
|
||||
LOADSCENE,
|
||||
@ -156,6 +157,12 @@ public class SynchronizationMessage extends NetworkMessage {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE_SIZE){
|
||||
return true;
|
||||
@ -340,6 +347,26 @@ public class SynchronizationMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage parseServerNotifyBTreeTransitionMessage(CircularByteBuffer byteBuffer){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.SERVERNOTIFYBTREETRANSITION);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage constructServerNotifyBTreeTransitionMessage(int entityId,int bTreeId,int fieldId,int bTreeValue){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.SERVERNOTIFYBTREETRANSITION);
|
||||
rVal.setentityId(entityId);
|
||||
rVal.setbTreeId(bTreeId);
|
||||
rVal.setfieldId(fieldId);
|
||||
rVal.setbTreeValue(bTreeValue);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage parseAttachTreeMessage(CircularByteBuffer byteBuffer){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.ATTACHTREE);
|
||||
stripPacketHeader(byteBuffer);
|
||||
@ -570,6 +597,29 @@ public class SynchronizationMessage extends NetworkMessage {
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
case SERVERNOTIFYBTREETRANSITION:
|
||||
rawBytes = new byte[2+4+4+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeValue);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[14+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
case ATTACHTREE:
|
||||
rawBytes = new byte[2+4+4];
|
||||
//message header
|
||||
|
||||
@ -152,9 +152,10 @@ Message categories
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTFLOATSTATE = 4;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTDOUBLESTATE = 5;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_CLIENTREQUESTBTREEACTION = 6;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE = 7;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE = 8;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_LOADSCENE = 9;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION = 7;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE = 8;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE = 9;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_LOADSCENE = 10;
|
||||
/*
|
||||
Synchronization packet sizes
|
||||
*/
|
||||
@ -164,6 +165,7 @@ Message categories
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTFLOATSTATE_SIZE = 18;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTDOUBLESTATE_SIZE = 22;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_CLIENTREQUESTBTREEACTION_SIZE = 14;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION_SIZE = 18;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE_SIZE = 10;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE_SIZE = 10;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ public class SynchronizationProtocol implements ServerProtocolTemplate<Synchroni
|
||||
case ATTACHTREE:
|
||||
case DETATCHTREE:
|
||||
case LOADSCENE:
|
||||
case SERVERNOTIFYBTREETRANSITION:
|
||||
//silently ignore
|
||||
break;
|
||||
}
|
||||
@ -45,6 +46,7 @@ public class SynchronizationProtocol implements ServerProtocolTemplate<Synchroni
|
||||
case ATTACHTREE:
|
||||
case DETATCHTREE:
|
||||
case LOADSCENE:
|
||||
case SERVERNOTIFYBTREETRANSITION:
|
||||
//silently ignore
|
||||
break;
|
||||
}
|
||||
|
||||
@ -73,6 +73,12 @@ public class ClientSynchronizationManager {
|
||||
Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId);
|
||||
updateEntityState(targetEntity,bTreeId,message);
|
||||
} break;
|
||||
case SERVERNOTIFYBTREETRANSITION: {
|
||||
int bTreeId = message.getbTreeId();
|
||||
int entityId = message.getentityId();
|
||||
Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId);
|
||||
transitionBTree(targetEntity, bTreeId, message);
|
||||
} break;
|
||||
case ATTACHTREE:{
|
||||
// int bTreeId = message.getbTreeId();
|
||||
// int bTreeValue = message.getbTreeValue();
|
||||
@ -216,5 +222,28 @@ public class ClientSynchronizationManager {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Transitions a behavior tree to a new state
|
||||
* </p>
|
||||
* @param entity The entity
|
||||
* @param bTreeId The id of the behavior tree
|
||||
* @param message The raw synchronization message holding the update data
|
||||
*/
|
||||
private void transitionBTree(Entity entity, int bTreeId, SynchronizationMessage message){
|
||||
switch(bTreeId){
|
||||
case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: {
|
||||
switch(message.getfieldId()){
|
||||
case FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID:{
|
||||
ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity);
|
||||
tree.transitionState(ClientBlockTree.getBlockStateShortAsEnum((short)message.getbTreeValue()));
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ public class ServerSynchronizationManager {
|
||||
case ATTACHTREE:
|
||||
case DETATCHTREE:
|
||||
case LOADSCENE:
|
||||
case SERVERNOTIFYBTREETRANSITION:
|
||||
//silently ignore
|
||||
break;
|
||||
}
|
||||
|
||||
@ -23,4 +23,8 @@ public @interface SyncedField {
|
||||
//ie when idle state changes (to idle from not idle), tell the client the position of the entity when this update happened alongside the actual state update
|
||||
public boolean updatePositionOnStateChange() default false;
|
||||
|
||||
//Instructs the server to send a state-transition packet instead of an immediate update packet
|
||||
//The state transition packet will invoke the transitionBTree function on the client instead of immediately overwriting the state's value
|
||||
public boolean serverSendTransitionPacket() default false;
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user