public override void _PhysicsProcess(float Delta) { Items.Instance Item = Game.PossessedPlayer.Inventory[Game.PossessedPlayer.InventorySlot]; if (Item != null && Item.Type != CurrentMeshType) //null means no item in slot { GhostMesh.Mesh = Meshes[Item.Type]; CurrentMeshType = Item.Type; } GhostMesh.Translation = OldPositions[0]; GhostMesh.RotationDegrees = OldRotations[0]; GhostMesh.Visible = OldVisible[0]; Player Plr = Game.PossessedPlayer; OldVisible.RemoveAt(0); OldVisible.Add(false); if (Plr.Inventory[Plr.InventorySlot] != null) { RayCast BuildRayCast = Plr.GetNode("SteelCamera/RayCast") as RayCast; if (BuildRayCast.IsColliding()) { Structure Hit = BuildRayCast.GetCollider() as Structure; if (Hit != null) { System.Nullable <Vector3> GhostPosition = BuildPositions.Calculate(Hit, Plr.Inventory[Plr.InventorySlot].Type); if (GhostPosition != null) { Vector3 GhostRotation = BuildRotations.Calculate(Hit, Plr.Inventory[Plr.InventorySlot].Type); Translation = (Vector3)GhostPosition; RotationDegrees = GhostRotation; OldVisible[1] = true; } } } } if (OldVisible[1] == false) { OldVisible[0] = false; GhostMesh.Visible = false; } OldCanBuild.RemoveAt(0); if (GetOverlappingBodies().Count > 0) { GhostMesh.MaterialOverride = RedMat; OldCanBuild.Add(false); } else { GhostMesh.MaterialOverride = GreenMat; OldCanBuild.Add(true); } CanBuild = OldCanBuild[0]; OldPositions.RemoveAt(0); OldPositions.Add(Translation); OldRotations.RemoveAt(0); OldRotations.Add(RotationDegrees); }
public static void Fire(Items.Instance Item, Player UsingPlayer) { Projectiles.Fire(Projectiles.ProjectileID.ROCKET_JUMPER, UsingPlayer); UsingPlayer.SfxManager.FpRocketFire(); UsingPlayer.SetCooldown(0, FireCooldown, true); }
public static void Fire(Items.Instance Item, Player UsingPlayer) { { float Multiplyer = Pow(UsingPlayer.AdsMultiplyer, 2); for (int x = -2; x <= 2; x++) { for (int y = -2; y <= 2; y++) { Hitscan.QueueFire(x * AngularOffset * Multiplyer, y * AngularOffset * Multiplyer, Range, HeadshotDamage, BodyshotDamage, LegshotDamage); } } Hitscan.ApplyQueuedFire(); } Hitscan.ApplyAdditiveRecoil(VerticalRecoil, RecoilLength); if (UsingPlayer.IsCrouching) { UsingPlayer.SetCooldown(0, FireCooldown * UsingPlayer.AdsMultiplyer * Hitscan.CrouchAffectPercentage, true); } else { UsingPlayer.SetCooldown(0, FireCooldown * UsingPlayer.AdsMultiplyer, true); } UsingPlayer.SfxManager.FpScattershockFire(); }
public static void SendInventoryTo(IHasInventory HasInventory, int Receiver) { var Ids = new Items.ID[HasInventory.Inventory.Contents.Length]; var Counts = new int[HasInventory.Inventory.Contents.Length]; int Index = 0; while (Index < HasInventory.Inventory.Contents.Length) { Items.Instance Item = HasInventory.Inventory.Contents[Index]; if (Item is null) { Ids[Index] = Items.ID.NONE; Counts[Index] = 0; Index += 1; continue; } Ids[Index] = Item.Id; Counts[Index] = Item.Count; Index += 1; } Self.RpcUnreliableId(Receiver, nameof(ReceiveInventory), HasInventory.Name, Ids, Counts); }
public void ItemGive(Items.Instance ToGive) { for (int Slot = 0; Slot <= 9; Slot++) { if (!(Inventory[Slot] is null)) //If inventory item is not null { if (Inventory[Slot].Type == ToGive.Type) { Inventory[Slot].Count += ToGive.Count; HUDInstance.HotbarUpdate(); return; } } } for (int Slot = 0; Slot <= 9; Slot++) { if (Inventory[Slot] is null) { Inventory[Slot] = ToGive; HUDInstance.HotbarUpdate(); return; } } }
public static void Fire(Items.Instance Item, Player UsingPlayer) { Hitscan.Fire(0, 0, Range, HeadshotDamage, BodyshotDamage, LegshotDamage); Hitscan.ApplyRecoil(VerticalRecoil, HorizontalRecoil); UsingPlayer.SetCooldown(0, FireCooldown, true); UsingPlayer.SfxManager.FpThunderboltFire(); }
public override void _Ready() { GhostMesh = (MeshInstance)GD.Load <PackedScene>("res://World/GhostMesh.tscn").Instance(); GetParent().AddChild(GhostMesh); Items.Instance Item = Game.PossessedPlayer.Inventory[Game.PossessedPlayer.InventorySlot]; if (Item != null) //null means no item in slot { GhostMesh.Mesh = Items.Meshes[Item.Id]; CurrentMeshType = Item.Id; } }
public override void _Ready() { GhostMesh = ((PackedScene)(GD.Load("res://Building/GhostMesh.tscn"))).Instance() as MeshInstance; GetParent().AddChild(GhostMesh); Items.Instance Item = Game.PossessedPlayer.Inventory[Game.PossessedPlayer.InventorySlot]; if (Item != null) //null means no item in slot { GhostMesh.Mesh = Meshes[Item.Type]; CurrentMeshType = Item.Type; } }
public static void SecondaryFire(float Sens) { Game.PossessedPlayer.MatchSome( (Plr) => { if (Sens > 0 && !Plr.IsSecondaryFiring) { Plr.IsSecondaryFiring = true; Items.Instance CurrentItem = Plr.Inventory[Plr.InventorySlot]; if (CurrentItem == null || !Items.IdInfos[CurrentItem.Id].CanAds) { if (Plr.CurrentCooldown >= Plr.CurrentMaxCooldown) { RayCast BuildRayCast = Plr.GetNode <RayCast>("SteelCamera/RayCast"); if (BuildRayCast.IsColliding()) { if (BuildRayCast.GetCollider() is Tile Hit) { Hit.NetRemove(); Plr.SetCooldown(0, Player.BuildingCooldown, true); } } } } else if (CurrentItem != null && Items.IdInfos[CurrentItem.Id].CanAds) { Plr.Ads = true; Plr.IsFlySprinting = false; } } if (Sens <= 0 && Plr.IsSecondaryFiring) { Plr.IsSecondaryFiring = false; Items.Instance CurrentItem = Plr.Inventory[Plr.InventorySlot]; if (CurrentItem != null && Items.IdInfos[CurrentItem.Id].CanAds) { Plr.Ads = false; if (Plr.FlySprintSens > 0) { FlySprint(Plr.FlySprintSens); } } } } ); }
public void SecondaryFire(float Sens) { if (Sens > 0 && !IsSecondaryFiring) { IsSecondaryFiring = true; Items.Instance CurrentItem = Inventory[InventorySlot]; if (CurrentItem == null || !Items.IdInfos[CurrentItem.Id].CanAds) { if (CurrentCooldown >= CurrentMaxCooldown) { RayCast BuildRayCast = GetNode("SteelCamera/RayCast") as RayCast; if (BuildRayCast.IsColliding()) { Tile Hit = BuildRayCast.GetCollider() as Tile; if (Hit != null && Game.Mode.ShouldRemoveTile(Hit.Type, Hit.Translation, Hit.RotationDegrees, Hit.OwnerId)) { Hit.NetRemove(); SetCooldown(0, BuildingCooldown, true); } } } } else if (CurrentItem != null && Items.IdInfos[CurrentItem.Id].CanAds) { Ads = true; IsSprinting = false; } } if (Sens <= 0 && IsSecondaryFiring) { IsSecondaryFiring = false; Items.Instance CurrentItem = Inventory[InventorySlot]; if (CurrentItem != null && Items.IdInfos[CurrentItem.Id].CanAds) { Ads = false; if (SprintSens > 0) { Sprint(SprintSens); } } } }
public static void SendInventory(IHasInventory HasInventory) { if (!Net.Work.IsNetworkServer()) { throw new Exception($"Cannot run {nameof(SendInventory)} on client"); } foreach (int Receiver in Net.Players.Keys) { if (Receiver == Net.Work.GetNetworkUniqueId()) { continue; } Net.Players[Receiver].Plr.MatchSome( (Plr) => { var EntityChunk = World.GetChunkTuple(HasInventory.Translation); if (World.ChunkWithinDistanceFrom(EntityChunk, World.ChunkRenderDistances[Receiver], Plr.Translation)) { var Ids = new Items.ID[HasInventory.Inventory.Contents.Length]; var Counts = new int[HasInventory.Inventory.Contents.Length]; int Index = 0; while (Index < HasInventory.Inventory.Contents.Length) { Items.Instance Item = HasInventory.Inventory.Contents[Index]; if (Item is null) { Ids[Index] = Items.ID.NONE; Counts[Index] = 0; Index += 1; continue; } Ids[Index] = Item.Id; Counts[Index] = Item.Count; Index += 1; } Self.RpcUnreliableId(Receiver, nameof(ReceiveInventory), HasInventory.Name, Ids, Counts); } } ); } }
public static void Fire(Items.Instance Item, Player UsingPlayer) { Hitscan.QueueFire(0, 0, Range, HeadshotDamage, BodyshotDamage, LegshotDamage); Hitscan.ApplyQueuedFire(); Hitscan.ApplyAdditiveRecoil(VerticalRecoil, RecoilLength); if (UsingPlayer.IsCrouching) { UsingPlayer.SetCooldown(0, FireCooldown * UsingPlayer.AdsMultiplier * Hitscan.CrouchAffectPercentage, true); } else { UsingPlayer.SetCooldown(0, FireCooldown * UsingPlayer.AdsMultiplier, true); } UsingPlayer.SfxManager.FpThunderboltFire(); }
public static void Fire(Items.Instance Item, Player UsingPlayer) { JumperRocket Rocket = JumperRocketScene.Instance() as JumperRocket; Rocket.IsLocal = true; Rocket.Player = UsingPlayer; Rocket.Translation = UsingPlayer.RocketStart.GetGlobalTransform().origin; Rocket.RotationDegrees = new Vector3(-UsingPlayer.LookVertical, UsingPlayer.LookHorizontal, 0); Rocket.Momentum = new Vector3(0, 0, RocketTravelSpeed) .Rotated(new Vector3(1, 0, 0), Deg2Rad(Rocket.RotationDegrees.x)) .Rotated(new Vector3(0, 1, 0), Deg2Rad(Rocket.RotationDegrees.y)); Rocket.Name = System.Guid.NewGuid().ToString(); World.EntitiesRoot.AddChild(Rocket); Net.SteelRpc(Self, nameof(RemoteFire), Rocket.Translation, Rocket.RotationDegrees, Rocket.Momentum, Rocket.GetName()); UsingPlayer.SfxManager.FpRocketFire(); }
public static void Fire(Items.Instance Item, Player UsingPlayer) { var Rocket = (JumperRocket)JumperRocketScene.Instance(); Rocket.IsLocal = true; Rocket.FiringPlayer = UsingPlayer; Rocket.Translation = UsingPlayer.ProjectileEmitter.GlobalTransform.origin; Rocket.RotationDegrees = new Vector3(-UsingPlayer.IntendedLookVertical, UsingPlayer.LookHorizontal, 0); Rocket.Momentum = new Vector3(0, 0, RocketTravelSpeed) .Rotated(new Vector3(1, 0, 0), Deg2Rad(Rocket.RotationDegrees.x)) .Rotated(new Vector3(0, 1, 0), Deg2Rad(Rocket.RotationDegrees.y)); Rocket.Name = System.Guid.NewGuid().ToString(); World.EntitiesRoot.AddChild(Rocket); Net.SteelRpc(Self, nameof(RemoteFire), Rocket.Translation, Rocket.RotationDegrees, Rocket.Momentum, Rocket.Name); UsingPlayer.SfxManager.FpRocketFire(); UsingPlayer.SetCooldown(0, FireCooldown, true); }
private void ReceiveInventory(string Identifier, Items.ID[] Ids, int[] Counts) { Node Entity = World.EntitiesRoot.GetNodeOrNull(Identifier); if (Entity is null) { RpcId(Net.ServerId, nameof(PleaseSendMeCreate), Identifier); return; } Assert.ActualAssert(Entity is IEntity); if (Entity is IHasInventory HasInventory) { Assert.ActualAssert(Ids.Length == Counts.Length); Assert.ActualAssert(HasInventory.Inventory.Contents.Length == Ids.Length); int Index = 0; while (Index < Ids.Length) { if (Ids[Index] == Items.ID.NONE) { HasInventory.Inventory.Contents[Index] = null; } else { var Item = new Items.Instance(Ids[Index]) { Count = Counts[Index] }; HasInventory.Inventory.Contents[Index] = Item; } Index += 1; } } else { Console.ThrowLog("Received an inventory for an entity without an inventory"); } }
public override void DropData(Vector2 Pos, object Data) { if (Data is int FromSlot && Source != null) { Items.Instance Moving = Source.Source.Inventory[FromSlot]; int RetrieveCount = CalcRetrieveCount(Moving.Count); Vector3 StartPos = Game.PossessedPlayer.Translation + Game.PossessedPlayer.Cam.Translation; for (int Index = 0; Index < RetrieveCount; Index++) { World.Self.DropItem(Moving.Id, StartPos, Game.PossessedPlayer.CalcThrowVelocity()); } bool EmptyMoving = RetrieveCount == Moving.Count; //If we have thrown all, empty the the source slot if (Net.Work.IsNetworkServer()) { if (EmptyMoving) { Source.Source.NetEmptyInventorySlot(FromSlot); } else { Source.Source.NetUpdateInventorySlot(FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } else { if (EmptyMoving) { Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetEmptyInventorySlot), FromSlot); } else { Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } } }
public Option <int[]> ItemGive(Items.Instance ToGive) { Option <int[]> Slots = Inventory.Give(ToGive); Slots.MatchSome( (ActualSlots) => { if (Possessed) { HUDInstance.HotbarUpdate(); } else { foreach (int Slot in ActualSlots) { RpcId(Id, nameof(NetUpdateInventorySlot), Slot, ToGive.Id, Inventory[Slot].Count); } } } ); return(Slots); }
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 Option <int[]> ItemGive(Items.Instance ToGive) { Assert.ActualAssert(Net.Work.IsNetworkServer()); return(Inventory.Give(ToGive)); }
public override void _PhysicsProcess(float Delta) { GhostMesh.Translation = OldPositions[0]; GhostMesh.RotationDegrees = OldRotations[0]; GhostMesh.Visible = OldVisible[0]; GhostMesh.Mesh = Items.Meshes[OldType[0]]; CurrentMeshType = OldType[0]; Player Plr = Game.PossessedPlayer; OldVisible.RemoveAt(0); OldVisible.Add(false); if (Plr.Inventory[Plr.InventorySlot] != null) { var BuildRayCast = Plr.GetNode <RayCast>("SteelCamera/RayCast"); if (BuildRayCast.IsColliding()) { if (BuildRayCast.GetCollider() is Tile Base) { Vector3?GhostPosition = Items.TryCalculateBuildPosition(CurrentMeshType, Base, Plr.RotationDegrees.y, Plr.BuildRotation, BuildRayCast.GetCollisionPoint()); if (GhostPosition != null) { Vector3 GhostRotation = Items.CalculateBuildRotation(CurrentMeshType, Base, Plr.RotationDegrees.y, Plr.BuildRotation, BuildRayCast.GetCollisionPoint()); Translation = (Vector3)GhostPosition; RotationDegrees = GhostRotation; OldVisible[1] = true; } } } } if (OldVisible[1] == false) { OldVisible[0] = false; GhostMesh.Visible = false; } OldCanBuild.RemoveAt(0); if (GetOverlappingBodies().Count > 0) { bool _CanBuild = true; foreach (Node Body in GetOverlappingBodies()) { Items.Instance SelectedItem = Game.PossessedPlayer.Inventory[Game.PossessedPlayer.InventorySlot]; if (SelectedItem == null) { continue; } Items.ID[] DisallowedCollisions = Items.IdInfos[SelectedItem.Id].DisallowedCollisions; if (DisallowedCollisions != null && Body is Tile && DisallowedCollisions.Contains(((Tile)Body).Type)) { GhostMesh.MaterialOverride = RedMat; _CanBuild = false; } } OldCanBuild.Add(_CanBuild); if (_CanBuild) { GhostMesh.MaterialOverride = GreenMat; } } else { GhostMesh.MaterialOverride = GreenMat; OldCanBuild.Add(true); } CanBuild = OldCanBuild[0]; OldPositions.RemoveAt(0); OldPositions.Add(Translation); OldRotations.RemoveAt(0); OldRotations.Add(RotationDegrees); Items.Instance Item = Game.PossessedPlayer.Inventory[Game.PossessedPlayer.InventorySlot]; if (Item != null && Item.Id != CurrentMeshType) //null means no item in slot { OldType.RemoveAt(0); OldType.Add(Item.Id); } }
public override void DropData(Vector2 Pos, object Data) { if (Data is int FromSlot && ParentMenu.Source != null) { if (Source == ParentMenu.Source.Source && Slot == FromSlot) { return; //Same source and slot, we dropped on ourself } Items.Instance Moving = ParentMenu.Source.Source.Inventory[FromSlot]; Assert.ActualAssert(Moving != null); if (Moving == null) { return; //Makes Roslyn happy } Items.Instance Original = Source.Inventory[Slot]; int RetrieveCount = ParentMenu.CalcRetrieveCount(Moving.Count); bool EmptyMoving = RetrieveCount == Moving.Count; //If we are moving all, empty the the source slot if (Original == null) //Replace (no item at target) { if (Net.Work.IsNetworkServer()) { Source.NetUpdateInventorySlot(Slot, Moving.Id, RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.NetEmptyInventorySlot(FromSlot); } else { ParentMenu.Source.Source.NetUpdateInventorySlot(FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } else { Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), Slot, Moving.Id, RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetEmptyInventorySlot), FromSlot); } else { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } } else { if (Moving.Id == Original.Id) //Combine at target { if (Net.Work.IsNetworkServer()) { Source.NetUpdateInventorySlot(Slot, Original.Id, Original.Count + RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.NetEmptyInventorySlot(FromSlot); } else { ParentMenu.Source.Source.NetUpdateInventorySlot(FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } else { Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), Slot, Original.Id, Original.Count + RetrieveCount); if (EmptyMoving) { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetEmptyInventorySlot), FromSlot); } else { ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Moving.Id, Moving.Count - RetrieveCount); } } } else if (RetrieveCount == Moving.Count) //Swap, only if we are moving all from the source slot { if (Net.Work.IsNetworkServer()) { Source.NetUpdateInventorySlot(Slot, Moving.Id, Moving.Count); ParentMenu.Source.Source.NetUpdateInventorySlot(FromSlot, Original.Id, Original.Count); } else { Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), Slot, Moving.Id, Moving.Count); ParentMenu.Source.Source.RpcId(Net.ServerId, nameof(IHasInventory.NetUpdateInventorySlot), FromSlot, Original.Id, Original.Count); } } } } }