Example #1
0
        private void SendBodyPartListToUser(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>();

            foreach (var(key, value) in bodyManager.Parts)
            {
                // For each limb in the target, add it to our cache if it is a valid option.
                if (value.CanInstallMechanism(ContainedMechanism))
                {
                    _optionsCache.Add(_idHash, value);
                    toSend.Add(key + ": " + value.Name, _idHash++);
                }
            }

            if (_optionsCache.Count > 0)
            {
                OpenSurgeryUI(eventArgs.User.GetComponent <BasicActorComponent>().playerSession);
                UpdateSurgeryUIBodyPartRequest(eventArgs.User.GetComponent <BasicActorComponent>().playerSession,
                                               toSend);
                _performerCache            = eventArgs.User;
                _bodyManagerComponentCache = bodyManager;
            }
            else // If surgery cannot be performed, show message saying so.
            {
                eventArgs.Target.PopupMessage(eventArgs.User,
                                              Loc.GetString("You see no way to install the {0}.", Owner.Name));
            }
        }
        private static float DistanceToNearestFoot(BodyManagerComponent body, BodyPart source)
        {
            if (source.HasProperty <FootProperty>() && source.TryGetProperty <ExtensionProperty>(out var property))
            {
                return(property.ReachDistance);
            }

            return(LookForFootRecursion(body, source, new List <BodyPart>()));
        }
        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));
            }
        }