Example #1
0
        /// <summary>
        /// Performs cleanups of settings unique to the current state.
        /// (Call before all state transitions.)
        /// </summary>
        private void CleanupCurrentState()
        {
            // Remember, transition is out of the current state.

            switch (Status)
            {
            case AccessoryStatus.Stored:

                if (m_UseDefaultStorage)
                {
                    gameObject.SetActive(true);
                }

                break;

            case AccessoryStatus.Mounted:
            case AccessoryStatus.Mounting:

                m_CurrentCoverage = 0;

                if (!LizittUtil.IsUnityDestroyed(m_CurrentMounter))      // Is mounting.
                {
                    m_CurrentMounter.CancelMount(this, CurrentLocation);
                    m_CurrentMounter = null;
                }

                break;
            }
        }
        public sealed override MountResult Mount(Accessory accessory, MountPointType locationType,
                                                 bool ignoreRestrictions, IAccessoryMounter priorityMounter, BodyCoverage additionalCoverage)
        {
            // Error checks are optimized with the assumption that the mount will succeed. Remounts to the same
            // location are allowed.  (Mounter may have changed or may have special remount behavior.)

            var location = GetMountPoint(locationType);

            if (!location)
            {
                Release(accessory);
                return(MountResult.NoMountPoint);
            }
            else if (location.IsBlocked)
            {
                Release(accessory);
                return(MountResult.LocationBlocked);
            }

            if (!ignoreRestrictions)
            {
                if (AccessoriesLimited && !accessory.IgnoreLimited)
                {
                    Release(accessory);
                    return(MountResult.OutfitIsLimited);
                }

                var currentCoverage = CurrentCoverage;
                if (m_Accessories.Contains(accessory))
                {
                    currentCoverage &= ~accessory.CurrentCoverage;
                }

                if (((accessory.GetCoverageFor(location) | additionalCoverage) & currentCoverage) != 0)
                {
                    Release(accessory);
                    return(MountResult.CoverageBlocked);
                }
            }

            if (priorityMounter != null && LizUtil.IsUnityDestroyed(priorityMounter))
            {
                Debug.LogError("The priority mounter is a reference to a destroyed object.", this);
                Release(accessory);
                return(MountResult.FailedOnError);
            }

            if (!accessory.Mount(location, gameObject, priorityMounter, additionalCoverage))
            {
                Release(accessory);
                return(MountResult.RejectedByAccessory);
            }

            LinkAccessory(accessory);

            Observers.SendAccessoryMount(this, accessory);

            return(MountResult.Success);
        }
        public sealed override MountResult Mount(Accessory accessory, MountPointType locationType,
                                                 bool ignoreRestrictions, IAccessoryMounter priorityMounter, BodyCoverage additionalCoverage)
        {
            // Error checks are optimized with the assumption that the mount will succeed.

            if (m_Accessories.Contains(accessory))
            {
                Debug.LogWarning("Attempted to attach same accessory more than once.  Attempt ignored: "
                                 + accessory.name);

                // It is a success since the accessory is mounted. But no event.
                return(MountResult.Success);
            }

            if (!ignoreRestrictions)
            {
                if (AccessoriesLimited && !accessory.IgnoreLimited)
                {
                    return(MountResult.OutfitIsLimited);
                }

                if (((accessory.GetCoverageFor(locationType) | additionalCoverage) & CurrentCoverage) != 0)
                {
                    return(MountResult.CoverageBlocked);
                }
            }

            var location = GetMountPoint(locationType);

            if (!location)
            {
                return(MountResult.NoMountPoint);
            }
            else if (location.IsBlocked)
            {
                return(MountResult.LocationBlocked);
            }

            if (priorityMounter != null && LizittUtil.IsUnityDestroyed(priorityMounter))
            {
                Debug.LogError("The priority mounter is a reference to a destroyed object.", this);
                return(MountResult.FailedOnError);
            }

            if (!accessory.Mount(location, gameObject, priorityMounter, additionalCoverage))
            {
                return(MountResult.RejectedByAccessory);
            }

            LinkAccessory(accessory);

            Observers.SendMount(this, accessory);

            return(MountResult.Success);
        }
        /// <summary>
        /// Determines if the mounter can mount the accessory to the specified location based on the accessory's
        /// current state and without violating the coverage restrictions.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method implements the standard method for this check, including all appropriate null checks.
        /// (E.g. If there is no accessory, it will return false.)
        /// </para>
        /// <para>
        /// The coverage restrictions are violated if a successful mount will result in a coverage that overlaps
        /// <paramref name="restrictions"/>.
        /// </para>
        /// </remarks>
        /// <param name="accessory">The accessory. (Optional)</param>
        /// <param name="mounter">The mounter. (Optional)</param>
        /// <param name="location">The mount location. (Optional)</param>
        /// <param name="restrictions">The body coverage restrictions.</param>
        /// <returns>
        /// True if accessory, mounter, and location are all non-null and the mounter can mount the accessory to the
        /// specified location with the coverage restrictions.
        /// </returns>
        public static bool CanMount(
            Accessory accessory, IAccessoryMounter mounter, MountPoint location, BodyCoverage restrictions)
        {
            if (accessory && location && !LizUtil.IsUnityDestroyed(mounter) &&
                (mounter.GetCoverageFor(location) & restrictions) == 0)
            {
                return(mounter.CanMount(accessory, location));
            }

            return(false);
        }
