internal void Clear(CameraUpdate update)
        {
            if (this.LastAddress == IntPtr.Zero)
            {
                return;
            }

            this.LastAddress  = IntPtr.Zero;
            this.LastSkeleton = IntPtr.Zero;
            this.LastFormId   = 0;
            this.LastFlags    = HideFlags.None;
            this.LastRaceId   = 0;

            this.CameraMain.Cull.Clear();
            this.SetFirstPersonSkeleton(null, update.GameCameraState.Id == TESCameraStates.FirstPerson, false);
            this.ClearHelmet();
        }
Пример #2
0
        protected void AddHeadBobModifier(CameraUpdate update, bool forceHeadBob = false, bool forceReducedStabilizeHistory = false, double multiplier = 1.0, long extraDuration = 0)
        {
            bool headBob = forceHeadBob || Settings.Instance.HeadBob;

            if (headBob)
            {
                double value  = 0.5;
                double amount = (forceHeadBob ? 1.0 : Settings.Instance.HeadBobAmount) * multiplier;
                if (amount > 0.01)
                {
                    value /= amount;
                    update.Values.StabilizeIgnorePositionZ.AddModifier(this, CameraValueModifier.ModifierTypes.SetIfPreviousIsHigherThanThis, value, true, extraDuration);
                }
            }

            if (headBob || forceReducedStabilizeHistory)
            {
                update.Values.StabilizeHistoryDuration.AddModifier(this, CameraValueModifier.ModifierTypes.SetIfPreviousIsHigherThanThis, 100.0, true, extraDuration);
            }
        }
        internal void UpdateMagicNodePosition(CameraUpdate update)
        {
            InitMagicNode();

            if (MagicNodes == null)
            {
                return;
            }

            for (var i = 0; i < MagicNodes.Length; i++)
            {
                var node = MagicNodes[i];
                var wt   = node.WorldTransform;

                {
                    wt.CopyFrom(FinalResult.Transform);
                    wt.Translate(MagicTranslates[i], wt.Position);
                }
            }
        }
Пример #4
0
 private void OnDisabled(CameraUpdate update)
 {
     this.UpdateSkeleton(this.GameWantsSkeletonMode > 0, this.GameWantsSkeletonMode < 0, this.GameWantsSkeletonMode < 0);
 }
Пример #5
0
 private void OnEnabled(CameraUpdate update)
 {
     this.LastActorTurnFrames = 0;
 }
Пример #6
0
        internal void Update(NiAVObject root, NiAVObject head, CameraUpdate update)
        {
            this.UpdateValues(update);

            var tpos = head.WorldTransform.Position;
            var spos = root.WorldTransform.Position;

            float x = tpos.X - spos.X;
            float y = tpos.Y - spos.Y;
            float z = tpos.Z - spos.Z;

            root.WorldTransform.Rotation.GetEulerAngles(this.TempPoint);
            float angle = this.TempPoint.Z;

            this.TempPoint.X = x;
            this.TempPoint.Y = y;
            this.TempPoint.Z = z;
            float len = this.TempPoint.Length;

            if (len > 0.0f)
            {
                this.TempPoint.Normalize(this.TempPoint);
            }

            tpos   = this.TempTransform.Position;
            tpos.X = 0.0f;
            tpos.Y = 0.0f;
            tpos.Z = 0.0f;

            this.TempTransform.LookAt(this.TempPoint);
            this.TempTransform.Rotation.RotateZ(angle, this.TempTransform.Rotation);

            this.TempPoint.X = 0.0f;
            this.TempPoint.Y = len;
            this.TempPoint.Z = 0.0f;
            this.TempTransform.Translate(this.TempPoint, this.TempPoint);

            x = this.TempPoint.X;
            y = this.TempPoint.Y;
            z = this.TempPoint.Z;

            root.WorldTransform.Rotation.GetEulerAngles(this.TempPoint);
            head.WorldTransform.Rotation.GetEulerAngles(this.TempTransform.Position);

            double ofx = Utility.ClampToPi(this.TempTransform.Position.Z - this.TempPoint.Z);
            double ofy = Utility.ClampToPi(this.TempTransform.Position.X - this.TempPoint.X);

            this.ApplyIgnoreOffset(ref ofx, ref ofy);

            long now = this.CameraMain.Plugin.Time;

            var e = new CameraStabilizeHistoryEntry();

            e.Time     = now;
            e.OffsetX  = (float)ofx;
            e.OffsetY  = (float)ofy;
            e.Position = new float[] { x, y, z };
            this.History.AddLast(e);

            this.NeedRecalculate = true;
        }
