state collection work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-08-11 12:22:14 -04:00
parent 438766d052
commit 263d6680ee
5 changed files with 294 additions and 0 deletions

View File

@ -533,6 +533,9 @@ Ability to serialize/deserialize a creature with equipped items
- Send to client - Send to client
- Receive from server - Receive from server
(08/11/2024)
Sending initial synchronized state on player connect to chunk
# TODO # TODO

View File

@ -3,6 +3,8 @@ package electrosphere.entity.types.creature;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import electrosphere.net.synchronization.transport.StateCollection;
/** /**
* The template used to construct the creature on the client * The template used to construct the creature on the client
*/ */
@ -23,6 +25,11 @@ public class CreatureTemplate {
*/ */
private CreatureEquipData equipData = new CreatureEquipData(); private CreatureEquipData equipData = new CreatureEquipData();
/**
* The collection of synchronized values
*/
private StateCollection stateCollection;
/** /**
* Creates the creature template * Creates the creature template
* @param creatureType The type of creature * @param creatureType The type of creature
@ -77,6 +84,22 @@ public class CreatureTemplate {
return this.equipData; return this.equipData;
} }
/**
* Gets the state collection for the creature
* @return The collection of synchronized values
*/
public StateCollection getStateCollection(){
return this.stateCollection;
}
/**
* Sets the synchronized values for this creature
* @param stateCollection The synchronized values
*/
public void setStateCollection(StateCollection stateCollection){
this.stateCollection = stateCollection;
}
/** /**
* A visual attribute of a creature (ie how wide is their nose, what type of hairstyle do they have, etc) * A visual attribute of a creature (ie how wide is their nose, what type of hairstyle do they have, etc)
*/ */

View File

@ -65,6 +65,7 @@ import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.player.Player; import electrosphere.net.server.player.Player;
import electrosphere.net.synchronization.transport.StateCollection;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorBoneRotator;
import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorStaticMorph;
@ -845,6 +846,7 @@ public class CreatureUtils {
equipData.setSlotItem(point, new EquippedItem(item.getId(),ItemUtils.getType(item))); equipData.setSlotItem(point, new EquippedItem(item.getId(),ItemUtils.getType(item)));
} }
} }
template.setStateCollection(StateCollection.getStateCollection(e));
return template; return template;
} }

View File

