Esempio n. 1
0
        public static void do_mix(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "What would you like to mix together?"))
            {
                return;
            }

            var secondArg = argument.SecondWord();

            if (CheckFunctions.CheckIfEmptyString(ch, secondArg, "What would you like to mix together?"))
            {
                return;
            }

            var firstObj = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, firstObj, "You aren't carrying that."))
            {
                return;
            }

            var secondObj = ch.GetCarriedObject(secondArg);

            if (CheckFunctions.CheckIfNullObject(ch, secondObj, "You aren't carrying that."))
            {
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch,
                                           firstObj.ItemType != ItemTypes.DrinkContainer && firstObj.ItemType != ItemTypes.DrinkMixture &&
                                           secondObj.ItemType != ItemTypes.DrinkContainer && secondObj.ItemType != ItemTypes.DrinkMixture,
                                           "You can't mix that!"))
            {
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch, firstObj.Values.Quantity <= 0 || secondObj.Values.Quantity <= 0,
                                           "It's empty."))
            {
                return;
            }

            var success = CheckMixture(firstObj, secondObj);

            if (CheckFunctions.CheckIfTrue(ch, !success, "Those two don't mix well together."))
            {
                return;
            }

            ch.SendTo("&cYou mix them together.&g");
        }
Esempio n. 2
0
        public static void do_empty(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Empty what?"))
            {
                return;
            }
            if (handler.FindObject_CheckMentalState(ch))
            {
                return;
            }

            var obj = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, obj, "You aren't carrying that."))
            {
                return;
            }

            if (obj.Count > 1)
            {
                obj.Split();
            }

            var secondArg = argument.SecondWord();

            if (secondArg.EqualsIgnoreCase("into"))
            {
                secondArg = argument.ThirdWord();
            }

            switch (obj.ItemType)
            {
            case ItemTypes.Pipe:
                EmptyPipe(ch, obj);
                break;

            case ItemTypes.DrinkContainer:
                EmptyDrinkContainer(ch, obj);
                break;

            case ItemTypes.Quiver:
            case ItemTypes.Container:
                EmptyContainerOrQuiver(ch, obj);
                break;

            case ItemTypes.KeyRing:
                EmptyKeyRing(ch, obj, secondArg);
                break;

            default:
                comm.act(ATTypes.AT_ACTION, "You shake $p in an attempt to empty it...", ch, obj, null, ToTypes.Character);
                comm.act(ATTypes.AT_ACTION, "$n begins to shake $p in an attempt to empty it...", ch, obj, null, ToTypes.Room);
                break;
            }
        }
Esempio n. 3
0
        private static object TargetObjectInInventory(string arg, CharacterInstance ch, bool silence)
        {
            if (CheckFunctions.CheckIfEmptyString(ch, arg, !silence ? "What should the spell be cast upon?" : ""))
            {
                return(null);
            }

            var obj = ch.GetCarriedObject(arg);

            return(CheckFunctions.CheckIfNullObject(ch, obj, !silence ? "You are not carrying that." : "") ? null : obj);
        }
Esempio n. 4
0
        private static void DropObject(CharacterInstance ch, string firstArg)
        {
            var obj = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, obj, "You do not have that item."))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, !ch.CanDrop(obj), "You can't let go of it."))
            {
                return;
            }

            obj.Split();
            comm.act(ATTypes.AT_ACTION, "$n drops $p.", ch, obj, null, ToTypes.Room);
            comm.act(ATTypes.AT_ACTION, "You drop $p.", ch, obj, null, ToTypes.Character);

            obj.RemoveFrom();
            obj = ch.CurrentRoom.AddTo(obj);
            MudProgHandler.ExecuteObjectProg(MudProgTypes.Drop, ch, obj);

            if (ch.CharDied() || handler.obj_extracted(obj))
            {
                return;
            }

            if (ch.CurrentRoom.Flags.IsSet(RoomFlags.ClanStoreroom))
            {
                foreach (var clan in RepositoryManager.Instance.CLANS.Values)
                {
                    if (clan.StoreRoom == ch.CurrentRoom.ID)
                    {
                        act_obj.save_clan_storeroom(ch, clan);
                    }
                }
            }

            if (GameManager.Instance.SystemData.SaveFlags.IsSet(AutoSaveFlags.Drop))
            {
                save.save_char_obj(ch);
            }
        }