Пример #7
0
        internal void Update(CameraUpdate update)
        {
            var actor = update.Target.Actor;

            if (actor == null || update.Target.RootNode == null)
            {
                this.Clear(update);
                return;
            }

            {
                IntPtr addr   = actor.Address;
                uint   formId = actor.FormId;
                var    race   = actor.Race;
                uint   raceId = race != null ? race.FormId : 0;
                var    node   = update.Target.RootNode;
                IntPtr addr2  = node != null ? node.Address : IntPtr.Zero;

                if (addr != this.LastAddress || formId != this.LastFormId || raceId != this.LastRaceId || this.LastSkeleton != addr2)
                {
                    this.Clear(update);

                    this.LastAddress  = addr;
                    this.LastSkeleton = addr2;
                    this.LastFormId   = formId;
                    this.LastRaceId   = raceId;
                }
            }

            HideFlags wantFlags = HideFlags.None;

            if (update.Values.HideHead.CurrentValue >= 0.5)
            {
                wantFlags |= HideFlags.Head;
            }
            if (update.Values.HideHead2.CurrentValue >= 0.5)
            {
                wantFlags |= HideFlags.Head2;
            }
            if (update.Values.HideHelmet.CurrentValue >= 0.5)
            {
                wantFlags |= HideFlags.Helmet;
            }
            if (update.Values.HideArms.CurrentValue >= 0.5)
            {
                wantFlags |= HideFlags.Arms;
            }
            if (update.Values.Show1stPersonArms.CurrentValue >= 0.5)
            {
                wantFlags |= HideFlags.Show1st;
            }
            switch (update.GameCameraState.Id)
            {
            case TESCameraStates.FirstPerson:
            case TESCameraStates.Free:
                break;

            default:
                wantFlags |= HideFlags.Has1st;
                break;
            }

            if (wantFlags == this.LastFlags)
            {
                if ((wantFlags & HideFlags.Helmet) != HideFlags.None)
                {
                    this.UpdateHelmet(update.Target.RootNode);
                }
                return;
            }

            if ((wantFlags & HideFlags.NeedUpdate) != (this.LastFlags & HideFlags.NeedUpdate))
            {
                this.CameraMain.Cull.Clear(this.HadHeadInHelmetNodes ? this.LastHeadAddress : IntPtr.Zero);
                this.ClearHelmet();
                this.HadHeadInHelmetNodes = false;
                this.LastFlags           &= ~HideFlags.NeedUpdate;
                this.UpdateHideWithCull(actor, wantFlags, update.Target.RootNode.As <NiNode>());
            }

            if ((wantFlags & HideFlags.Has1st) != (this.LastFlags & HideFlags.Has1st))
            {
                if ((wantFlags & HideFlags.Has1st) != HideFlags.None)
                {
                    var skeleton = actor.GetSkeletonNode(true);
                    if (skeleton != null)
                    {
                        this.SetFirstPersonSkeleton(skeleton, update.GameCameraState.Id == TESCameraStates.FirstPerson, (wantFlags & HideFlags.Show1st) != HideFlags.None);
                        this.LastFlags |= HideFlags.Has1st;
                        if ((wantFlags & HideFlags.Show1st) != HideFlags.None)
                        {
                            this.LastFlags |= HideFlags.Show1st;
                        }
                    }
                }
                else
                {
                    this.LastFlags &= ~(HideFlags.Has1st | HideFlags.Show1st);
                    this.SetFirstPersonSkeleton(null, update.GameCameraState.Id == TESCameraStates.FirstPerson, false);
                }
            }
        }
        internal void Update(NiAVObject root, NiAVObject head, CameraUpdate update)
        {
            UpdateValues(update);

            var tpos = head.WorldTransform.Position;
            var spos = root.WorldTransform.Position;

            var x = tpos.X - spos.X;
            var y = tpos.Y - spos.Y;
            var z = tpos.Z - spos.Z;

            root.WorldTransform.Rotation.GetEulerAngles(TempPoint);
            var angle = TempPoint.Z;

            TempPoint.X = x;
            TempPoint.Y = y;
            TempPoint.Z = z;
            var len = TempPoint.Length;

            if (len > 0.0f)
            {
                TempPoint.Normalize(TempPoint);
            }

            tpos   = TempTransform.Position;
            tpos.X = 0.0f;
            tpos.Y = 0.0f;
            tpos.Z = 0.0f;

            TempTransform.LookAt(TempPoint);
            TempTransform.Rotation.RotateZ(angle, TempTransform.Rotation);

            TempPoint.X = 0.0f;
            TempPoint.Y = len;
            TempPoint.Z = 0.0f;
            TempTransform.Translate(TempPoint, TempPoint);

            x = TempPoint.X;
            y = TempPoint.Y;
            z = TempPoint.Z;

            root.WorldTransform.Rotation.GetEulerAngles(TempPoint);
            head.WorldTransform.Rotation.GetEulerAngles(TempTransform.Position);

            var ofx = Utility.ClampToPi(TempTransform.Position.Z - TempPoint.Z);
            var ofy = Utility.ClampToPi(TempTransform.Position.X - TempPoint.X);

            ApplyIgnoreOffset(ref ofx, ref ofy);

            var now = CameraMain.Plugin.Time;

            var e = new CameraStabilizeHistoryEntry();

            e.Time     = now;
            e.OffsetX  = (float)ofx;
            e.OffsetY  = (float)ofy;
            e.Position = new[] { x, y, z };
            History.AddLast(e);

            NeedRecalculate = true;
        }