Example #5
0
        /// <summary>
        /// Performs the first update on the mounter and takes the appropriate action if it completes or needs
        /// more updates.
        /// </summary>
        private void RunMounter(IAccessoryMounter mounter, GameObject owner, MountPoint location,
                                BodyCoverage additionalCoverage)
        {
            CleanupCurrentState();

            int id = m_MounterId + 1;

            m_MounterId = id;

            m_CurrentCoverage = mounter.GetCoverageFor(location.LocationType) | additionalCoverage;

            if (mounter.UpdateMount(this, location, !Application.isPlaying))
            {
                StartCoroutine(DoDurationMount(mounter, owner, location));
            }
            else
            {
                SetState(AccessoryStatus.Mounted, owner, location);
            }
        }
Example #6
0
        // TODO: EVAL: Convert mounting to a method that supports serialization.
        // This is not a high proiority, especially since the standard mounters support
        // immediate completion outside of play mode.  But having all major features except
        // mounting provide support for serialization might be an issue.

        /// <summary>
        /// Kicks off a coroutine to run the mounter through to completion.
        /// </summary>
        private System.Collections.IEnumerator DoDurationMount(
            IAccessoryMounter mounter, GameObject owner, MountPoint location)
        {
            m_CurrentMounter = mounter;
            var id = m_MounterId;

            SetState(AccessoryStatus.Mounting, owner, location);

            yield return(null);

            while (m_MounterId == id && !LizittUtil.IsUnityDestroyed(mounter) && mounter.UpdateMount(this, location))
            {
                yield return(null);
            }

            if (m_MounterId == id)
            {
                SetState(AccessoryStatus.Mounted, owner, location);
                m_CurrentMounter = null;
            }
        }
