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); } }
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(); } }