Esempio n. 5
0
        public static ObjectInstance FindObject(CharacterInstance ch, string argument, bool carryonly)
        {
            var tuple = argument.FirstArgument();
            var arg1  = tuple.Item1;

            tuple = tuple.Item2.FirstArgument();
            var arg2      = tuple.Item1;
            var remainder = tuple.Item2;

            if (arg2.EqualsIgnoreCase("from") && !string.IsNullOrEmpty(remainder))
            {
                tuple     = remainder.FirstArgument();
                arg2      = tuple.Item1;
                remainder = tuple.Item2;
            }

            ObjectInstance obj;

            if (string.IsNullOrEmpty(arg2))
            {
                obj = carryonly ? ch.GetCarriedObject(arg1) : ch.GetObjectOnMeOrInRoom(arg1);
                if (CheckFunctions.CheckIfTrue(ch, obj == null && carryonly, "You do not have that item."))
                {
                    return(null);
                }

                if (obj == null)
                {
                    comm.act(ATTypes.AT_PLAIN, "I see no $T here.", ch, null, arg1, ToTypes.Character);
                    return(null);
                }

                return(obj);
            }

            ObjectInstance container = null;

            if (CheckFunctions.CheckIfTrue(ch,
                                           carryonly && (container = ch.GetCarriedObject(arg2)) == null &&
                                           (container = ch.GetWornObject(arg2)) == null, "You do not have that item."))
            {
                return(null);
            }

            if (!carryonly && (container = ch.GetObjectOnMeOrInRoom(arg2)) == null)
            {
                comm.act(ATTypes.AT_PLAIN, "I see no $T here.", ch, null, arg2, ToTypes.Character);
                return(null);
            }

            if (!container.ExtraFlags.IsSet((int)ItemExtraFlags.Covering) && container.Value.ToList()[1].IsSet(ContainerFlags.Closed))
            {
                comm.act(ATTypes.AT_PLAIN, "The $d is closed.", ch, null, container.Name, ToTypes.Character);
                return(null);
            }

            obj = ch.GetObjectInList(container.Contents, arg1);
            if (obj == null)
            {
                comm.act(ATTypes.AT_PLAIN, container.ExtraFlags.IsSet((int)ItemExtraFlags.Covering)
                    ? "I see nothing like that beneath $p."
                    : "I see nothing like that in $p.", ch, container, null, ToTypes.Character);
            }

            return(obj);
        }