Пример #9
0
 internal virtual void Update(CameraUpdate update)
 {
 }
Пример #10
0
 internal virtual bool Check(CameraUpdate update)
 {
     return(true);
 }
Пример #11
0
 internal virtual void OnLeaving(CameraUpdate update)
 {
 }
Пример #12
0
 internal virtual void OnEntering(CameraUpdate update)
 {
 }
Пример #13
0
        internal static bool Apply(CameraUpdate update, NiTransform transform, NiPoint3 result)
        {
            init();

            if (update == null || transform == null || result == null)
            {
                return(false);
            }

            if (update.Values.CollisionEnabled.CurrentValue < 0.5)
            {
                return(false);
            }

            var actor = update.Target.Actor;

            if (actor == null)
            {
                return(false);
            }

            var cell = actor.ParentCell;

            if (cell == null)
            {
                return(false);
            }

            float safety = (float)(update.Values.NearClip.CurrentValue + 1.0);

            if (safety < 1.0f)
            {
                safety = 1.0f;
            }

            float safety2 = Math.Max(0.0f, Settings.Instance.CameraCollisionSafety);

            var tpos = transform.Position;

            TempPoint1.CopyFrom(actor.Position);
            TempPoint1.Z = tpos.Z;

            if (safety2 > 0.0f)
            {
                TempSafety.Y = -safety2 * 0.5f;
                TempTransform.CopyFrom(transform);
                TempTransform.Position.CopyFrom(TempPoint1);
                TempTransform.Translate(TempSafety, TempPoint1);
            }

            TempNormal.X = tpos.X - TempPoint1.X;
            TempNormal.Y = tpos.Y - TempPoint1.Y;
            TempNormal.Z = tpos.Z - TempPoint1.Z;

            float len = TempNormal.Length;

            if (len <= 0.0f)
            {
                return(false);
            }

            TempNormal.Normalize(TempNormal);
            TempNormal.Multiply(len + safety + safety2, TempNormal);

            TempPoint2.X = TempPoint1.X + TempNormal.X;
            TempPoint2.Y = TempPoint1.Y + TempNormal.Y;
            TempPoint2.Z = TempPoint1.Z + TempNormal.Z;

            var ls = TESObjectCELL.RayCast(new RayCastParameters()
            {
                Cell  = cell,
                Begin = new float[] { TempPoint1.X, TempPoint1.Y, TempPoint1.Z },
                End   = new float[] { TempPoint2.X, TempPoint2.Y, TempPoint2.Z }
            });

            if (ls == null || ls.Count == 0)
            {
                return(false);
            }

            RayCastResult     best     = null;
            float             bestDist = 0.0f;
            List <NiAVObject> ignore   = new List <NiAVObject>(3);

            {
                var sk = actor.GetSkeletonNode(true);
                if (sk != null)
                {
                    ignore.Add(sk);
                }
            }
            {
                var sk = actor.GetSkeletonNode(false);
                if (sk != null)
                {
                    ignore.Add(sk);
                }
            }
            if (update.CachedMounted)
            {
                var mount = actor.GetMount();
                if (mount != null)
                {
                    var sk = mount.GetSkeletonNode(false);
                    if (sk != null)
                    {
                        ignore.Add(sk);
                    }
                }
            }

            foreach (var r in ls)
            {
                if (!IsValid(r, ignore))
                {
                    continue;
                }

                float dist = r.Fraction;
                if (best == null)
                {
                    best     = r;
                    bestDist = dist;
                }
                else if (dist < bestDist)
                {
                    best     = r;
                    bestDist = dist;
                }
            }

            if (best == null)
            {
                return(false);
            }

            bestDist *= len + safety + safety2;
            bestDist -= safety + safety2;
            bestDist /= len + safety + safety2;

            // Negative is ok!

            result.X = (TempPoint2.X - TempPoint1.X) * bestDist + TempPoint1.X;
            result.Y = (TempPoint2.Y - TempPoint1.Y) * bestDist + TempPoint1.Y;
            result.Z = (TempPoint2.Z - TempPoint1.Z) * bestDist + TempPoint1.Z;

            return(true);
        }
