/* Like Handletake, HandleDrop checks for an item's existence, but in this case it has to be in the
         * requesting user's inventory.
         * if item exists, remove it from the user inventory's list of refs and add to the room's Items instead
         */
        void HandleDrop(User sender, string e)
        {
            if (sender.Player.IsDead)
            {
                sender.Connection.SendMessage("You cannot do that while defeated!");
                return;
            }
            int  roomId = CommandUtils.GetCurrentRoomId(sender, Map);
            Item target = sender.Inventory.Items.FirstOrDefault(t => CommandUtils.FuzzyEquals(t.Name, e));

            if (target == null)
            {
                HandleHoldDrop(sender, e);
                return;
            }

            if (!target.Commands.Contains("drop"))
            {
                sender.Connection.SendMessage("You cannot drop that.");
                return;
            }

            XMLReference <Item> item = new XMLReference <Item> {
                Actual = target
            };

            sender.Player.Drop(target);
            sender.Inventory.setCurrentLoweredCapacity(target.Weight);
            sender.Inventory.RemoveFromInventory(target);
            Map.Rooms[roomId].Items.Add(item);
        }
Пример #2
0
        public void AddToContainer(User sender)
        {
            if (CurrentCapacity <= Capacity)
            {
                sender.Connection.SendMessage("You have: ");
                foreach (Item i in sender.Inventory.Items)
                {
                    sender.Connection.SendMessage($"{i.Name} - Weight: {i.Weight}");
                }
                sender.Connection.SendMessage($"The {Name} can hold {Capacity - CurrentCapacity} more units.");

                sender.Connection.SendMessage("What would you like to put in the container?");
                string addItem = sender.Connection.ReadMessage();
                Item   item    = sender.Inventory.Items.Find(t => CommandUtils.FuzzyEquals(t.Name, addItem));

                if (item.Weight + CurrentCapacity > Capacity)
                {
                    sender.Connection.SendMessage($"The {Name} cannot hold that!");
                }
                else
                {
                    sender.Inventory.RemoveFromInventory(item);
                    CurrentCapacity += item.Weight;

                    XMLReference <Item> xmlItem = new XMLReference <Item> {
                        Actual = item
                    };

                    Contents.Add(xmlItem);

                    sender.Connection.SendMessage($"The {item.Name} has been added to the {Name}.");

                    return;
                }
            }
            else
            {
                sender.Connection.SendMessage($"The {Name} is full.");
                return;
            }
        }
        // Attack an enemy
        void HandleAttack(User sender, string e)
        {
            if (sender.Player.IsDead)
            {
                sender.Connection.SendMessage("You cannot do that while defeated!");
                return;
            }
            int currRoom = CommandUtils.GetCurrentRoomId(sender, Map);
            NPC target   = CommandUtils.GetTarget(currRoom, e, Map);

            // Make sure the target is actually attackable
            if (target == null)
            {
                sender.Connection.SendMessage("You cannot attack that.");
                return;
            }
            if (CommandUtils.FuzzyEquals(target.Faction, "ally"))
            {
                sender.Connection.SendMessage("You cannot attack friendly people!");
                return;
            }
            if (CommandUtils.FuzzyEquals(target.Faction, "dead"))
            {
                sender.Connection.SendMessage("You cannot attack dead bodies!");
                return;
            }
            // If these checks pass, then there is an available target to fight
            // Check and see if the target is already engaged : if so, join the target session
            //  RoomSay($"{sender.Name} is attacking the {target.Name}!", sender);
            if (target.Combat == null)
            {
                target.Combat = new Combat(target);
            }
            target.Combat.Combatants.Add(sender);
            sender.Player.Combat = target.Combat;

            // Pre-emptively get the direction to run in in case the user decides to try to run.
            var runDir = Map.Rooms[CommandUtils.GetCurrentRoomId(sender, Map)].Doors.Where(d => !d.Actual.Locked).FirstOrDefault()?.Actual;

            // Combat loop: check turns
            while (target.Combat != null && sender.Player.Combat != null)
            {
                sender.Player.IsBlocking = false;
                sender.Connection.SendMessage(@"a: Attack
d: Defend
h: Heal
r: Run");
                if (sender.Player.Stats.CurrHealth <= 0)
                {
                    break;
                }
                else
                {
                    string action = sender.Connection.ReadMessage();
                    if (CommandUtils.FuzzyEquals(action, "a"))
                    {
                        target.Combat.Attack(sender);
                    }
                    if (CommandUtils.FuzzyEquals(action, "d"))
                    {
                        target.Combat.Defend(sender);
                    }
                    if (CommandUtils.FuzzyEquals(action, "h"))
                    {
                        sender.Connection.SendMessage("Consume what?");
                        var consumables = sender.Inventory.Items.Where(t => t.IsConsumable);
                        foreach (Item item in consumables)
                        {
                            sender.Connection.SendMessage(item.Name);
                        }
                        string choice = sender.Connection.ReadMessage();
                        HandleEat(sender, choice);
                    }
                    if (CommandUtils.FuzzyEquals(action, "r"))
                    {
                        target.Combat.Run(sender, runDir);
                        target.Combat = null;
                        break;
                    }
                }
                if (target.Health <= 0)
                {
                    break;
                }
                target.Combat.EnemyTurn();
            }

            if (sender.Player.Stats.CurrHealth <= 0)
            {
                sender.Player.Combat = null;
                target.Combat        = null;
                sender.Connection.SendMessage("You have been defeated!");
                if (Users.Count > 2)
                {
                    sender.Connection.SendMessage("Would you like to wait for a revive? (y/n)");
                    string action = sender.Connection.ReadMessage();
                    if (CommandUtils.FuzzyEquals(action, "y"))
                    {
                        sender.Player.IsDead = true;
                        return;
                    }
                }
                sender.Connection.SendMessage("As you were the only soul in this place, you have been sent back to the start.");
                foreach (Item items in sender.Inventory.Items.ToList())
                {
                    sender.Inventory.RemoveFromInventory(items);
                    XMLReference <Item> item = new XMLReference <Item> {
                        Actual = items
                    };
                    Map.Rooms[CommandUtils.GetCurrentRoomId(sender, Map)].Items.Add(item);
                }
                sender.Player.Stats.CurrHealth = sender.Player.Stats.MaxHealth;
                sender.CurrRoomId = 0001;
                return;
            }
            // After this loop, the target is dead. Remove them from the npc list and add them to the dead list/faction.
            target.Faction = "dead";

            // Upon death, an npc's inventory gets dropped to the room.

            /* foreach(Item items in target.Inventory.Items.ToList())
             * {
             *  target.Inventory.RemoveFromInventory(items);
             *  XMLReference<Item> item = new XMLReference<Item> { Actual = items };
             *  Map.Rooms[CommandUtils.GetCurrentRoomId(sender, Map)].Items.Add(item);
             * } */

            foreach (var i in Map.Rooms[CommandUtils.GetCurrentRoomId(sender, Map)].NPCs.ToList())
            {
                if (i.Actual.Name == target.Name)
                {
                    Map.Rooms[CommandUtils.GetCurrentRoomId(sender, Map)].NPCs.Remove(i);
                    Map.Rooms[CommandUtils.GetCurrentRoomId(sender, Map)].DeadNPCs.Add(i);
                }
            }

            sender.Connection.SendMessage("Send 'q' to exit combat.");
            sender.Player.Combat = null;
            target.Combat        = null;
        }