Esempio n. 6
0
        public static bool CheckAbility(CharacterInstance ch, string command, string argument,
                                        IRepositoryManager databaseManager = null)
        {
            var sn = ch.GetIDOfSkillCharacterKnows(command);

            if (sn == -1)
            {
                return(false);
            }

            var skill = (databaseManager ?? RepositoryManager.Instance).GetEntity <SkillData>(sn);

            if (skill.SkillFunction == null || skill.SpellFunction == null ||
                ch.CanUseSkill(0, sn))
            {
                return(false);
            }

            if (!interp.check_pos(ch, skill.MinimumPosition))
            {
                return(true);
            }

            if (CheckFunctions.CheckIf(ch, HelperFunctions.IsCharmedOrPossessed,
                                       "For some reason, you seem unable to perform that...",
                                       new List <object> {
                ch
            }))
            {
                comm.act(ATTypes.AT_GREY, "$n wanders around aimlessly.", ch, null, null, ToTypes.Room);
                return(true);
            }

            //// Check if mana is required
            int mana = 0, blood = 0;

            if (skill.MinimumMana > 0)
            {
                mana = ch.IsNpc() ? 0 : skill.MinimumMana
                       .GetHighestOfTwoNumbers(100 / (2 + ch.Level - skill.RaceLevel.ToList()[(int)ch.CurrentRace]));

                if (CheckFunctions.CheckIf(ch, HelperFunctions.HasSufficientBloodPower,
                                           "You don't have enough blood power.",
                                           new List <object> {
                    ch, blood
                }))
                {
                    return(true);
                }

                if (CheckFunctions.CheckIf(ch, HelperFunctions.HasSufficientMana, "You don't have enough mana.",
                                           new List <object> {
                    ch, mana
                }))
                {
                    return(true);
                }
            }

            DateTime start, end;

            //// Is this a real d-fun or just a spell?
            if (skill.SkillFunction == null)
            {
                CharacterInstance victim = null;
                ObjectInstance    obj    = null;
                var    targetName        = string.Empty;
                object vo;

                switch (skill.Target)
                {
                default:
                    LogManager.Instance.Bug("Bad target to Skill {0}", sn);
                    ch.SendTo("Something went wrong...");
                    return(true);

                case TargetTypes.Ignore:
                    vo         = null;
                    victim     = ch.GetMyTarget();
                    targetName = argument.IsNullOrEmpty() && victim != null ? victim.Name : argument;
                    break;

                case TargetTypes.OffensiveCharacter:
                    victim = ch.GetMyTarget();

                    if (argument.IsNullOrEmpty() && victim == null)
                    {
                        ch.Printf("Confusion overcomes you as your '%s' has no target.\r\n", skill.Name);
                        return(true);
                    }

                    victim = ch.GetCharacterInRoom(argument);
                    if (CheckFunctions.CheckIfTrue(ch, !argument.IsNullOrEmpty() && victim == null,
                                                   "They aren't here."))
                    {
                        return(true);
                    }

                    if (fight.is_safe(ch, victim, true))
                    {
                        return(true);
                    }

                    if (CheckFunctions.CheckIfTrue(ch, ch == victim && skill.Flags.IsSet(SkillFlags.NoSelf),
                                                   "You can't target yourself!"))
                    {
                        return(true);
                    }

                    if (!ch.IsNpc())
                    {
                        if (!victim.IsNpc())
                        {
                            if (CheckFunctions.CheckIfNotNullObject(ch, ch.GetTimer(TimerTypes.PKilled),
                                                                    "You have been killed in the last five minutes."))
                            {
                                return(true);
                            }
                            if (CheckFunctions.CheckIfNotNullObject(ch, victim.GetTimer(TimerTypes.PKilled),
                                                                    "This player has been killed in the last five minutes."))
                            {
                                return(true);
                            }
                            if (CheckFunctions.CheckIfEquivalent(ch, ch, victim,
                                                                 "You really shouldn't do this to another player..."))
                            {
                                return(true);
                            }
                        }

                        if (CheckFunctions.CheckIfTrue(ch,
                                                       ch.IsAffected(AffectedByTypes.Charm) && ch.Master == victim,
                                                       "You can't do that on your own follower."))
                        {
                            return(true);
                        }
                    }

                    if (CheckFunctions.CheckIfTrue(ch, fight.check_illegal_pk(ch, victim),
                                                   "You can't do that to another player!"))
                    {
                        return(true);
                    }

                    vo = victim;
                    break;

                case TargetTypes.DefensiveCharacter:
                    victim = ch.GetCharacterInRoom(argument);
                    if (CheckFunctions.CheckIfTrue(ch, !argument.IsNullOrEmpty() && victim == null,
                                                   "They aren't here."))
                    {
                        return(true);
                    }

                    if (CheckFunctions.CheckIfTrue(ch, ch == victim && skill.Flags.IsSet(SkillFlags.NoSelf),
                                                   "You can't target yourself!"))
                    {
                        return(true);
                    }

                    vo = victim;
                    break;

                case TargetTypes.Self:
                    victim = ch;
                    vo     = ch;
                    break;

                case TargetTypes.InventoryObject:
                    obj = ch.GetCarriedObject(argument);
                    if (CheckFunctions.CheckIfNullObject(ch, obj, "You can't find that."))
                    {
                        return(true);
                    }

                    vo = obj;
                    break;
                }

                Macros.WAIT_STATE(ch, skill.Rounds);

                //// Check for failure
                if (SmaugRandom.D100() + skill.difficulty * 5 > (ch.IsNpc() ? 75 : Macros.LEARNED(ch, (int)skill.ID)))
                {
                    ch.FailedCast(skill, victim, obj);
                    skill.LearnFromFailure((PlayerInstance)ch);
                    if (mana > 0)
                    {
                        if (ch.IsVampire())
                        {
                            ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -blood / 2);
                        }
                        else
                        {
                            ch.CurrentMana -= mana / 2;
                        }
                    }
                    return(true);
                }
                if (mana > 0)
                {
                    if (ch.IsVampire())
                    {
                        ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -blood);
                    }
                    else
                    {
                        ch.CurrentMana -= mana;
                    }
                }

                start = DateTime.Now;
                var retcode = skill.SpellFunction.Value.Invoke((int)skill.ID, ch.Level, ch, vo);
                end = DateTime.Now;
                skill.UseHistory.Use(ch, end.Subtract(start));

                if (retcode == ReturnTypes.CharacterDied || retcode == ReturnTypes.Error || ch.CharDied())
                {
                    return(true);
                }

                if (retcode == ReturnTypes.SpellFailed)
                {
                    skill.LearnFromFailure((PlayerInstance)ch);
                    retcode = ReturnTypes.None;
                }
                else
                {
                    skill.AbilityLearnFromSuccess((PlayerInstance)ch);
                }

                if (skill.Target == TargetTypes.OffensiveCharacter &&
                    victim != ch &&
                    !victim.CharDied())
                {
                    if (ch.CurrentRoom.Persons.Any(vch => victim == vch && victim.CurrentFighting == null && victim.Master != ch))
                    {
                        retcode = fight.multi_hit(victim, ch, Program.TYPE_UNDEFINED);
                    }
                }

                return(true);
            }

            if (mana > 0)
            {
                if (ch.IsVampire())
                {
                    ((PlayerInstance)ch).GainCondition(ConditionTypes.Bloodthirsty, -blood);
                }
                else
                {
                    ch.CurrentMana -= mana;
                }
            }

            ch.LastCommand = skill.SkillFunction;
            start          = DateTime.Now;
            skill.SkillFunction.Value.Invoke(ch, argument);
            end = DateTime.Now;
            skill.UseHistory.Use(ch, end.Subtract(start));

            // TODO: Tail chain?

            return(true);
        }