Пример #14
0
        private void DoUpdate(CameraUpdate update)
        {
            {
                var wasEnabled = IsEnabled;
                var isEnabled  = CalculateEnabled(update);

                if (wasEnabled != isEnabled)
                {
                    if (!isEnabled)
                    {
                        Stack.DisableAll(update);
                    }

                    IsEnabled = isEnabled;
                    if (isEnabled)
                    {
                        OnEnabled(update);
                    }
                    else
                    {
                        OnDisabled(update);
                    }
                }
            }

            if (IsEnabled)
            {
                OnUpdating(0);
            }

            if (IsEnabled)
            {
                if (Stabilize == null || Stabilize.ShouldRecreate(update.Target))
                {
                    Stabilize = new CameraStabilize(this, update.Target);
                }

                Stabilize?.Update(update.Target.StabilizeRootNode, update.Target.HeadNode, update);
            }

            Stack.Check(update);
            Stack.Update(update);
            update.Values.Update(Plugin.Time, IsEnabled);
            Hide.Update(update);
            {
                var isFpArms = IsEnabled && update.Values.Show1stPersonArms.CurrentValue >= 0.5;
                if (isFpArms != WasUsingFirstPersonArms)
                {
                    WasUsingFirstPersonArms = isFpArms;
                }
            }

            if (IsEnabled)
            {
                var mode      = update.Values.SkeletonMode.CurrentValue;
                var wantThird = true;
                if (mode <= -0.5)
                {
                    wantThird = !WasUsingFirstPersonArms;
                }
                else if (mode >= 0.5)
                {
                    wantThird = false;
                }
                //else wantThird = true;

                var showFirst = WasUsingFirstPersonArms;
                var showThird = !(DidCollideLastUpdate && Settings.Instance.HidePlayerWhenColliding == 2);

                UpdateSkeleton(showFirst, showThird, wantThird);
            }

            if (IsEnabled)
            {
                if (Stabilize == null || !Stabilize.Get(update.Target.StabilizeRootNode, BaseRoot.Transform))
                {
                    BaseRoot.Transform.CopyFrom(update.Target.HeadNode.WorldTransform);
                }
                BaseHead.Transform.CopyFrom(update.Target.HeadNode.WorldTransform);

                CameraResult cur = null;
                using (cur)
                {
                    {
                        var posRatio = update.Values.PositionFromHead.CurrentValue;
                        switch (posRatio)
                        {
                        case 0.0:
                            BaseResult.Transform.Position.CopyFrom(BaseRoot.Transform.Position);
                            break;

                        case 1.0:
                            BaseResult.Transform.Position.CopyFrom(BaseHead.Transform.Position);
                            break;

                        default:
                        {
                            var pos     = BaseResult.Transform.Position;
                            var rootPos = BaseRoot.Transform.Position;
                            var headPos = BaseHead.Transform.Position;

                            pos.X = (float)((headPos.X - rootPos.X) * posRatio + rootPos.X);
                            pos.Y = (float)((headPos.Y - rootPos.Y) * posRatio + rootPos.Y);
                            pos.Z = (float)((headPos.Z - rootPos.Z) * posRatio + rootPos.Z);
                            break;
                        }
                        }
                    }

                    // Calculate base rotation.
                    {
                        var rotRatio = update.Values.RotationFromHead.CurrentValue;
                        switch (rotRatio)
                        {
                        case 0.0:
                            BaseResult.Transform.Rotation.CopyFrom(BaseRoot.Transform.Rotation);
                            break;

                        case 1.0:
                            BaseResult.Transform.Rotation.CopyFrom(BaseHead.Transform.Rotation);
                            break;

                        default:
                        {
                            var rot     = BaseResult.Transform.Rotation;
                            var rootRot = BaseRoot.Transform.Rotation;
                            var headRot = BaseHead.Transform.Rotation;

                            rootRot.Interpolate(headRot, (float)rotRatio, rot);
                            break;
                        }
                        }
                    }

                    cur = BaseResult;

                    // Calculate offset based on object rotation itself.
                    {
                        var root = update.Target.RootNode;
                        if (root != null)
                        {
                            var x = Values.OffsetObjectPositionX.CurrentValue;
                            var y = Values.OffsetObjectPositionY.CurrentValue;
                            var z = Values.OffsetObjectPositionZ.CurrentValue;

                            if (x != 0.0 || y != 0.0 || z != 0.0)
                            {
                                Offset1Result.Transform.Position.CopyFrom(BaseResult.Transform.Position);
                                Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation);
                                ApplyPositionOffset(Offset1Result.Transform, (float)x, (float)y, (float)z,
                                                    BaseResult.Transform.Position);
                            }
                        }
                    }

                    // Look down offset.
                    if (Default._look_downoffset_ratio > 0.0f || Default._look_downoffset_ratio_leftrightmove > 0.0f)
                    {
                        var ratio = Default._look_downoffset_ratio;
                        var root  = update.Target.RootNode;
                        if (root != null)
                        {
                            var x = Settings.Instance.DownOffsetX * ratio;
                            var y = Settings.Instance.DownOffsetY * ratio;
                            var z = Settings.Instance.DownOffsetZ * ratio;

                            y += Settings.Instance.TryFixLeftRightMovementClipping *
                                 Default._look_downoffset_ratio_leftrightmove;

                            if (x != 0.0f || y != 0.0f || z != 0.0f)
                            {
                                Offset1Result.Transform.Position.CopyFrom(BaseResult.Transform.Position);
                                Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation);
                                ApplyPositionOffset(Offset1Result.Transform, x, y, z, BaseResult.Transform.Position);
                            }
                        }
                    }

                    // Calculate offset #1.
                    {
                        var rx = (float)Values.Offset1RotationX.CurrentValue;
                        var ry = (float)Values.Offset1RotationY.CurrentValue;
                        var px = (float)Values.Offset1PositionX.CurrentValue;
                        var py = (float)Values.Offset1PositionY.CurrentValue;
                        var pz = (float)Values.Offset1PositionZ.CurrentValue;

                        var hasRot = rx != 0.0f || ry != 0.0f;
                        var hasPos = px != 0.0f || py != 0.0f || pz != 0.0f;

                        if (hasRot || hasPos)
                        {
                            Offset1Result.Transform.CopyFrom(cur.Transform);
                            if (hasRot)
                            {
                                ApplyRotationOffset(Offset1Result.Transform.Rotation, rx, ry,
                                                    Offset1Result.Transform.Rotation);
                            }
                            if (hasPos)
                            {
                                ApplyPositionOffset(Offset1Result.Transform, px, py, pz, Offset1Result.Transform.Position);
                            }

                            cur = Offset1Result;
                        }
                    }

                    // Calculate input.
                    {
                        var extraX = 0.0f;
                        var extraY = 0.0f;
                        if (LastActorTurnFrames > 0)
                        {
                            LastActorTurnFrames--;
                            extraX = LastActorTurnX;
                            //extraY = this.LastActorTurnY;
                        }

                        var rx = (float)(Values.InputRotationX.CurrentValue + extraX) *
                                 (float)Values.InputRotationXMultiplier.CurrentValue;
                        var ry = (float)(Values.InputRotationY.CurrentValue + extraY) *
                                 (float)Values.InputRotationYMultiplier.CurrentValue;

                        if (rx != 0.0f || ry != 0.0f)
                        {
                            InputResult.Transform.CopyFrom(cur.Transform);
                            ApplyRotationOffset(InputResult.Transform.Rotation, rx, ry, InputResult.Transform.Rotation);

                            cur = InputResult;
                        }
                    }

                    // Calculate offset #2.
                    {
                        var rx = (float)Values.Offset2RotationX.CurrentValue;
                        var ry = (float)Values.Offset2RotationY.CurrentValue;
                        var px = (float)Values.Offset2PositionX.CurrentValue;
                        var py = (float)Values.Offset2PositionY.CurrentValue;
                        var pz = (float)Values.Offset2PositionZ.CurrentValue;

                        var hasRot = rx != 0.0f || ry != 0.0f;
                        var hasPos = px != 0.0f || py != 0.0f || pz != 0.0f;

                        if (hasRot || hasPos)
                        {
                            Offset2Result.Transform.CopyFrom(cur.Transform);
                            if (hasRot)
                            {
                                ApplyRotationOffset(Offset2Result.Transform.Rotation, rx, ry,
                                                    Offset2Result.Transform.Rotation);
                            }
                            if (hasPos)
                            {
                                ApplyPositionOffset(Offset2Result.Transform, px, py, pz, Offset2Result.Transform.Position);
                            }

                            cur = Offset2Result;
                        }
                    }

                    // Apply tween from stabilize.
                    {
                        Stabilize?.ApplyTween(cur.Transform.Position, Plugin.Time);
                    }

                    // Apply collision of camera so we don't go inside walls, this can be done within the same transform.
                    {
                        DidCollideLastUpdate = CameraCollision.Apply(update, cur.Transform, cur.Transform.Position);
                    }

                    // Calculate final result.
                    {
                        FinalResult.Transform.CopyFrom(cur.Transform);
                    }
                }

                update.GameCameraNode.LocalTransform.CopyFrom(FinalResult.Transform);
                update.GameCameraNode.Update(0.0f);

                Hide.UpdateFirstPersonSkeletonRotation(update);

                if (update.GameCameraState is ThirdPersonState third)
                {
                    third.Position.CopyFrom(update.GameCameraNode.LocalTransform.Position);
                }

                if (WasUsingFirstPersonArms)
                {
                    UpdateMagicNodePosition(update);
                }
            }
            else
            {
                DidCollideLastUpdate = false;
            }

            if (IsEnabled)
            {
                OnUpdating(1);
            }

            if (!IsEnabled && Settings.Instance.ReplaceDefaultCamera &&
                update.GameCameraState.Id == TESCameraStates.FirstPerson && IsGameCameraSwitchControlsEnabled())
            {
                update.GameCamera.EnterThirdPerson();
                SetWantState(WantStates.EnabledFromTogglePOV);
            }

            FixSensitivityMode = IsEnabled && update.GameCameraState.Id == TESCameraStates.ThirdPerson2 &&
                                 Memory.ReadUInt8(update.GameCameraState.Address + 0xDC) != 0;
        }
