/// <summary> /// Combines two entity deltas to create a new entity delta /// </summary> /// <param name="baseEntityDelta">Base entity delta</param> /// <param name="patchEntityDelta">Patch entity delta</param> /// <returns>Combined entity delta</returns> public static EntityDelta Combine(IEntityDelta baseEntityDelta, IEntityDelta patchEntityDelta) { if (baseEntityDelta == null) { throw new ArgumentNullException(nameof(baseEntityDelta)); } if (!baseEntityDelta.IsValid) { throw new ArgumentException("Base entity delta is not valid.", nameof(baseEntityDelta)); } if (patchEntityDelta == null) { throw new ArgumentNullException(nameof(patchEntityDelta)); } if (!patchEntityDelta.IsValid) { throw new ArgumentException("Patch entity delta is not valid.", nameof(patchEntityDelta)); } if (baseEntityDelta.GUID != patchEntityDelta.GUID) { throw new ArgumentException($"Base entity delta GUID \"{ baseEntityDelta.GUID }\" does not match patch entity delta GUID \"{ patchEntityDelta.GUID }\".", nameof(patchEntityDelta)); } HashSet <string> actions = (baseEntityDelta.Actions == null) ? null : new HashSet <string>(baseEntityDelta.Actions); if (patchEntityDelta.Actions != null) { if (actions == null) { actions = new HashSet <string>(patchEntityDelta.Actions); } else { actions.UnionWith(patchEntityDelta.Actions); } } return(new EntityDelta ( baseEntityDelta.GUID, patchEntityDelta.EntityType ?? baseEntityDelta.EntityType, patchEntityDelta.GameColor ?? baseEntityDelta.GameColor, patchEntityDelta.IsSpectating ?? baseEntityDelta.IsSpectating, patchEntityDelta.Position ?? baseEntityDelta.Position, patchEntityDelta.Rotation ?? baseEntityDelta.Rotation, patchEntityDelta.Velocity ?? baseEntityDelta.Velocity, patchEntityDelta.AngularVelocity ?? baseEntityDelta.AngularVelocity, actions, patchEntityDelta.IsResyncRequested ?? baseEntityDelta.IsResyncRequested )); }
/// <summary> /// Tries to get entity delta from the specified entities /// </summary> /// <param name="baseEntity">Base entity</param> /// <param name="patchEntity">Patch entity</param> /// <param name="entityDelta">Entity data</param> /// <returns>"true" if differences between base and patch entities exist, otherwise "false"</returns> public static bool TryGetDelta(IEntity baseEntity, IEntity patchEntity, out IEntityDelta entityDelta) { if (baseEntity == null) { throw new ArgumentNullException(nameof(baseEntity)); } if (!baseEntity.IsValid) { throw new ArgumentException("Base entity is not valid.", nameof(baseEntity)); } if (patchEntity == null) { throw new ArgumentNullException(nameof(patchEntity)); } if (!patchEntity.IsValid) { throw new ArgumentException("Patch entity is not valid.", nameof(patchEntity)); } if (baseEntity.GUID != patchEntity.GUID) { throw new ArgumentException($"Base entity GUID \"{ baseEntity.GUID }\" does not match patch entity GUID \"{ patchEntity.GUID }\".", nameof(patchEntity)); } bool ret = false; string entity_type = null; EGameColor? game_color = null; bool? is_spectating = null; Vector3? position = null; Quaternion? rotation = null; Vector3? velocity = null; Vector3? angular_velocity = null; IEnumerable <string> actions = null; bool? is_resync_requested = null; if (baseEntity != patchEntity) { if (baseEntity.EntityType != patchEntity.EntityType) { ret = true; entity_type = patchEntity.EntityType; } if (baseEntity.EntityType != patchEntity.EntityType) { ret = true; entity_type = patchEntity.EntityType; } if (baseEntity.GameColor != patchEntity.GameColor) { ret = true; game_color = patchEntity.GameColor; } if (baseEntity.IsSpectating != patchEntity.IsSpectating) { ret = true; is_spectating = patchEntity.IsSpectating; } if (baseEntity.Position != patchEntity.Position) { ret = true; position = patchEntity.Position; } if (baseEntity.Rotation != patchEntity.Rotation) { ret = true; rotation = patchEntity.Rotation; } if (baseEntity.Velocity != patchEntity.Velocity) { ret = true; velocity = patchEntity.Velocity; } if (baseEntity.AngularVelocity != patchEntity.AngularVelocity) { ret = true; angular_velocity = patchEntity.AngularVelocity; } foreach (string action in baseEntity.Actions) { if (!Protection.IsContained(patchEntity.Actions, (patch_entity_action) => patch_entity_action == action)) { actions = patchEntity.Actions; break; } } if (baseEntity.IsResyncRequested != patchEntity.IsResyncRequested) { ret = true; is_resync_requested = patchEntity.IsResyncRequested; } if (actions == null) { foreach (string action in patchEntity.Actions) { if (!Protection.IsContained(baseEntity.Actions, (base_entity_action) => base_entity_action == action)) { actions = patchEntity.Actions; break; } } } } entityDelta = ret ? (IEntityDelta) new EntityDelta(baseEntity.GUID, entity_type, game_color, is_spectating, position, rotation, velocity, angular_velocity, actions, is_resync_requested) : null; return(ret); }