Esempio n. 7
0
        public static void do_apply(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Apply what?"))
            {
                return;
            }

            var secondArg = argument.SecondWord();

            if (CheckFunctions.CheckIfNotNullObject(ch, ch.CurrentFighting, "You're too busy fighting..."))
            {
                return;
            }
            if (handler.FindObject_CheckMentalState(ch))
            {
                return;
            }

            var salve = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, salve, "You do not have that."))
            {
                return;
            }

            CharacterInstance victim;
            ObjectInstance    obj = null;

            if (string.IsNullOrEmpty(secondArg))
            {
                victim = ch;
            }
            else
            {
                victim = ch.GetCharacterInRoom(secondArg);
                obj    = ch.GetObjectOnMeOrInRoom(secondArg);

                if (CheckFunctions.CheckIfTrue(ch, victim == null && obj == null, "Apply it to what or whom?"))
                {
                    return;
                }
            }

            if (CheckFunctions.CheckIfNotNullObject(ch, obj, "You can't do that... yet."))
            {
                return;
            }
            if (CheckFunctions.CheckIfNotNullObject(ch, victim.CurrentFighting,
                                                    "Wouldn't work very well while they're fighting..."))
            {
                return;
            }

            if (salve.ItemType != ItemTypes.Salve)
            {
                ApplyNonSalve(salve, ch, victim);
                return;
            }

            salve.Split();
            salve.Values.Charges -= 1;

            if (!MudProgHandler.ExecuteObjectProg(MudProgTypes.Use, ch, salve, null, null))
            {
                UseSalve(salve, ch, victim);
            }

            Macros.WAIT_STATE(ch, salve.Values.Delay);
            var retcode = ch.ObjectCastSpell((int)salve.Values.Skill1ID, (int)salve.Values.SpellLevel, victim);

            if (retcode == ReturnTypes.None)
            {
                retcode = ch.ObjectCastSpell((int)salve.Values.Skill2ID, (int)salve.Values.SpellLevel, victim);
            }
            if (retcode == ReturnTypes.CharacterDied || retcode == ReturnTypes.BothDied)
            {
                throw new CharacterDiedException("Salve {0}, Actor {1}, Victim {2}", salve.ID, ch.ID, victim.ID);
            }

            if (!handler.obj_extracted(salve) && salve.Values.Charges <= 0)
            {
                salve.Extract();
            }
        }