Пример #15
0
        private bool CalculateEnabled(CameraUpdate update)
        {
            int keyCode = Settings.Instance.ToggleHotkey;

            if (keyCode > 0 && NetScriptFramework.Tools.Input.IsPressed((NetScriptFramework.Tools.VirtualKeys)keyCode))
            {
                if (!this.HadKey)
                {
                    this.HadKey = true;
                    if (this.IsEnabled)
                    {
                        this.SetWantState(WantStates.DisabledFromHotkey);
                    }
                    else
                    {
                        this.SetWantState(WantStates.EnabledFromHotkey);
                    }
                }
            }
            else
            {
                this.HadKey = false;
            }

            update.Values.WantEnabled.Update(this.Plugin.Time, this.IsEnabled);
            update.Values.WantDisabled.Update(this.Plugin.Time, this.IsEnabled);

            if (update.Values.WantDisabled.CurrentValue > 0.0 || update.Values.WantEnabled.CurrentValue <= 0.0)
            {
                return(false);
            }

            switch (update.GameCameraState.Id)
            {
            case TESCameraStates.Free:
            case TESCameraStates.FirstPerson:
            case TESCameraStates.TweenMenu:
            case TESCameraStates.AutoVanity:
                return(false);

            case TESCameraStates.VATS:
            {
                if (Settings.Instance.DisableDuringKillmove)
                {
                    return(false);
                }
            }
            break;
            }

            var menuManager = MenuManager.Instance;

            if (menuManager == null)
            {
                return(false);
            }

            if (menuManager.IsMenuOpen("RaceSex Menu"))
            {
                return(false);
            }

            return(true);
        }
