private void MoveThing() { if (FromTile == null || ToTile == null) { return; } var thing = Thing; FromTile.RemoveThing(ref thing, Count); ToTile.AddThing(ref thing, thing.Count); if (thing is ICreature) { Game.Instance.NotifySpectatingPlayers( conn => new CreatureMovedNotification( conn, (thing as ICreature).CreatureId, FromLocation, FromStackPos, ToLocation, ToTile.GetStackPosition(Thing), IsTeleport), FromLocation, ToLocation); } else { // TODO: see if we can save network bandwith here: // Game.Instance.NotifySpectatingPlayers( // (conn) => new ItemMovedNotification( // conn, // (IItem)Thing, // FromLocation, // oldStackpos, // ToLocation, // destinationTile.GetStackPosition(Thing), // false // ), // FromLocation, // ToLocation // ); Game.Instance.NotifySpectatingPlayers(conn => new TileUpdatedNotification(conn, FromLocation, Game.Instance.GetMapTileDescription(conn.PlayerId, FromLocation)), FromLocation); Game.Instance.NotifySpectatingPlayers(conn => new TileUpdatedNotification(conn, ToLocation, Game.Instance.GetMapTileDescription(conn.PlayerId, ToLocation)), ToLocation); } if (FromTile.HandlesSeparation) { 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(); } } if (ToTile.HandlesCollision) { foreach (var itemWithCollision in ToTile.ItemsWithCollision) { var collisionEvents = Game.Instance.EventsCatalog[ItemEventType.Collision].Cast <CollisionItemEvent>(); var candidate = collisionEvents.FirstOrDefault(e => e.ThingIdOfCollision == itemWithCollision.Type.TypeId && e.Setup(itemWithCollision, thing, Requestor as IPlayer) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } } }
private void MoveFromGroudToSlot() { var updatedItem = Thing as IItem; if (FromTile == null || Thing == null || updatedItem == null || Requestor == 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); // 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, Requestor) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } } if (thing != Thing) { // item got split cause we removed less than the total amount. // update the thing we're adding to the container. updatedItem = thing as IItem; } if (updatedItem == null) { return; } // attempt to place the intended item at the slot. IItem addedItem; if (!Requestor.Inventory.Add(updatedItem, out addedItem, ToSlot, updatedItem.Count)) { // failed to add to the slot, add again to the source tile FromTile.AddThing(ref thing, 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); // call any collision events again. if (FromTile.HandlesCollision) { 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, updatedItem) && e.CanBeExecuted); // Execute all actions. candidate?.Execute(); } } } else { // added the new item to the slot if (addedItem == null) { return; } // we exchanged or got some leftover item, place back in the source container at any index. IThing remainderThing = addedItem; FromTile.AddThing(ref remainderThing, remainderThing.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, remainderThing) && 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(); } }