// Local helper method for use object highlighting. private void HighlightUseObject(IMyUseObject useObject, MyHighlightData data) { // Use the helper to perform preprocessing m_highlightCalculationHelper.HighlightAttribute = null; m_highlightCalculationHelper.Highlight(useObject); // For objects with dummy prepare dummy data if (useObject.Dummy != null) { object attributeData; useObject.Dummy.CustomData.TryGetValue(MyModelDummy.ATTRIBUTE_HIGHLIGHT, out attributeData); string highlightAttribute = attributeData as string; m_highlightCalculationHelper.HighlightAttribute = highlightAttribute; } // Send message to renderer MyRenderProxy.UpdateModelHighlight( (uint)m_highlightCalculationHelper.InteractiveObject.RenderObjectID, m_highlightCalculationHelper.SectionIndices, m_highlightCalculationHelper.SubpartIndices, data.OutlineColor, data.Thickness, data.PulseTimeInFrames, m_highlightCalculationHelper.InteractiveObject.InstanceID); }
/// <summary> /// Requests Exclusive highlight from render proxy. The call is handled localy for /// default player id. Only server can use the player id to propagate the /// Highlight calls to clients. /// Uses Exclusive key as lock accessor. Can be obtained from ExclusiveHighlightAccepted event. /// </summary> /// <param name="data">Highlight data wrapper.</param> /// <param name="exclusiveKey">Exclusive key.</param> /// <param name="playerId">Player Identity Id.</param> public void RequestHighlightChangeExclusive(MyHighlightData data, int exclusiveKey = -1) { ProcessRequest( data, exclusiveKey, true); }
/// <summary> /// Requests highlight from render proxy. The call is handled localy for /// default player id. Only server can use the player id to propagate the /// Highlight calls to clients. /// </summary> /// <param name="data">Highlight data wrapper.</param> /// <param name="playerId">Player Identity Id.</param> public void RequestHighlightChange(MyHighlightData data) { ProcessRequest( data, -1, false); }
private void NotifyExclusiveHighlightRejected(MyHighlightData data, int exclusiveKey) { if (ExclusiveHighlightRejected == null) { return; } ExclusiveHighlightRejected(data, exclusiveKey); // unsubscribe all foreach (var @delegate in ExclusiveHighlightRejected.GetInvocationList()) { ExclusiveHighlightRejected -= (Action <MyHighlightData, int>)@delegate; } }
private void NotifyHighlightAccepted(MyHighlightData data) { if (HighlightAccepted == null) { return; } HighlightAccepted(data); // unsubscribe all foreach (var @delegate in HighlightAccepted.GetInvocationList()) { HighlightAccepted -= (Action <MyHighlightData>)@delegate; } }
private void NotifyExclusiveHighlightRejected(MyHighlightData data, int exclusiveKey) { if(ExclusiveHighlightRejected == null) return; ExclusiveHighlightRejected(data, exclusiveKey); // unsubscribe all foreach (var @delegate in ExclusiveHighlightRejected.GetInvocationList()) { ExclusiveHighlightRejected -= (Action<MyHighlightData, int>)@delegate; } }
private void NotifyHighlightAccepted(MyHighlightData data) { if(HighlightAccepted == null) return; HighlightAccepted(data); // unsubscribe all foreach (var @delegate in HighlightAccepted.GetInvocationList()) { HighlightAccepted -= (Action<MyHighlightData>)@delegate; } }
// No network logic involved. highlighs the object. private void MakeLocalHighlightChange(MyHighlightData data) { if (data.Thickness > -1) { // Highlight On m_highlightedIds.Add(data.EntityId); } else { // Highlight Off m_highlightedIds.Remove(data.EntityId); } MyEntity entity; if(!MyEntities.TryGetEntityById(data.EntityId, out entity)) { //Debug.Fail("Highlight system: Entity was not found."); return; } if (!data.IgnoreUseObjectData) { var useObject = entity as IMyUseObject; var useComp = entity.Components.Get<MyUseObjectsComponentBase>(); // Entities can derive from IMyUseObject or have useObject component. if (useObject != null || useComp != null) { if (useComp != null) { // Has UseObjectComp List<IMyUseObject> useObjectTmpList = new List<IMyUseObject>(); useComp.GetInteractiveObjects(useObjectTmpList); for (var index = 0; index < useObjectTmpList.Count; index++) { HighlightUseObject(useObjectTmpList[index], data); } if (useObjectTmpList.Count > 0) { if (HighlightAccepted != null) HighlightAccepted(data); return; } } else { // Is useObject HighlightUseObject(useObject, data); if (HighlightAccepted != null) HighlightAccepted(data); return; } } } // Collect subPart indicies m_subPartIndicies.Clear(); CollectSubPartIndicies(entity); // No use object just use the model for highlight MyRenderProxy.UpdateModelHighlight( (uint)entity.Render.GetRenderObjectID(), null, m_subPartIndicies.ToArray(), data.OutlineColor, data.Thickness, data.PulseTimeInFrames); if(HighlightAccepted != null) HighlightAccepted(data); }
// Determines if the highlight is local or global request. // Sends message to eighter render proxy or server. private void ProcessRequest(MyHighlightData data, int exclusiveKey, bool isExclusive) { // It is a local highlight if(data.PlayerId == -1) { data.PlayerId = MySession.Static.LocalPlayerId; } if ((MyMultiplayer.Static == null || MyMultiplayer.Static.IsServer) && data.PlayerId != MySession.Static.LocalPlayerId) { // Stop right here if id does not exist. MyPlayer.PlayerId _playerId; if (!MySession.Static.Players.TryGetPlayerId(data.PlayerId, out _playerId)) return; var msg = new HighlightMsg() { Data = data, ExclusiveKey = exclusiveKey, IsExclusive = isExclusive }; // Server knows nothing, needs to ask clients for exclusive key. OnRejected or OnAccepted will give him answer. MyMultiplayer.RaiseStaticEvent(s => OnHighlightOnClient, msg, new EndpointId(_playerId.SteamId)); } else { var enableHighlight = data.Thickness > -1; // Discard invalid requests long storedEntityId; if(m_exclusiveKeysToIds.ContainsValue(data.EntityId)) { if(!m_exclusiveKeysToIds.TryGetValue(exclusiveKey, out storedEntityId) || storedEntityId != data.EntityId) { if(HighlightRejected != null) HighlightRejected(data); return; } } // Give the exclusive request new local Key if (isExclusive) { if (exclusiveKey == -1) { // Get new key from the counter exclusiveKey = m_exclusiveKeyCounter++; } if(enableHighlight) { if(!m_exclusiveKeysToIds.ContainsKey(exclusiveKey)) m_exclusiveKeysToIds.Add(exclusiveKey, data.EntityId); } else { m_exclusiveKeysToIds.Remove(exclusiveKey); } MakeLocalHighlightChange(data); if(ExclusiveHighlightAccepted != null) ExclusiveHighlightAccepted(data, exclusiveKey); } else { MakeLocalHighlightChange(data); if (HighlightAccepted != null) HighlightAccepted(data); } } }
// No network logic involved. highlighs the object. private void MakeLocalHighlightChange(MyHighlightData data) { if (data.Thickness > -1) { // Highlight On m_highlightedIds.Add(data.EntityId); } else { // Highlight Off m_highlightedIds.Remove(data.EntityId); } MyEntity entity; if (!MyEntities.TryGetEntityById(data.EntityId, out entity)) { //Debug.Fail("Highlight system: Entity was not found."); return; } if (!data.IgnoreUseObjectData) { var useObject = entity as IMyUseObject; var useComp = entity.Components.Get <MyUseObjectsComponentBase>(); // Entities can derive from IMyUseObject or have useObject component. if (useObject != null || useComp != null) { if (useComp != null) { // Has UseObjectComp List <IMyUseObject> useObjectTmpList = new List <IMyUseObject>(); useComp.GetInteractiveObjects(useObjectTmpList); for (var index = 0; index < useObjectTmpList.Count; index++) { HighlightUseObject(useObjectTmpList[index], data); } if (useObjectTmpList.Count > 0) { if (HighlightAccepted != null) { HighlightAccepted(data); } return; } } else { // Is useObject HighlightUseObject(useObject, data); if (HighlightAccepted != null) { HighlightAccepted(data); } return; } } } // Collect subPart indicies m_subPartIndicies.Clear(); CollectSubPartIndicies(entity); // No use object just use the model for highlight MyRenderProxy.UpdateModelHighlight( (uint)entity.Render.GetRenderObjectID(), null, m_subPartIndicies.ToArray(), data.OutlineColor, data.Thickness, data.PulseTimeInFrames); if (HighlightAccepted != null) { HighlightAccepted(data); } }
// Determines if the highlight is local or global request. // Sends message to eighter render proxy or server. private void ProcessRequest(MyHighlightData data, int exclusiveKey, bool isExclusive) { // It is a local highlight if (data.PlayerId == -1) { data.PlayerId = MySession.Static.LocalPlayerId; } if ((MyMultiplayer.Static == null || MyMultiplayer.Static.IsServer) && data.PlayerId != MySession.Static.LocalPlayerId) { // Stop right here if id does not exist. MyPlayer.PlayerId _playerId; if (!MySession.Static.Players.TryGetPlayerId(data.PlayerId, out _playerId)) { return; } var msg = new HighlightMsg() { Data = data, ExclusiveKey = exclusiveKey, IsExclusive = isExclusive }; // Server knows nothing, needs to ask clients for exclusive key. OnRejected or OnAccepted will give him answer. MyMultiplayer.RaiseStaticEvent(s => OnHighlightOnClient, msg, new EndpointId(_playerId.SteamId)); } else { var enableHighlight = data.Thickness > -1; // Discard invalid requests long storedEntityId; if (m_exclusiveKeysToIds.ContainsValue(data.EntityId)) { if (!m_exclusiveKeysToIds.TryGetValue(exclusiveKey, out storedEntityId) || storedEntityId != data.EntityId) { if (HighlightRejected != null) { HighlightRejected(data); } return; } } // Give the exclusive request new local Key if (isExclusive) { if (exclusiveKey == -1) { // Get new key from the counter exclusiveKey = m_exclusiveKeyCounter++; } if (enableHighlight) { if (!m_exclusiveKeysToIds.ContainsKey(exclusiveKey)) { m_exclusiveKeysToIds.Add(exclusiveKey, data.EntityId); } } else { m_exclusiveKeysToIds.Remove(exclusiveKey); } MakeLocalHighlightChange(data); if (ExclusiveHighlightAccepted != null) { ExclusiveHighlightAccepted(data, exclusiveKey); } } else { MakeLocalHighlightChange(data); if (HighlightAccepted != null) { HighlightAccepted(data); } } } }
// Local helper method for use object highlighting. private void HighlightUseObject(IMyUseObject useObject, MyHighlightData data) { // Use the helper to perform preprocessing m_highlightCalculationHelper.HighlightAttribute = null; if (useObject.Dummy != null) { // For objects with dummy prepare dummy data object attributeData; useObject.Dummy.CustomData.TryGetValue(MyModelDummy.ATTRIBUTE_HIGHLIGHT, out attributeData); string highlightAttribute = attributeData as string; if (highlightAttribute == null) { return; } if (data.SubPartNames != null) { // When the SubPartName hints are present check the attributes. // Use only those who should be rendered. m_highlightAttributeBuilder.Clear(); var splits = data.SubPartNames.Split(';'); foreach (var split in splits) { if (highlightAttribute.Contains(split)) { m_highlightAttributeBuilder.Append(split).Append(';'); } } if (m_highlightAttributeBuilder.Length > 0) { m_highlightAttributeBuilder.TrimEnd(1); } m_highlightCalculationHelper.HighlightAttribute = m_highlightAttributeBuilder.ToString(); } else { // Use whole set of attributes. m_highlightCalculationHelper.HighlightAttribute = highlightAttribute; } if (string.IsNullOrEmpty(m_highlightCalculationHelper.HighlightAttribute)) { return; } } m_highlightCalculationHelper.Highlight(useObject); // Send message to renderer MyRenderProxy.UpdateModelHighlight( (uint)m_highlightCalculationHelper.InteractiveObject.RenderObjectID, m_highlightCalculationHelper.SectionNames, m_highlightCalculationHelper.SubpartIndices, data.OutlineColor, data.Thickness, data.PulseTimeInFrames, m_highlightCalculationHelper.InteractiveObject.InstanceID); }