private void MoveBetweenContainers() { IItem extraItem; var updatedItem = Thing as IItem; if (FromContainer == null || ToContainer == null || updatedItem == null || Requestor == null) { return; } // attempt to remove from the source container if (!FromContainer.RemoveContent(updatedItem.Type.TypeId, FromIndex, Count, out extraItem)) { return; } if (extraItem != null) { updatedItem = extraItem; } // successfully removed thing from the source container // attempt to add to the dest container if (ToContainer.AddContent(updatedItem, ToIndex)) { return; } // failed to add to the dest container (whole or partial) // attempt to add again to the source at any index. if (FromContainer.AddContent(updatedItem, 0xFF)) { return; } // and we somehow failed to re-add it to the source container... // throw to the ground. IThing thing = updatedItem; Requestor.Tile.AddThing(ref thing, updatedItem.Count); // notify all spectator players of that tile. Game.Instance.NotifySpectatingPlayers(conn => new TileUpdatedNotification(conn, Requestor.Location, Game.Instance.GetMapTileDescription(conn.PlayerId, Requestor.Location)), Requestor.Location); // and handle collision. if (!Requestor.Tile.HandlesCollision) { return; } foreach (var itemWithCollision in Requestor.Tile.ItemsWithCollision) { var collisionEvents = Game.Instance.EventsCatalog[ItemEventType.Collision].Cast <CollisionItemEvent>(); var candidate = collisionEvents.FirstOrDefault(e => e.ThingIdOfCollision == itemWithCollision.Type.TypeId && e.Setup(itemWithCollision, thing) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } }
private void MoveSlotToContainer() { if (Item == null || Requestor == null) { return; } bool partialRemove; // attempt to remove the item from the inventory var movingItem = Requestor.Inventory?.Remove(FromSlot, Count, out partialRemove); if (movingItem == null) { return; } // successfully removed thing from the source container // attempt to add to the dest container if (ToContainer.AddContent(movingItem, ToIndex)) { return; } // failed to add to the slot, add again to the source slot if (!Requestor.Inventory.Add(movingItem, out movingItem, FromSlot, movingItem.Count)) { // and we somehow failed to re-add it to the source container... // throw to the ground. IThing thing = movingItem; Requestor.Tile.AddThing(ref thing, movingItem.Count); // notify all spectator players of that tile. Game.Instance.NotifySpectatingPlayers(conn => new TileUpdatedNotification(conn, Requestor.Location, Game.Instance.GetMapTileDescription(conn.PlayerId, Requestor.Location)), Requestor.Location); // call any collision events again. if (Requestor.Tile.HandlesCollision) { foreach (var itemWithCollision in Requestor.Tile.ItemsWithCollision) { var collisionEvents = Game.Instance.EventsCatalog[ItemEventType.Collision].Cast <CollisionItemEvent>(); var candidate = collisionEvents.FirstOrDefault( e => e.ThingIdOfCollision == itemWithCollision.Type.TypeId && e.Setup(itemWithCollision, thing) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } } } }
private void PickupToContainer() { var thingAsItem = Thing as IItem; if (FromTile == null || ToContainer == null || Thing == null || thingAsItem == null) { return; } var thingAtTile = FromTile.GetThingAtStackPosition(FromStackPos); if (thingAtTile == null) { return; } var thing = Thing; FromTile.RemoveThing(ref thing, Count); // notify all spectator players of that tile. Game.Instance.NotifySpectatingPlayers(conn => new TileUpdatedNotification(conn, FromTile.Location, Game.Instance.GetMapTileDescription(conn.PlayerId, FromTile.Location)), FromTile.Location); if (thing != Thing) { // item got split cause we removed less than the total amount. // update the thing we're adding to the container. thingAsItem = thing as IItem; } // attempt to add the item to the container. if (thingAsItem == null || ToContainer.AddContent(thingAsItem, ToIndex)) { // and call any separation events. if (FromTile.HandlesSeparation) // TODO: what happens on separation of less than required quantity, etc? { foreach (var itemWithSeparation in FromTile.ItemsWithSeparation) { var separationEvents = Game.Instance.EventsCatalog[ItemEventType.Separation].Cast <SeparationItemEvent>(); var candidate = separationEvents.FirstOrDefault(e => e.ThingIdOfSeparation == itemWithSeparation.Type.TypeId && e.Setup(itemWithSeparation, thing, Requestor as IPlayer) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } } return; } // failed to add to the dest container (whole or partial) // add again to the source tile IThing itemAsThing = thingAsItem; FromTile.AddThing(ref itemAsThing, thingAsItem.Count); // notify all spectator players of that tile. Game.Instance.NotifySpectatingPlayers(conn => new TileUpdatedNotification(conn, FromTile.Location, Game.Instance.GetMapTileDescription(conn.PlayerId, FromTile.Location)), FromTile.Location); // call any collision events again. if (!FromTile.HandlesCollision) { return; } foreach (var itemWithCollision in FromTile.ItemsWithCollision) { var collisionEvents = Game.Instance.EventsCatalog[ItemEventType.Collision].Cast <CollisionItemEvent>(); var candidate = collisionEvents.FirstOrDefault(e => e.ThingIdOfCollision == itemWithCollision.Type.TypeId && e.Setup(itemWithCollision, Thing) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } }