예제 #1
0
    public override void _PhysicsProcess(float Delta)
    {
        if (Frozen)
        {
            return;
        }

        if (Possessed && !Dying && Health <= 0)
        {
            Entities.Self.PleaseDestroyMe(Name);
            Dying = true;
        }

        if (Dying)
        {
            return;
        }

        var OriginalChunkTuple = World.GetChunkTuple(Translation);

        if (Net.Work.IsNetworkServer())
        {
            List <DroppedItem> ToPickUpList = new List <DroppedItem>();
            foreach (DroppedItem Item in World.ItemList)
            {
                if (Translation.DistanceTo(Item.Translation) <= ItemPickupDistance && Item.Life >= DroppedItem.MinPickupLife)
                {
                    PhysicsDirectSpaceState      State   = GetWorld().DirectSpaceState;
                    Godot.Collections.Dictionary Results = State.IntersectRay(Translation, Item.Translation, new Godot.Collections.Array {
                        this
                    }, 4);
                    if (Results.Count <= 0)
                    {
                        ToPickUpList.Add(Item);
                    }
                }
            }
            if (ToPickUpList.Count > 0)
            {
                foreach (DroppedItem Item in ToPickUpList)
                {
                    Net.Players[Id].Plr.MatchSome(
                        (Plr) =>
                    {
                        var Instance         = new Items.Instance(Item.Type);
                        Option <int[]> Slots = Plr.ItemGive(Instance);

                        //TODO: Grab ungiven count from Instance to only pick up part of stack
                        //Dropped items currently are only one item though

                        Slots.MatchSome(
                            (ActualSlots) =>
                        {
                            Plr.NotifyPickedUpItem();
                            Entities.SendDestroy(Item.Name);
                            Item.Destroy();
                        }
                            );
                    }
                        );
                }
            }

            Entities.AsServerMaybePhaseOut(this);
        }

        if (!Possessed)
        {
            return;
        }

        CurrentCooldown = Clamp(CurrentCooldown + (100 * Delta), 0, CurrentMaxCooldown);

        if (JumpAxis > 0 && OnFloor && !Ads)
        {
            Momentum.y = JumpStartForce;
            IsJumping  = true;
        }

        if (!OnFloor && !FlyMode)
        {
            Momentum.y = Clamp(Momentum.y - Gravity * Delta, -MaxVerticalSpeed, MaxVerticalSpeed);
        }

        if (FlyMode && JumpAxis <= 0 && !IsCrouching)
        {
            //In flymode and jump is not being held
            if (Momentum.y > 0)
            {
                Momentum.y = Mathf.Clamp(Momentum.y - FlyFriction * Delta, 0, MaxVerticalSpeed);
            }
            else if (Momentum.y < 0)
            {
                Momentum.y = Mathf.Clamp(Momentum.y + FlyFriction * Delta, -MaxVerticalSpeed, 0);
            }
        }

        if (OnFloor && !WasOnFloor && Abs(LastMomentumY) > SfxMinLandMomentumY)
        {
            float Volume = Abs(Clamp(LastMomentumY, -MaxVerticalSpeed, 0)) / 4 - 30;
            SfxManager.FpLand(Volume);
        }

        WasOnFloor = OnFloor;

        if (!IsJumping && (OnFloor || FlyMode))
        {
            float SpeedLimit = MovementSpeed * GetAdsMovementMultiplyer();
            if (FlyMode && IsFlySprinting)
            {
                SpeedLimit *= FlySprintMultiplier;
            }
            else if (IsCrouching)
            {
                SpeedLimit = (MovementSpeed * GetAdsMovementMultiplyer()) / CrouchMovementDivisor;
            }

            float X = 0, Z = 0;
            if (RightAxis > 0)
            {
                X = -RightSens;
            }
            else if (RightAxis < 0)
            {
                X = LeftSens;
            }
            if (ForwardAxis > 0)
            {
                Z = ForwardSens;
            }
            else if (ForwardAxis < 0)
            {
                Z = -BackwardSens;
            }

            float Speed = Momentum.Flattened().Length();
            if (Speed > 0)
            {
                if (FlyMode)
                {
                    Speed = Clamp(Speed - FlyFriction * Delta, 0, Speed);
                }
                else if (IsCrouching && Speed > SpeedLimit)
                {
                    Speed = Clamp(Speed - (Friction / SlideFrictionDivisor) * Delta, 0, Speed);
                }
                else
                {
                    Speed = Clamp(Speed - Friction * Delta, 0, Speed);
                }

                Vector3 HorzMomentum = Momentum.Flattened().Normalized() * Speed;
                Momentum.x = HorzMomentum.x;
                Momentum.z = HorzMomentum.z;
            }

            {
                Vector3 WishDir = ClampVec3(new Vector3(X, 0, Z), 0, 1) * SpeedLimit;
                WishDir = WishDir.Rotated(new Vector3(0, 1, 0), Deg2Rad(LookHorizontal));

                float Multiplier = Clamp(SpeedLimit - Momentum.Flattened().Length(), 0, SpeedLimit) / SpeedLimit;
                WishDir *= Multiplier;

                Momentum.x += WishDir.x;
                Momentum.z += WishDir.z;
            }
        }
        else
        {
            float X = 0, Z = 0;
            if (RightAxis > 0)
            {
                X = -RightSens;
            }
            else if (RightAxis < 0)
            {
                X = LeftSens;
            }
            if (ForwardAxis > 0)
            {
                Z = ForwardSens;
            }
            else if (ForwardAxis < 0)
            {
                Z = -BackwardSens;
            }

            Vector3 WishDir = new Vector3(X, 0, Z);
            WishDir  = WishDir.Rotated(new Vector3(0, 1, 0), Deg2Rad(LookHorizontal));
            Momentum = AirAccelerate(Momentum, WishDir, Delta);
        }

        LastMomentumY = Momentum.y;

        if (FlyMode)
        {
            Move(
                Momentum.Flattened()
                .Rotated(new Vector3(0, 1, 0), Deg2Rad(LoopRotation(-LookHorizontal)))
                .Rotated(new Vector3(1, 0, 0), Deg2Rad(LoopRotation(-ActualLookVertical)))
                .Rotated(new Vector3(0, 1, 0), Deg2Rad(LoopRotation(LookHorizontal))),
                Delta,
                1,
                60f,
                0f
                );

            Move(
                new Vector3(0, Momentum.y, 0)
                .Rotated(new Vector3(0, 1, 0), Deg2Rad(LoopRotation(LookHorizontal))),
                Delta,
                1,
                60f,
                0f
                );
        }
        else
        {
            Momentum = Move(Momentum, Delta, 1, 60f, MovementSpeed);
        }

        if (CrouchAxis == 0)
        {
            PhysicsDirectSpaceState State = GetWorld().DirectSpaceState;

            Godot.Collections.Dictionary DownResults = State.IntersectRay(Translation, Translation - new Vector3(0, RequiredUncrouchHeight, 0), new Godot.Collections.Array {
                this
            }, 1);
            Godot.Collections.Dictionary UpResults = State.IntersectRay(Translation, Translation + new Vector3(0, RequiredUncrouchHeight, 0), new Godot.Collections.Array {
                this
            }, 1);

            bool UnCrouch = false;
            if (UpResults.Count == 0)
            {
                UnCrouch = true;
            }
            else if (UpResults.Count > 0 && DownResults.Count == 0)
            {
                UnCrouch = true;
            }
            else if (UpResults.Count > 0 && DownResults.Count > 0)
            {
                float UpY   = ((Vector3)UpResults["position"]).y;
                float DownY = ((Vector3)DownResults["position"]).y;

                if (UpY - DownY >= RequiredUncrouchHeight)
                {
                    UnCrouch = true;
                }
            }

            if (UnCrouch)
            {
                IsCrouching = false;
                TickUncrouch(Delta);
            }
            else
            {
                TickCrouch(Delta);
            }
        }
        else if (IsCrouching)
        {
            TickCrouch(Delta);
        }

        Entities.MovedTick(this, OriginalChunkTuple);

        {
            Items.ID ItemId;
            if (Inventory[InventorySlot] != null)
            {
                ItemId = Inventory[InventorySlot].Id;
            }
            else
            {
                ItemId = Items.ID.ERROR;
            }

            Entities.ClientSendUpdate(
                Name,
                this.Transform,
                ActualLookVertical,
                IsJumping,
                IsCrouching,
                Health,
                ItemId,
                Momentum.Rotated(new Vector3(0, 1, 0),
                                 Deg2Rad(LoopRotation(-LookHorizontal))).z
                );
        }

        if (!World.GetChunkTuple(Translation).Equals(DepreciatedCurrentChunk))
        {
            DepreciatedCurrentChunk = World.GetChunkTuple(Translation);
            World.UnloadAndRequestChunks(Translation, Game.ChunkRenderDistance);
        }
    }
