/// <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; } }
protected override IAccessoryMounter GetInitializedMounter(MountPoint location, GameObject owner) { if (!LizittUtil.IsUnityDestroyed(m_PriorityMounter) && PriorityMounter.InitializeMount(this, location)) { return(PriorityMounter); } return(m_Mounters.GetInitializedMounter(this, location)); }
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="locationType">The mount location type.</param> /// <param name="restrictions">The body coverage restrictions.</param> /// <returns> /// True if accessory and mounter are non-null and the mounter can mount the accessory to the specified /// location based on the accessory's current state and coverage restrictions.</returns> public static bool CanMount( Accessory accessory, IAccessoryMounter mounter, MountPointType locationType, BodyCoverage restrictions) { if (accessory && !LizittUtil.IsUnityDestroyed(mounter) && (mounter.GetCoverageFor(locationType) & restrictions) == 0) { return(mounter.CanMount(accessory, locationType)); } return(false); }
// 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; } }
/// <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); }