Пример #16
0
        private void DoUpdate(CameraUpdate update)
        {
            {
                bool wasEnabled = this.IsEnabled;
                bool isEnabled  = this.CalculateEnabled(update);

                if (wasEnabled != isEnabled)
                {
                    if (!isEnabled)
                    {
                        this.Stack.DisableAll(update);
                    }

                    this.IsEnabled = isEnabled;
                    if (isEnabled)
                    {
                        this.OnEnabled(update);
                    }
                    else
                    {
                        this.OnDisabled(update);
                    }
                }
            }

            if (this.IsEnabled)
            {
                this.OnUpdating(0);
            }

            if (this.IsEnabled)
            {
                if (this.Stabilize == null || this.Stabilize.ShouldRecreate(update.Target))
                {
                    this.Stabilize = new CameraStabilize(this, update.Target);
                }

                if (this.Stabilize != null)
                {
                    this.Stabilize.Update(update.Target.StabilizeRootNode, update.Target.HeadNode, update);
                }
            }

            this.Stack.Check(update);
            this.Stack.Update(update);
            update.Values.Update(this.Plugin.Time, this.IsEnabled);
            this.Hide.Update(update);
            {
                bool isFpArms = this.IsEnabled && update.Values.Show1stPersonArms.CurrentValue >= 0.5;
                if (isFpArms != this.WasUsingFirstPersonArms)
                {
                    this.WasUsingFirstPersonArms = isFpArms;
                }
            }

            if (this.IsEnabled)
            {
                double mode      = update.Values.SkeletonMode.CurrentValue;
                bool   wantThird = true;
                if (mode <= -0.5)
                {
                    wantThird = !this.WasUsingFirstPersonArms;
                }
                else if (mode >= 0.5)
                {
                    wantThird = false;
                }
                //else wantThird = true;

                bool showFirst = this.WasUsingFirstPersonArms;
                bool showThird = true;

                if (this.DidCollideLastUpdate && Settings.Instance.HidePlayerWhenColliding == 2)
                {
                    showThird = false;
                }

                this.UpdateSkeleton(showFirst, showThird, wantThird);
            }

            if (this.IsEnabled)
            {
                if (this.Stabilize == null || !this.Stabilize.Get(update.Target.StabilizeRootNode, this.BaseRoot.Transform))
                {
                    this.BaseRoot.Transform.CopyFrom(update.Target.HeadNode.WorldTransform);
                }
                this.BaseHead.Transform.CopyFrom(update.Target.HeadNode.WorldTransform);

                CameraResult cur = null;

                // Calculate base position.
                {
                    double posRatio = update.Values.PositionFromHead.CurrentValue;
                    if (posRatio == 0.0)
                    {
                        this.BaseResult.Transform.Position.CopyFrom(this.BaseRoot.Transform.Position);
                    }
                    else if (posRatio == 1.0)
                    {
                        this.BaseResult.Transform.Position.CopyFrom(this.BaseHead.Transform.Position);
                    }
                    else
                    {
                        var pos     = this.BaseResult.Transform.Position;
                        var rootPos = this.BaseRoot.Transform.Position;
                        var headPos = this.BaseHead.Transform.Position;

                        pos.X = (float)((headPos.X - rootPos.X) * posRatio + rootPos.X);
                        pos.Y = (float)((headPos.Y - rootPos.Y) * posRatio + rootPos.Y);
                        pos.Z = (float)((headPos.Z - rootPos.Z) * posRatio + rootPos.Z);
                    }
                }

                // Calculate base rotation.
                {
                    double rotRatio = update.Values.RotationFromHead.CurrentValue;
                    if (rotRatio == 0.0)
                    {
                        this.BaseResult.Transform.Rotation.CopyFrom(this.BaseRoot.Transform.Rotation);
                    }
                    else if (rotRatio == 1.0)
                    {
                        this.BaseResult.Transform.Rotation.CopyFrom(this.BaseHead.Transform.Rotation);
                    }
                    else
                    {
                        var rot     = this.BaseResult.Transform.Rotation;
                        var rootRot = this.BaseRoot.Transform.Rotation;
                        var headRot = this.BaseHead.Transform.Rotation;

                        rootRot.Interpolate(headRot, (float)rotRatio, rot);
                    }
                }

                cur = this.BaseResult;

                // Calculate offset based on object rotation itself.
                {
                    var root = update.Target.RootNode;
                    if (root != null)
                    {
                        double x = this.Values.OffsetObjectPositionX.CurrentValue;
                        double y = this.Values.OffsetObjectPositionY.CurrentValue;
                        double z = this.Values.OffsetObjectPositionZ.CurrentValue;

                        if (x != 0.0 || y != 0.0 || z != 0.0)
                        {
                            this.Offset1Result.Transform.Position.CopyFrom(this.BaseResult.Transform.Position);
                            this.Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation);
                            this.ApplyPositionOffset(this.Offset1Result.Transform, (float)x, (float)y, (float)z, this.BaseResult.Transform.Position);
                        }
                    }
                }

                // Look down offset.
                if (States.Default._look_downoffset_ratio > 0.0f || States.Default._look_downoffset_ratio_leftrightmove > 0.0f)
                {
                    float ratio = States.Default._look_downoffset_ratio;
                    var   root  = update.Target.RootNode;
                    if (root != null)
                    {
                        float x = Settings.Instance.DownOffsetX * ratio;
                        float y = Settings.Instance.DownOffsetY * ratio;
                        float z = Settings.Instance.DownOffsetZ * ratio;

                        y += Settings.Instance.TryFixLeftRightMovementClipping * States.Default._look_downoffset_ratio_leftrightmove;

                        if (x != 0.0f || y != 0.0f || z != 0.0f)
                        {
                            this.Offset1Result.Transform.Position.CopyFrom(this.BaseResult.Transform.Position);
                            this.Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation);
                            this.ApplyPositionOffset(this.Offset1Result.Transform, x, y, z, this.BaseResult.Transform.Position);
                        }
                    }
                }

                // Calculate offset #1.
                {
                    float rx = (float)this.Values.Offset1RotationX.CurrentValue;
                    float ry = (float)this.Values.Offset1RotationY.CurrentValue;
                    float px = (float)this.Values.Offset1PositionX.CurrentValue;
                    float py = (float)this.Values.Offset1PositionY.CurrentValue;
                    float pz = (float)this.Values.Offset1PositionZ.CurrentValue;

                    bool hasRot = rx != 0.0f || ry != 0.0f;
                    bool hasPos = px != 0.0f || py != 0.0f || pz != 0.0f;

                    if (hasRot || hasPos)
                    {
                        this.Offset1Result.Transform.CopyFrom(cur.Transform);
                        if (hasRot)
                        {
                            this.ApplyRotationOffset(this.Offset1Result.Transform.Rotation, rx, ry, this.Offset1Result.Transform.Rotation);
                        }
                        if (hasPos)
                        {
                            this.ApplyPositionOffset(this.Offset1Result.Transform, px, py, pz, this.Offset1Result.Transform.Position);
                        }

                        cur = this.Offset1Result;
                    }
                }

                // Calculate input.
                {
                    float extraX = 0.0f;
                    float extraY = 0.0f;
                    if (this.LastActorTurnFrames > 0)
                    {
                        this.LastActorTurnFrames--;
                        extraX = this.LastActorTurnX;
                        //extraY = this.LastActorTurnY;
                    }

                    float rx = (float)(this.Values.InputRotationX.CurrentValue + extraX) * (float)this.Values.InputRotationXMultiplier.CurrentValue;
                    float ry = (float)(this.Values.InputRotationY.CurrentValue + extraY) * (float)this.Values.InputRotationYMultiplier.CurrentValue;

                    if (rx != 0.0f || ry != 0.0f)
                    {
                        this.InputResult.Transform.CopyFrom(cur.Transform);
                        this.ApplyRotationOffset(this.InputResult.Transform.Rotation, rx, ry, this.InputResult.Transform.Rotation);

                        cur = this.InputResult;
                    }
                }

                // Calculate offset #2.
                {
                    float rx = (float)this.Values.Offset2RotationX.CurrentValue;
                    float ry = (float)this.Values.Offset2RotationY.CurrentValue;
                    float px = (float)this.Values.Offset2PositionX.CurrentValue;
                    float py = (float)this.Values.Offset2PositionY.CurrentValue;
                    float pz = (float)this.Values.Offset2PositionZ.CurrentValue;

                    bool hasRot = rx != 0.0f || ry != 0.0f;
                    bool hasPos = px != 0.0f || py != 0.0f || pz != 0.0f;

                    if (hasRot || hasPos)
                    {
                        this.Offset2Result.Transform.CopyFrom(cur.Transform);
                        if (hasRot)
                        {
                            this.ApplyRotationOffset(this.Offset2Result.Transform.Rotation, rx, ry, this.Offset2Result.Transform.Rotation);
                        }
                        if (hasPos)
                        {
                            this.ApplyPositionOffset(this.Offset2Result.Transform, px, py, pz, this.Offset2Result.Transform.Position);
                        }

                        cur = this.Offset2Result;
                    }
                }

                // Apply tween from stabilize.
                {
                    if (this.Stabilize != null)
                    {
                        this.Stabilize.ApplyTween(cur.Transform.Position, this.Plugin.Time);
                    }
                }

                // Apply collision of camera so we don't go inside walls, this can be done within the same transform.
                {
                    this.DidCollideLastUpdate = CameraCollision.Apply(update, cur.Transform, cur.Transform.Position);
                }

                // Calculate final result.
                {
                    this.FinalResult.Transform.CopyFrom(cur.Transform);
                }

                update.GameCameraNode.LocalTransform.CopyFrom(this.FinalResult.Transform);
                update.GameCameraNode.Update(0.0f);

                this.Hide.UpdateFirstPersonSkeletonRotation(update);

                var third = update.GameCameraState.As <ThirdPersonState>();
                if (third != null)
                {
                    third.Position.CopyFrom(update.GameCameraNode.LocalTransform.Position);
                }

                if (this.WasUsingFirstPersonArms)
                {
                    this.UpdateMagicNodePosition(update);
                }
            }
            else
            {
                this.DidCollideLastUpdate = false;
            }

            if (this.IsEnabled)
            {
                this.OnUpdating(1);
            }

            if (!this.IsEnabled && Settings.Instance.ReplaceDefaultCamera && update.GameCameraState.Id == TESCameraStates.FirstPerson && this.IsGameCameraSwitchControlsEnabled())
            {
                update.GameCamera.EnterThirdPerson();
                this.SetWantState(WantStates.EnabledFromTogglePOV);
            }

            this.FixSensitivityMode = this.IsEnabled && update.GameCameraState.Id == TESCameraStates.ThirdPerson2 && Memory.ReadUInt8(update.GameCameraState.Address + 0xDC) != 0;
        }
Пример #17
0
 private void OnDisabled(CameraUpdate update)
 {
     UpdateSkeleton(GameWantsSkeletonMode > 0, GameWantsSkeletonMode < 0, GameWantsSkeletonMode < 0);
 }