예제 #2
0
    public override void _PhysicsProcess(float Delta)
    {
        if (!Possessed || Frozen)
        {
            return;
        }

        {
            List <DroppedItem> ToPickUpList = new List <DroppedItem>();
            foreach (DroppedItem Item in World.ItemList)
            {
                if (CenterPosition().DistanceTo(Item.Translation) <= ItemPickupDistance && Item.Life >= DroppedItem.MinPickupLife)
                {
                    PhysicsDirectSpaceState      State   = GetWorld().DirectSpaceState;
                    Godot.Collections.Dictionary Results = State.IntersectRay(CenterPosition(), Item.Translation, new Godot.Collections.Array {
                        this
                    }, 1);
                    if (Results.Count <= 0)
                    {
                        ToPickUpList.Add(Item);
                    }
                }
            }
            if (ToPickUpList.Count > 0)
            {
                SfxManager.FpPickup();
                foreach (DroppedItem Item in ToPickUpList)
                {
                    if (Game.Mode.ShouldPickupItem(Item.Type))
                    {
                        World.Self.RequestDroppedItem(Net.Work.GetNetworkUniqueId(), Item.GetName());
                        World.ItemList.Remove(Item);
                    }
                }
            }
        }

        WallKickRecoverPercentage = Clamp(WallKickRecoverPercentage + Delta * WallKickRecoverSpeed, 0, 1);

        if (JumpAxis > 0 && WallKickRecoverPercentage >= MinWallKickRecoverPercentage && IsOnFloor())
        {
            Momentum.y = JumpStartForce;
            IsJumping  = true;
        }

        if (IsJumping && !WasOnFloor)
        {
            Momentum.y += JumpContinueForce * Delta;

            JumpTimer += Delta;
            if (JumpTimer >= MaxJumpLength)
            {
                JumpTimer = 0;
                IsJumping = false;
            }
        }

        if (!IsJumping && !FlyMode)
        {
            Momentum.y = Mathf.Clamp(Momentum.y - Gravity * Delta, -MaxVerticalSpeed, MaxVerticalSpeed);
        }

        if (FlyMode && JumpAxis <= 0 && !IsCrouching)
        {
            //In flymode and jump is not being held
            if (Momentum.y > 0)
            {
                Momentum.y = Mathf.Clamp(Momentum.y - Friction * Delta, 0, MaxVerticalSpeed);
            }
            else if (Momentum.y < 0)
            {
                Momentum.y = Mathf.Clamp(Momentum.y + Friction * Delta, -MaxVerticalSpeed, 0);
            }
        }

        if (IsOnFloor() && !WasOnFloor && Abs(LastMomentumY) > SfxMinLandMomentumY)
        {
            float Volume = Abs(Clamp(LastMomentumY, -MaxVerticalSpeed, 0)) / 2 - 30;
            SfxManager.FpLand(Volume);
        }

        WasOnFloor = IsOnFloor();

        if (!IsJumping && (IsOnFloor() || FlyMode))
        {
            float SpeedLimit = BaseMovementSpeed;
            if (IsSprinting)
            {
                SpeedLimit *= SprintMultiplyer;
            }

            float X = 0, Z = 0;
            if (RightAxis > 0)
            {
                X = -RightSens;
            }
            else if (RightAxis < 0)
            {
                X = LeftSens;
            }
            if (ForwardAxis > 0)
            {
                Z = ForwardSens;
            }
            else if (ForwardAxis < 0)
            {
                Z = -BackwardSens;
            }

            Vector3 WishDir = ClampVec3(new Vector3(X, 0, Z), 0, 1) * (SpeedLimit + Friction * Delta);
            WishDir = WishDir.Rotated(new Vector3(0, 1, 0), Deg2Rad(LookHorizontal));
            if (WishDir.Length() > 0)
            {
                Momentum.x = WishDir.x;
                Momentum.z = WishDir.z;
            }

            float Speed = Momentum.Length();
            if (Speed > 0)
            {
                Speed = Clamp(Speed - Friction * Delta, 0, Speed);
                Vector3 HorzMomentum = new Vector3(Momentum.x, 0, Momentum.z).Normalized() * Speed;
                Momentum.x = HorzMomentum.x;
                Momentum.z = HorzMomentum.z;
            }
        }
        else
        {
            float X = 0, Z = 0;
            if (RightAxis > 0)
            {
                X = -RightSens;
            }
            else if (RightAxis < 0)
            {
                X = LeftSens;
            }
            if (ForwardAxis > 0)
            {
                Z = ForwardSens;
            }
            else if (ForwardAxis < 0)
            {
                Z = -BackwardSens;
            }

            Vector3 WishDir = new Vector3(X, 0, Z);
            WishDir  = WishDir.Rotated(new Vector3(0, 1, 0), Deg2Rad(LookHorizontal)) * WallKickRecoverPercentage;
            Momentum = AirAccelerate(Momentum, WishDir, Delta);
        }

        LastMomentumY = Momentum.y;

        Vector3 OldPos = Translation;

        if (FlyMode)
        {
            Vector3 FlatVel = Momentum;
            FlatVel.y = 0;
            MoveAndSlide(FlatVel
                         .Rotated(new Vector3(0, 1, 0), Mathf.Deg2Rad(LoopRotation(-LookHorizontal)))
                         .Rotated(new Vector3(1, 0, 0), Mathf.Deg2Rad(LoopRotation(-LookVertical)))
                         .Rotated(new Vector3(0, 1, 0), Mathf.Deg2Rad(LoopRotation(LookHorizontal))),
                         new Vector3(0, 1, 0), true, 100, Mathf.Deg2Rad(60));

            MoveAndSlide(new Vector3(0, Momentum.y, 0).Rotated(new Vector3(0, 1, 0), Mathf.Deg2Rad(LookHorizontal)), new Vector3(0, 1, 0), true, 100, Mathf.Deg2Rad(60))
            .Rotated(new Vector3(0, 1, 0), Mathf.Deg2Rad(LoopRotation(-LookHorizontal)));
        }
        else
        {
            Momentum = MoveAndSlide(Momentum, new Vector3(0, 1, 0), true, 100, Mathf.Deg2Rad(60));

            if (GetSlideCount() > 0)
            {
                Game.Mode.OnPlayerCollide(GetSlideCollision(0));
            }

            if (JumpAxis > 0 && WallKickRecoverPercentage >= MinWallKickRecoverPercentage && IsOnWall() && GetSlideCount() > 0 && Game.Mode.ShouldWallKick())
            {
                WallKickRecoverPercentage = 0;

                Momentum  += WallKickHorzontalForce * GetSlideCollision(0).Normal;
                Momentum.y = WallKickJumpForce;

                SfxManager.FpWallKick();
            }
        }
        Vector3 NewPos = Translation;

        Translation = OldPos;
        if (NewPos != OldPos)
        {
            if (Game.Mode.ShouldPlayerMove(NewPos))
            {
                Translation = NewPos;
            }
        }

        if (!FlyMode && IsOnFloor() && Momentum.y <= 0f)
        {
            Momentum.y = -1f;
        }

        Net.SteelRpcUnreliable(this, nameof(Update), Translation, RotationDegrees);

        if (!World.GetChunkTuple(Translation).Equals(CurrentChunk))
        {
            CurrentChunk = World.GetChunkTuple(Translation);
            Net.UnloadAndRequestChunks();
        }
    }