private static float LookForFootRecursion(BodyManagerComponent body, BodyPart current, ICollection <BodyPart> searchedParts) { if (!current.TryGetProperty <ExtensionProperty>(out var extProperty)) { return(float.MinValue); } // Get all connected parts if the current part has an extension property if (!body.TryGetBodyPartConnections(current, out var connections)) { return(float.MinValue); } // If a connected BodyPart is a foot, return this BodyPart's length. foreach (var connection in connections) { if (!searchedParts.Contains(connection) && connection.HasProperty <FootProperty>()) { return(extProperty.ReachDistance); } } // Otherwise, get the recursion values of all connected BodyParts and // store them in a list. var distances = new List <float>(); foreach (var connection in connections) { if (!searchedParts.Contains(connection)) { continue; } var result = LookForFootRecursion(body, connection, searchedParts); if (Math.Abs(result - float.MinValue) > 0.001f) { distances.Add(result); } } // If one or more of the searches found a foot, return the smallest one // and add this ones length. if (distances.Count > 0) { return(distances.Min <float>() + extProperty.ReachDistance); } return(float.MinValue); // No extension property, no go. }
private void SendBodySlotListToUser(AfterInteractEventArgs eventArgs, BodyManagerComponent bodyManager) { // Create dictionary to send to client (text to be shown : data sent back if selected) var toSend = new Dictionary <string, int>(); // Here we are trying to grab a list of all empty BodySlots adjacent to an existing BodyPart that can be // attached to. i.e. an empty left hand slot, connected to an occupied left arm slot would be valid. var unoccupiedSlots = bodyManager.AllSlots.ToList().Except(bodyManager.OccupiedSlots.ToList()).ToList(); foreach (var slot in unoccupiedSlots) { if (!bodyManager.TryGetSlotType(slot, out var typeResult) || typeResult != ContainedBodyPart?.PartType || !bodyManager.TryGetBodyPartConnections(slot, out var parts)) { continue; } foreach (var connectedPart in parts) { if (!connectedPart.CanAttachPart(ContainedBodyPart)) { continue; } _optionsCache.Add(_idHash, slot); toSend.Add(slot, _idHash++); } } if (_optionsCache.Count > 0) { OpenSurgeryUI(eventArgs.User.GetComponent <BasicActorComponent>().playerSession); UpdateSurgeryUIBodyPartSlotRequest(eventArgs.User.GetComponent <BasicActorComponent>().playerSession, toSend); _performerCache = eventArgs.User; _bodyManagerComponentCache = bodyManager; } else // If surgery cannot be performed, show message saying so. { _sharedNotifyManager.PopupMessage(eventArgs.Target, eventArgs.User, Loc.GetString("You see no way to install {0:theName}.", Owner)); } }