Example #7
0
        /// <summary>
        /// Mount the accessory to the specified mount point.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is guarenteed to return true if <see cref="CanMount"/> returns true.
        /// But it is valid to use a call to this method without pre-checking mountability. E.g. As an optimitation,
        /// it is valid to simply call this method on a list of all available accessories to let the accessory
        /// decide whether or not it can attach
        /// </para>
        /// <para>
        /// <paramref name="additionalCoverage"/> is useful in when an accessory  uses a generic mounter that doesn't
        /// provide coverage information.
        /// </para>
        /// <para>
        /// Mount priority is as follows:  The priority mounter supplied by the mount method,
        /// the mounter provided by <see cref="GetInitializedMounter"/>, <see cref="MountInternal"/> if
        /// <see cref="CanMountInteral"/> is true.  <see cref="MountInternal"/> only supports immediate completion
        /// mounting.
        /// </para>
        /// </remarks>
        /// <param name="location">The mount location. (Required)</param>
        /// <param name="owner">
        /// The object that will own the accessory after a successful mount. (Required)
        /// </param>
        /// <param name="priorityMounter">
        /// The mounter to attempt before any others are tried.  (I.e. A custom mounter.)
        /// </param>
        /// <param name="additionalCoverage">
        /// Additional coverage to apply on a successful mount, above and beyond the coverage
        /// supplied by the mounter or built into the accessory.
        /// </param>
        /// <returns>True if the mount succeeded, otherwise false.</returns>
        public sealed override bool Mount(MountPoint location, GameObject owner,
                                          IAccessoryMounter priorityMounter, BodyCoverage additionalCoverage)
        {
            // While not expected to be common, it is technically ok to re-attach to the same
            // mount location.  So there is no optimization check for that.

            if (!(location && owner))
            {
                Debug.LogError("Null mount location and/or owner.", this);
                return(false);
            }
            ;

            if (!LizittUtil.IsUnityDestroyed(priorityMounter) && priorityMounter.InitializeMount(this, location))
            {
                RunMounter(priorityMounter, owner, location, additionalCoverage);
                return(true);
            }

            var mounter = GetInitializedMounter(location, owner);

            if (!LizittUtil.IsUnityDestroyed(mounter))
            {
                RunMounter(mounter, owner, location, additionalCoverage);
                return(true);
            }

            if (CanMountInternal(location, owner))
            {
                CleanupCurrentState();

                m_CurrentCoverage = MountInternal(location, owner) | additionalCoverage;
                SetState(AccessoryStatus.Mounted, owner, location);

                return(true);
            }

            return(false);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////
        // HACK: Unity 5.3.1: Workaround for Mono's optional parameter key duplication bug.

        /// <summary>
        /// Mount the accessory to the specified location.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method will always succeed if <see cref="CanMount(MountPoint, BodyCoverage)"/> returns true.
        /// </para>
        /// <para>
        /// Supports lazy calling.  E.g. As an optimitation it is valid to simply call this method on a list of
        /// available accessories and let each accessory decide whether or not it can mount.
        /// </para>
        /// </remarks>
        /// <param name="location">The mount location. (Required)</param>
        /// <param name="owner">The object that will own the accessory after a successful mount. (Required)</param>
        /// <param name="priorityMounter">The mounter to attempt before any others are tried. (Optional)</param>
        /// <returns>True if the mount succeeded, otherwise false.</returns>
        public bool Mount(MountPoint location, GameObject owner, IAccessoryMounter priorityMounter)
        {
            return(Mount(location, owner, priorityMounter, 0));
        }
        ////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Mount the accessory to the specified location.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method will always succeed if <see cref="CanMount(MountPoint, BodyCoverage)"/> returns true.
        /// </para>
        /// <para>
        /// Supports lazy calling.  E.g. As an optimitation it is valid to simply call this method on a list of
        /// available accessories and let each accessory decide whether or not it can mount.
        /// </para>
        /// <para>
        /// <paramref name="additionalCoverage"/> is useful in situations where an accessory uses a generic mounter
        /// that doesn't provide coverage information.  On a successful mount the additional coverage will be
        /// added to the coverage supplied by the mounter and/or built into the accessory.
        /// </para>
        /// </remarks>
        /// <param name="location">The mount location. (Required)</param>
        /// <param name="owner">The object that will own the accessory after a successful mount. (Required)</param>
        /// <param name="priorityMounter">The mounter to attempt before any others are tried. (Optional) </param>
        /// <param name="additionalCoverage">
        /// Additional coverage to apply on a successful mount, above and beyond the coverage supplied by the
        /// mounter and/or built into the accessory. (Optional)
        /// </param>
        /// <returns>True if the mount succeeded, otherwise false.</returns>
        public abstract bool Mount(MountPoint location, GameObject owner, IAccessoryMounter priorityMounter,
                                   BodyCoverage additionalCoverage);
        ////////////////////////////////////////////////////////////////////////////////////////////
        // HACK: Unity 5.3.1: Workaround for Mono's optional parameter key duplication bug.

        /// <summary>
        /// Mount the accessory to the specified location.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Remounting to a different or same location is allowed.  If a remount fails the accessory will be
        /// released.  This behavior is due to the multiple actors involved.  E.g. The outfit, accessory, and
        /// possibly a mounter. The outfit can't guarentee behavior of all actors, so it implements a behavior that
        /// is consistant.
        /// </para>
        /// </remarks>
        /// <param name="accessory">The accessory to mount. (Required)</param>
        /// <param name="locationType">The location to mount the accessory to.</param>
        /// <param name="ignoreRestrictions">
        /// If true, ignore coverage restrictions and the value of <see cref="AccessoriesLimited"/>.
        /// </param>
        /// <param name="priorityMounter">
        /// The mounter that should be tried before any other mounters.  (Optional)
        /// </param>
        /// <returns>The result of the mount attempt.</returns>
        public MountResult Mount(Accessory accessory, MountPointType locationType,
                                 bool ignoreRestrictions, IAccessoryMounter priorityMounter)
        {
            return(Mount(accessory, locationType, ignoreRestrictions, priorityMounter, 0));
        }
 /// <summary>
 /// Mount the accessory to the specified location.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Remounting to a different or same location is allowed.  If a remount fails the accessory will be
 /// released.  This behavior is due to the multiple actors involved.  E.g. The outfit, accessory, and
 /// possibly a mounter. The outfit can't guarentee behavior of all actors, so it implements a behavior that
 /// is consistant.
 /// </para>
 /// </remarks>
 /// <param name="accessory">The accessory to mount. (Required)</param>
 /// <param name="locationType">The location to mount the accessory to.</param>
 /// <param name="ignoreRestrictions">
 /// If true, ignore coverage restrictions and the value of <see cref="AccessoriesLimited"/>.
 /// </param>
 /// <param name="priorityMounter">
 /// The mounter that should be tried before any other mounters.  (Optional)
 /// </param>
 /// <param name="additionalCoverage">
 /// Coverage to add to the accessory if it is successfully mounted, above and beyond any coverage inherent
 /// iin the accessory and/or mounter.
 /// </param>
 /// <returns>The result of the mount attempt.</returns>
 public abstract MountResult Mount(Accessory accessory, MountPointType locationType,
                                   bool ignoreRestrictions, IAccessoryMounter priorityMounter, BodyCoverage additionalCoverage);