Esempio n. 8
0
        private static void PlaceItemForAuction(CharacterInstance ch, string argument, IAuctionManager auctionManager)
        {
            var firstArg = argument.FirstWord();
            var obj      = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, obj, "You aren't carrying that."))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, obj.Timer > 0, "You can't auction objects that are decaying."))
            {
                return;
            }
            if (CheckFunctions.CheckIfSet(ch, obj.ExtraFlags, (int)ItemExtraFlags.Personal,
                                          "Personal items may not be auctioned."))
            {
                return;
            }

            if (CheckFunctions.CheckIfTrue(ch,
                                           (auctionManager ?? AuctionManager.Instance).Repository.History.Any(x => x.ItemForSale == obj.ObjectIndex.ID),
                                           "Such an item has been auctioned recently, try again later."))
            {
                return;
            }

            var secondArg = argument.SecondWord();

            if (CheckFunctions.CheckIfEmptyString(ch, secondArg, "Auction it for what?"))
            {
                return;
            }
            if (CheckFunctions.CheckIfTrue(ch, !secondArg.IsNumber(),
                                           "You must input a number at which to start the auction."))
            {
                return;
            }

            var startingBid = secondArg.ToInt32();

            if (CheckFunctions.CheckIfTrue(ch, startingBid <= 0, "You can't auction something for nothing!"))
            {
                return;
            }

            if ((auctionManager ?? AuctionManager.Instance).Auction != null)
            {
                comm.act(ATTypes.AT_TELL, "Try again later - $p is being auctioned right now!", ch,
                         (auctionManager ?? AuctionManager.Instance).Auction.ItemForSale, null, ToTypes.Character);
                if (!ch.IsImmortal())
                {
                    Macros.WAIT_STATE(ch, GameConstants.GetSystemValue <int>("PulseViolence"));
                }
                return;
            }

            if (!obj.HasAttribute <AuctionableAttribute>())
            {
                comm.act(ATTypes.AT_TELL, "You cannot auction $Ts.", ch, null, obj.GetItemTypeName(), ToTypes.Character);
                return;
            }

            obj.Split();
            obj.RemoveFrom();
            if (GameManager.Instance.SystemData.SaveFlags.IsSet(AutoSaveFlags.Auction))
            {
                save.save_char_obj(ch);
            }

            (auctionManager ?? AuctionManager.Instance).StartAuction(ch, obj, startingBid);
            ChatManager.talk_auction($"A new item is being auctioned: {obj.ShortDescription} at {startingBid} coin.");
        }
Esempio n. 9
0
 public static ObjectInstance GetObjectOnMeOrInRoom(this CharacterInstance ch, string argument)
 {
     return(GetObjectInReversedList(ch.CurrentRoom.Contents, argument)
            ?? ch.GetCarriedObject(argument)
            ?? GetWornObject(ch, argument));
 }