@ -25,6 +25,7 @@ import electrosphere.game.data.creature.type.ViewModelData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.EntityMessage.EntityMessageType; import electrosphere.net.parser.net.message.EntityMessage.EntityMessageType;
import electrosphere.net.synchronization.transport.StateCollection;
import electrosphere.net.template.ClientProtocolTemplate; import electrosphere.net.template.ClientProtocolTemplate;
import electrosphere.util.Utilities; import electrosphere.util.Utilities;
@ -110,6 +111,10 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), itemDefinition.getEntityId()); Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), itemDefinition.getEntityId());
} }
} }
//apply state synchronization if present
if(template != null && template.getStateCollection() != null && template.getStateCollection().getValues() != null){
StateCollection.applyStateCollection(newlySpawnedEntity, template.getStateCollection());
}
} break; } break;
case SPAWNITEM: { case SPAWNITEM: {
LoggerInterface.loggerNetworking.DEBUG("Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ()); LoggerInterface.loggerNetworking.DEBUG("Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());

View File

@ -0,0 +1,261 @@
package electrosphere.net.synchronization.transport;
import electrosphere.entity.state.equip.ClientEquipState;
import java.util.LinkedList;
import java.util.List;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.block.ClientBlockTree;
import electrosphere.entity.state.block.ServerBlockTree;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.idle.ClientIdleTree;
import electrosphere.entity.state.idle.ServerIdleTree;
import electrosphere.entity.state.life.ClientLifeTree;
import electrosphere.entity.state.life.ServerLifeTree;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
import electrosphere.entity.state.movement.jump.ClientJumpTree;
import electrosphere.entity.state.movement.jump.ServerJumpTree;
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
import electrosphere.net.synchronization.enums.FieldIdEnums;
/**
* A collection of values for synchronized variables.
* Used to transport data from server to client on initially loading a given entity.
*/
public class StateCollection {
/**
* The synchronized values
*/
List<SynchronizedFieldValue> values = new LinkedList<SynchronizedFieldValue>();
/**
* Get the synchronized field's values
* @return The values
*/
public List<SynchronizedFieldValue> getValues(){
return values;
}
/**
* Sets a given value
* @param value The value
*/
public void setValue(SynchronizedFieldValue value){
this.values.add(value);
}
/**
* <p> Automatically generated </p>
* <p>
* Gets the state collection for the given entity
* </p>
* @param entity The entity
* @return The state collection
*/
public static StateCollection getStateCollection(Entity entity){
StateCollection collection = new StateCollection();
for(int treeId : Globals.entityValueTrackingService.getEntityTrees(entity)){
switch(treeId){
case BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID: {
ServerAttackTree tree = ServerAttackTree.getServerAttackTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID,FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID,ClientAttackTree.getAttackTreeStateEnumAsShort(tree.getState())));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID,FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_DRIFTSTATE_ID,ClientAttackTree.getAttackTreeDriftStateEnumAsShort(tree.getDriftState())));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID,FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_CURRENTMOVEID_ID,tree.getCurrentMoveId()));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: {
ServerBlockTree tree = ServerBlockTree.getServerBlockTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID,FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID,ClientBlockTree.getBlockStateEnumAsShort(tree.getState())));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID,FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID,tree.getCurrentBlockVariant()));
} break;
case BehaviorTreeIdEnums.BTREE_SERVEREQUIPSTATE_ID: {
ServerEquipState tree = ServerEquipState.getServerEquipState(entity);
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
ServerGravityTree tree = ServerGravityTree.getServerGravityTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID,FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID,ClientGravityTree.getGravityTreeStateEnumAsShort(tree.getState())));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID: {
ServerIdleTree tree = ServerIdleTree.getServerIdleTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID,FieldIdEnums.TREE_SERVERIDLE_SYNCEDFIELD_STATE_ID,ClientIdleTree.getIdleTreeStateEnumAsShort(tree.getState())));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERLIFETREE_ID: {
ServerLifeTree tree = ServerLifeTree.getServerLifeTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERLIFETREE_ID,FieldIdEnums.TREE_SERVERLIFETREE_SYNCEDFIELD_STATE_ID,ClientLifeTree.getLifeStateEnumEnumAsShort(tree.getState())));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGROUNDMOVEMENTTREE_ID: {
ServerGroundMovementTree tree = ServerGroundMovementTree.getServerGroundMovementTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERGROUNDMOVEMENTTREE_ID,FieldIdEnums.TREE_SERVERGROUNDMOVEMENTTREE_SYNCEDFIELD_FACING_ID,ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(tree.getFacing())));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID: {
ServerJumpTree tree = ServerJumpTree.getServerJumpTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID,FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_STATE_ID,ClientJumpTree.getJumpStateEnumAsShort(tree.getState())));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID,FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTFRAME_ID,tree.getCurrentFrame()));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID,FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTJUMPFORCE_ID,tree.getCurrentJumpForce()));
} break;
}
}
return collection;
}
/**
* <p> Automatically generated </p>
* <p>
* Applies the state collection to the given entity
* </p>
* @param entity The entity
* @param collection The state collection
*/
public static void applyStateCollection(Entity entity, StateCollection collection){
for(SynchronizedFieldValue syncedValue : collection.getValues()){
switch(syncedValue.getBehaviorTreeId()){
case BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID: {
ClientAttackTree tree = ClientAttackTree.getClientAttackTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientAttackTree.getAttackTreeStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
case(FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_DRIFTSTATE_ID): {
tree.setDriftState(ClientAttackTree.getAttackTreeDriftStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
case(FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_CURRENTMOVEID_ID): {
tree.setCurrentMoveId((String)syncedValue.getValue());
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: {
ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientBlockTree.getBlockStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
case(FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID): {
tree.setCurrentBlockVariant((String)syncedValue.getValue());
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVEREQUIPSTATE_ID: {
ClientEquipState tree = ClientEquipState.getClientEquipState(entity);
switch(syncedValue.getFieldId()){
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
ClientGravityTree tree = ClientGravityTree.getClientGravityTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientGravityTree.getGravityTreeStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID: {
ClientIdleTree tree = ClientIdleTree.getClientIdleTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERIDLE_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientIdleTree.getIdleTreeStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERLIFETREE_ID: {
ClientLifeTree tree = ClientLifeTree.getClientLifeTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERLIFETREE_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientLifeTree.getLifeStateEnumShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGROUNDMOVEMENTTREE_ID: {
ClientGroundMovementTree tree = ClientGroundMovementTree.getClientGroundMovementTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERGROUNDMOVEMENTTREE_SYNCEDFIELD_FACING_ID): {
tree.setFacing(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID: {
ClientJumpTree tree = ClientJumpTree.getClientJumpTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientJumpTree.getJumpStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
case(FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTFRAME_ID): {
tree.setCurrentFrame(((Double)syncedValue.getValue()).intValue());
} break;
case(FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTJUMPFORCE_ID): {
tree.setCurrentJumpForce(((Double)syncedValue.getValue()).floatValue());
} break;
}
} break;
}
}
}
/**
* The value of a single synchronized field
*/
public static class SynchronizedFieldValue {
/**
* The behavior tree this field is on
*/
int behaviorTreeId;
/**
* The id of the field
*/
int fieldId;
/**
* The value of the field
*/
Object value;
/**
* Creates a synchronized value
* @param behaviorTreeId The behavior tree id of the field
* @param fieldId The field id of the field
* @param value The value of the field currently
*/
public SynchronizedFieldValue(int behaviorTreeId, int fieldId, Object value){
this.behaviorTreeId = behaviorTreeId;
this.fieldId = fieldId;
this.value = value;
}
/**
* Gets the behavior tree this field is in
* @return the id of the behavior tree
*/
public int getBehaviorTreeId(){
return behaviorTreeId;
}
/**
* Gets the id of the field
* @return The id
*/
public int getFieldId(){
return fieldId;
}
/**
* Gets the current value for this field
* @return The current value
*/
public Object getValue(){
return value;
}
}
}