예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        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();
            }
        }