Esempio n. 10
0
        public static void do_fill(CharacterInstance ch, string argument)
        {
            var firstArg = argument.FirstWord();

            if (CheckFunctions.CheckIfEmptyString(ch, firstArg, "Fill what?"))
            {
                return;
            }
            if (handler.FindObject_CheckMentalState(ch))
            {
                return;
            }

            var obj = ch.GetCarriedObject(firstArg);

            if (CheckFunctions.CheckIfNullObject(ch, obj, "You do not have that item."))
            {
                return;
            }

            if (obj.ItemType == ItemTypes.Container)
            {
                if (obj.Values.Flags.IsSet(ContainerFlags.Closed))
                {
                    comm.act(ATTypes.AT_PLAIN, "The $d is closed.", ch, null, obj.Name, ToTypes.Character);
                    return;
                }
                if (CheckFunctions.CheckIfTrue(ch, obj.GetRealWeight() / obj.Count >= obj.Values.Capacity,
                                               "It's already full as it can be."))
                {
                    return;
                }
            }
            else
            {
                if (CheckFunctions.CheckIfTrue(ch,
                                               (GetMaximumCondition() < 1) || (obj.Values.Quantity >= obj.Values.Capacity),
                                               "It's already full as it can be."))
                {
                    return;
                }
            }

            if (CheckFunctions.CheckIfTrue(ch,
                                           obj.ItemType == ItemTypes.Pipe && obj.Values.Flags.IsSet(PipeFlags.FullOfAsh),
                                           "It's full of ashes, and needs to be emptied first."))
            {
                return;
            }

            var sourceItemTypes = ChooseSourceItemTypes(ch, obj);

            var secondArg = argument.SecondWord();

            if (secondArg.EqualsIgnoreCase("from") ||
                secondArg.EqualsIgnoreCase("with"))
            {
                secondArg = argument.ThirdWord();
            }

            ObjectInstance source = null;
            var            all    = false;

            if (!secondArg.IsNullOrEmpty())
            {
                handler.separate_obj(obj);

                if (obj.ItemType == ItemTypes.Container &&
                    (secondArg.EqualsIgnoreCase("all") || secondArg.StartsWithIgnoreCase("all.")))
                {
                    all = true;
                }
                else if (obj.ItemType == ItemTypes.Pipe)
                {
                    source = ch.GetCarriedObject(secondArg);
                    if (CheckFunctions.CheckIfNullObject(ch, source, "You don't have that item."))
                    {
                        return;
                    }
                    if (sourceItemTypes.All(x => x != source.ItemType))
                    {
                        comm.act(ATTypes.AT_PLAIN, "You cannot fill $p with $P!", ch, obj, source, ToTypes.Character);
                        return;
                    }
                }
                else
                {
                    source = ch.GetObjectOnMeOrInRoom(secondArg);
                    if (CheckFunctions.CheckIfNullObject(ch, source, "You cannot find that item."))
                    {
                        return;
                    }
                }
            }
            else
            {
                source = null;
            }

            if (CheckFunctions.CheckIfTrue(ch, source == null && obj.ItemType == ItemTypes.Pipe,
                                           "Fill it with what?"))
            {
                return;
            }

            bool found = false;

            if (source != null)
            {
                foreach (var sourceObj in ch.CurrentRoom.Contents)
                {
                    source = sourceObj;
                    if (obj.ItemType == ItemTypes.Container)
                    {
                        if (ch.CanWear(source, ItemWearFlags.Take) || source.IsObjStat(ItemExtraFlags.Buried) ||
                            (source.IsObjStat(ItemExtraFlags.Prototype) && ch.CanTakePrototype()) ||
                            ch.CarryWeight + source.GetWeight() > ch.CanCarryMaxWeight() ||
                            (source.GetRealWeight() + obj.GetRealWeight() / obj.Count) > obj.Value[0])
                        {
                            continue;
                        }

                        if (all && secondArg[3] == '.' && secondArg.Substring(4).IsAnyEqual(source.Name))
                        {
                            continue;
                        }

                        source.InRoom.Contents.Remove(source);
                        if (source.ItemType == ItemTypes.Money)
                        {
                            ch.CurrentCoin += source.Value[0];
                            source.Extract();
                        }
                        else
                        {
                            source.AddTo(obj);
                        }
                        found = true;
                    }
                    else if (sourceItemTypes.Any(x => x == source.ItemType))
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    if (SourceItemTypeNotFoundTable.TryGetValue(sourceItemTypes.First(), out var message))
                    {
                        ch.SendTo(message);
                    }
                    else
                    {
                        ch.SendTo("There is nothing appropriate here!");
                    }
                }

                if (obj.ItemType == ItemTypes.Container)
                {
                    comm.act(ATTypes.AT_ACTION, "You fill $p.", ch, obj, null, ToTypes.Character);
                    comm.act(ATTypes.AT_ACTION, "$n fills $p.", ch, obj, null, ToTypes.Room);
                    return;
                }
            }

            if (obj.ItemType == ItemTypes.Container)
            {
                if (source == obj)
                {
                    ch.SendTo("You can't fill something with itself!");
                    return;
                }

                switch (source.ItemType)
                {
                case ItemTypes.Money:
                    ch.SendTo("You can't do that... yet.");
                    break;

                case ItemTypes.PlayerCorpse:
                    if (ch.IsNpc())
                    {
                        ch.SendTo("You can't do that.");
                        return;
                    }

                    if (source.IsObjStat(ItemExtraFlags.ClanCorpse) && !ch.IsImmortal())
                    {
                        ch.SendTo("Your hands fumble.  Maybe you better loot a different way.");
                        return;
                    }

                    if (!source.IsObjStat(ItemExtraFlags.ClanCorpse) || !((PlayerInstance)ch).PlayerData.Flags.IsSet((int)PCFlags.Deadly))
                    {
                        // TODO liquids.c lines 1734 to 1758
                    }
                    break;

                case ItemTypes.Container:
                    if (source.ItemType == ItemTypes.Container && source.Value[1].IsSet((int)ContainerFlags.Closed))
                    {
                        comm.act(ATTypes.AT_PLAIN, "The $d is closed.", ch, null, source.Name, ToTypes.Character);
                        return;
                    }
                    break;

                case ItemTypes.NpcCorpse:
                    if (!source.Contents.Any())
                    {
                        ch.SendTo("It's empty.");
                        return;
                    }

                    handler.separate_obj(obj);

                    bool wasFound = false;
                    foreach (var contentObj in source.Contents)
                    {
                        if (!ch.CanWear(contentObj, ItemWearFlags.Take) ||
                            (contentObj.IsObjStat(ItemExtraFlags.Prototype) && !ch.CanTakePrototype()) ||
                            ch.CarryNumber + contentObj.Count > ch.CanCarryN() ||
                            ch.CarryWeight + contentObj.GetWeight() > ch.CanCarryMaxWeight() ||
                            (source.GetRealWeight() + obj.GetRealWeight() / obj.Count) > obj.Value[0])
                        {
                            continue;
                        }

                        contentObj.RemoveFrom(source);
                        contentObj.AddTo(obj);
                        wasFound = true;
                    }

                    if (wasFound)
                    {
                        comm.act(ATTypes.AT_ACTION, "You fill $p from $P.", ch, obj, source, ToTypes.Character);
                        comm.act(ATTypes.AT_ACTION, "$n fills $p from $P.", ch, obj, source, ToTypes.Room);
                    }
                    else
                    {
                        ch.SendTo("There is nothing appropriate in there.");
                    }
                    break;

                default:
                    if (source.InRoom == null ||
                        ch.CanWear(source, ItemWearFlags.Take) ||
                        (obj.IsObjStat(ItemExtraFlags.Prototype) && !ch.CanTakePrototype()) ||
                        ch.CarryWeight + source.GetWeight() > ch.CanCarryMaxWeight() ||
                        (source.GetRealWeight() + obj.GetRealWeight() / obj.Count) > obj.Value[0])
                    {
                        ch.SendTo("You can't do that.");
                        return;
                    }

                    handler.separate_obj(obj);
                    comm.act(ATTypes.AT_ACTION, "You take $P and put it inside $p.", ch, obj, source, ToTypes.Character);
                    comm.act(ATTypes.AT_ACTION, "$n takes $P and puts it inside $p.", ch, obj, source, ToTypes.Room);
                    source.InRoom.Contents.Remove(source);
                    source.AddTo(obj);
                    break;
                }
                return;
            }

            if (source.Value[1] < 1)
            {
                ch.SendTo("There's none left!");
                return;
            }

            if (source.Count > 1 && source.ItemType != ItemTypes.Fountain)
            {
                handler.separate_obj(source);
            }
            handler.separate_obj(obj);

            var diff = GetMaximumCondition();

            switch (obj.ItemType)
            {
            case ItemTypes.Fountain:
                if (obj.Value[1] != 0 && obj.Value[2] != 0)
                {
                    ch.SendTo("There is already another liquid in it.");
                    return;
                }

                obj.Value[2] = 0;
                obj.Value[1] = obj.Value[0];
                comm.act(ATTypes.AT_ACTION, "You fill $p from $P.", ch, obj, source, ToTypes.Character);
                comm.act(ATTypes.AT_ACTION, "$n fills $p from $P.", ch, obj, source, ToTypes.Room);
                return;

            case ItemTypes.Blood:
                if (obj.Value[1] != 0 && obj.Value[2] != 13)
                {
                    ch.SendTo("There is already another liquid in it.");
                    return;
                }

                obj.Value[2] = 13;
                if (source.Value[1] < diff)
                {
                    diff = source.Value[1];
                }

                obj.Value[1] += diff;
                comm.act(ATTypes.AT_ACTION, "You fill $p from $p.", ch, obj, source, ToTypes.Character);
                comm.act(ATTypes.AT_ACTION, "$n fills $p from $P.", ch, obj, source, ToTypes.Room);

                source.Value[1] -= diff;
                if (source.Value[1] < 1)
                {
                    source.Extract();
                    ObjectFactory.CreateBloodstain(ch);
                }
                return;

            case ItemTypes.Herb:
                if (obj.Value[1] != 0 && obj.Value[2] != source.Value[2])
                {
                    ch.SendTo("There is already another type of herb in it.");
                    return;
                }

                obj.Value[2] = source.Value[2];
                if (source.Value[1] < diff)
                {
                    diff = source.Value[1];
                }

                obj.Value[1] += diff;
                comm.act(ATTypes.AT_ACTION, "You fill $p from $p.", ch, obj, source, ToTypes.Character);
                comm.act(ATTypes.AT_ACTION, "$n fills $p from $P.", ch, obj, source, ToTypes.Room);

                source.Value[1] -= diff;
                if (source.Value[1] < 1)
                {
                    source.Extract();
                }
                return;

            case ItemTypes.HerbContainer:
                if (obj.Value[1] != 0 && obj.Value[2] != source.Value[2])
                {
                    ch.SendTo("There is already another type of herb in it.");
                    return;
                }

                obj.Value[2] = source.Value[2];
                if (source.Value[1] < diff)
                {
                    diff = source.Value[1];
                }

                obj.Value[1] += diff;
                comm.act(ATTypes.AT_ACTION, "You fill $p from $p.", ch, obj, source, ToTypes.Character);
                comm.act(ATTypes.AT_ACTION, "$n fills $p from $P.", ch, obj, source, ToTypes.Room);
                return;

            case ItemTypes.DrinkContainer:
                if (obj.Value[1] != 0 && obj.Value[2] != source.Value[2])
                {
                    ch.SendTo("There is already another liquid in it.");
                    return;
                }

                obj.Value[2] = source.Value[2];
                if (source.Value[1] < diff)
                {
                    diff = source.Value[1];
                }

                obj.Value[1]    += diff;
                source.Value[1] -= diff;

                comm.act(ATTypes.AT_ACTION, "You fill $p from $P.", ch, obj, source, ToTypes.Character);
                comm.act(ATTypes.AT_ACTION, "$n fills $p from $P.", ch, obj, source, ToTypes.Room);
                return;

            default:
                // TODO bug
                ch.SendTo("Somethign went wrong...");
                return;
            }
        }