示例#1
0
        /// <summary>
        /// Put on a piece of equipment.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Wear(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj;

            if (ch.IsAffected(Affect.AFFECT_HOLD) || ch.IsAffected(Affect.AFFECT_MINOR_PARA))
            {
                ch.SendText("Your body refuses the call to movement.\r\n");
                return;
            }

            if (!ch.IsNPC() && ch.IsAffected( Affect.AFFECT_WRAITHFORM))
            {
                ch.SendText("You try, but your &n&+wghoul&n form resists your attempts.\r\n");
                return;
            }

            if (ch.Fighting || ch.CurrentPosition == Position.fighting)
            {
                ch.SendText("You can't wear stuff while you're fighting!\r\n");
                return;
            }

            if (str.Length == 0)
            {
                ch.SendText("Wear, wield, or hold what?\r\n");
                return;
            }

            if (str[0] == "all")
            {
                foreach (Object iobj in ch.Carrying)
                {
                    if (iobj.WearLocation != ObjTemplate.WearLocation.none || !CharData.CanSeeObj(ch, iobj))
                    {
                        continue;
                    }

                    if (iobj.HasWearFlag(ObjTemplate.WEARABLE_WIELD)
                            && !ch.HasInnate(Race.RACE_WEAPON_WIELD))
                    {
                        continue;
                    }

                    Object.WearObject(ch, iobj, false);
                    if (iobj.Trap != null && iobj.Trap.CheckTrigger( Trap.TriggerType.wear))
                    {
                        ch.SetOffTrap(iobj);
                        if (ch.CurrentPosition == Position.dead)
                        {
                            return;
                        }
                    }
                }
                return;
            }
            if (!(obj = ch.GetObjCarrying(str[0])))
            {
                ch.SendText("You do not have that item.\r\n");
                return;
            }

            if (obj.HasWearFlag(ObjTemplate.WEARABLE_WIELD)
                && !ch.HasInnate(Race.RACE_WEAPON_WIELD))
            {
                ch.SendText("You are not able to wield a weapon.\r\n");
                return;
            }

            Object.WearObject(ch, obj, true);
            if (obj.Trap != null && obj.Trap.CheckTrigger( Trap.TriggerType.wear))
            {
                ch.SetOffTrap(obj);
                if (ch.CurrentPosition == Position.dead)
                {
                    return;
                }
            }

            return;
        }
示例#2
0
        /// <summary>
        /// Steal an object or some coins from a victim.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Steal(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj = null;
            CharData victim;
            bool sleeping = false;
            string arg1 = String.Empty;
            string arg2 = String.Empty;
            string arg = String.Empty;
            int percent;

            if (!ch.HasSkill("steal") && !ch.IsAffected(Affect.AFFECT_CHARM))
            {
                ch.SendText("Who are you trying to kid?  You couldn't steal shoes from a &n&+mbl&+Mo&n&+ma&+Mte&n&+md&n corpse.\r\n");
                return;
            }

            if (ch.Riding != null)
            {
                ch.SendText("You can't do that while mounted.\r\n");
                return;
            }

            if (String.IsNullOrEmpty(arg1) || String.IsNullOrEmpty(arg2))
            {
                ch.SendText("Steal what from whom?\r\n");
                return;
            }

            if ((victim = ch.GetCharRoom(arg2)) == null)
            {
                ch.SendText("They aren't here.\r\n");
                return;
            }

            if (victim == ch)
            {
                ch.SendText("That's pointless.\r\n");
                return;
            }

            if (Combat.IsSafe(ch, victim))
                return;

            if (!ch.IsImmortal())
            {
                ch.WaitState(Skill.SkillList["steal"].Delay);
            }

            // Justice stuff
            Crime.CheckThief(ch, victim);

            if (ch.IsNPC())
            {
                percent = ch.Level * 2;
            }
            else
            {
                percent = ((PC)ch).SkillAptitude["steal"];
            }

            percent += ch.GetCurrLuck() / 20; /* Luck */

            percent -= victim.Level; /* Character level vs victim's */

            if (ch.GetRace() == Race.RACE_HALFLING)
            {
                // Halflings get a racial bonus
                percent += 10;
            }

            if (victim.IsAffected(Affect.AFFECT_CURSE))
                percent += 15;

            if (ch.IsAffected(Affect.AFFECT_CURSE))
                percent -= 15;

            if (!victim.IsAwake())
                percent += 25; /* Sleeping characters are easier */

            if (ch.CheckSneak())
                percent += 10; /* Quiet characters steal better */

            if (!CharData.CanSee(ch, victim))
                percent += 10; /* Unseen characters steal better */

            if (!MUDString.IsPrefixOf(arg1, "coins"))
            {
                percent = (int)(percent * 1.2); /* Cash is fairly easy to steal */
            }
            else
            {
                int number = MUDString.NumberArgument(arg1, ref arg);
                int count = 0;
                foreach (Object iobj in victim.Carrying)
                {
                    if (CharData.CanSeeObj(ch, iobj) && MUDString.NameContainedIn(arg, iobj.Name))
                    {
                        if (++count == number)
                        {
                            obj = iobj;
                            break;
                        }
                    }
                }

                if (!obj)
                {
                    ch.SendText("You can't find it.\r\n");
                    return;
                }

                if (ch.Level < victim.Level)
                {
                    // stealing from higher level is possible, but harder
                    percent -= 5 * (victim.Level - ch.Level);
                }
                else
                {
                    // slight bonus for mobs lower level
                    percent += (ch.Level - victim.Level);
                }
                if (obj.WearLocation == ObjTemplate.WearLocation.none)
                    /* Items worn are harder */
                    percent = (int)(percent * .8);
                else
                    percent = (int)(percent * .4);
            }

            ch.PracticeSkill("steal");

            if (percent > 85)
                percent = 85;

            if (percent < 2)
                percent = 2;
            if (percent < MUDMath.NumberPercent())
            {
                /*
                * Failure.
                */
                //strip sneak
                ch.RemoveAffect(Affect.AFFECT_SNEAK);
                // chance of removing invis
                if (ch.IsAffected(Affect.AFFECT_INVISIBLE) && MUDMath.NumberPercent() > percent)
                {
                    ch.SendText("You really bungled that attempt.\r\n");
                    ch.RemoveAffect(Affect.AFFECT_INVISIBLE);
                }
                else
                {
                    ch.SendText("Oops.\r\n");
                }
                SocketConnection.Act("$n&n tried to steal from $N&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                if (victim.IsAwake())
                {
                    SocketConnection.Act("$n&n tried to steal from you!", ch, null, victim, SocketConnection.MessageTarget.victim);
                }
                else
                {
                    sleeping = true;
                }
                // Thief flag for justice.
                // Added so blind mobs dont hit who ever failed steal from em.
                if (victim.IsNPC())
                {
                    if (!sleeping && !victim.IsBlind())
                    {
                        CommandType.Interpret(victim, "kill " + ch.Name);
                    }
                }
                else
                {
                    if (!victim.IsBlind() && !sleeping && victim.IsAffected(Affect.AFFECT_BERZERK))
                    {
                        victim.SendText("In your &+Rblood rage&n, you lash out in anger!\r\n");
                        CommandType.Interpret(victim, "kill " + ch.Name);
                    }
                }
                /*
                if ( !Macros.IS_SET( ch.actflags, PC.PLAYER_THIEF ) )
                {
                Macros.SET_BIT( ref ch.actflags, PC.PLAYER_THIEF );
                buf = String.Format(  "{0} became a THIEF by stealing from {1}",
                ch._name, victim._name );
                Immtalk.Immtalk( ch, Immtalk.IMMTALK_CRIME, ch.GetTrust(), buf );
                CharData.SavePlayer( ch );
                }
                */
                //    }
                if (sleeping)
                {
                    if (MUDMath.NumberPercent() < victim.GetCurrLuck())
                    {
                        CommandType.Interpret(victim, "wake");
                    }
                }
                return;
            } //end failure

            if (!MUDString.IsPrefixOf(arg1, "coins"))
            {
                int amount = victim.GetGold() * MUDMath.NumberRange(1, 20) / 100;
                int amount2 = victim.GetSilver() * MUDMath.NumberRange(1, 20) / 100;
                int amount3 = victim.GetCopper() * MUDMath.NumberRange(1, 20) / 100;
                int amount4 = victim.GetPlatinum() * MUDMath.NumberRange(1, 20) / 100;

                if ((amount + amount2 + amount3 + amount4) <= 0)
                {
                    ch.SendText("You couldn't get any &n&+wcoins&n.\r\n");
                    return;
                }

                ch.ReceiveGold(amount);
                ch.ReceiveSilver(amount2);
                ch.ReceiveCopper(amount3);
                ch.ReceivePlatinum(amount4);

                victim.SpendGold(amount);
                victim.SpendSilver(amount2);
                victim.SpendCopper(amount3);
                victim.SpendPlatinum(amount4);

                string text = String.Format("Success!  You got {0} &+Wplatinum&n, {1} &+Ygold&n, {2} silver, and {3} &+ycopper&n.\r\n",
                                            amount2, amount3, amount, amount4);
                ch.SendText(text);
                return;
            }

            if (!ch.CanDropObject(obj) || obj.HasFlag(ObjTemplate.ITEM_INVENTORY))
            {
                ch.SendText("You can't pry it away.\r\n");
                return;
            }

            if (ch.CarryNumber + 1 > Limits.MAX_CARRY)
            {
                ch.SendText("You have your hands full.\r\n");
                return;
            }

            if (ch.CarryWeight + obj.GetWeight() > ch.MaxCarryWeight())
            {
                ch.SendText("You cannot carry that much weight.\r\n");
                return;
            }

            if (obj.WearLocation != ObjTemplate.WearLocation.none)
            {
                ch.SendText("Very daring, and you got it!\r\n");
                victim.UnequipObject(obj);
            }

            obj.RemoveFromChar();
            obj.ObjToChar(ch);
            ch.SendText("Nice work.\r\n");
            if (obj.Trap != null && obj.Trap.CheckTrigger( Trap.TriggerType.steal))
            {
                ch.SetOffTrap(obj);
                if (ch.CurrentPosition == Position.dead)
                {
                    return;
                }
            }
            return;
        }
示例#3
0
        /// <summary>
        /// Remove a piece of equipment.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Remove(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj;

            if (ch.IsAffected(Affect.AFFECT_HOLD) || ch.IsAffected(Affect.AFFECT_MINOR_PARA))
            {
                ch.SendText("You no longer have control of your body!\r\n");
                return;
            }

            if (str.Length == 0)
            {
                ch.SendText("Remove what?\r\n");
                return;
            }

            if (str[0] != "all" && MUDString.IsPrefixOf("all.", str[0]))
            {
                /* 'remove obj' */
                if (!(obj = ch.GetObjWear(str[0])))
                {
                    ch.SendText("You do not have that item.\r\n");
                    return;
                }

                if (ch.CarryNumber + 1 > Limits.MAX_CARRY)
                {
                    ch.SendText("You have your hands full.\r\n");
                    return;
                }

                ch.RemoveObject(obj.WearLocation, true);
                if (obj.Trap != null && obj.Trap.CheckTrigger( Trap.TriggerType.unequip))
                {
                    ch.SetOffTrap(obj);
                    if (ch.CurrentPosition == Position.dead)
                        return;
                }
            }
            else
            {
                /* 'remove all' or 'remove all.obj' */
                bool found = false;
                foreach (Object iobj in ch.Carrying)
                {
                    if (str.Length < 2 || (MUDString.NameContainedIn(str[0].Substring(4), iobj.Name)
                            && iobj.WearLocation != ObjTemplate.WearLocation.none))
                    {
                        found = true;
                        if (ch.CarryNumber + 1 > Limits.MAX_CARRY)
                        {
                            ch.SendText("You have your hands full.\r\n");
                            return;
                        }
                        ch.RemoveObject(iobj.WearLocation, true);
                        if (iobj.Trap != null && iobj.Trap.CheckTrigger(Trap.TriggerType.unequip))
                        {
                            ch.SetOffTrap(iobj);
                            if (ch.CurrentPosition == Position.dead)
                            {
                                return;
                            }
                        }
                    }
                }

                if (!found)
                {
                    if (str.Length == 0 || str[0].Length < 4)
                    {
                        ch.SendText("You can't find anything to remove.\r\n");
                    }
                    else
                    {
                        SocketConnection.Act("You can't find any $T&n to remove.",
                             ch, null, str[0].Substring(4), SocketConnection.MessageTarget.character);
                    }
                }
            }

            return;
        }
示例#4
0
        /// <summary>
        /// Put an object into another object.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Put(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj;

            if (str.Length < 2)
            {
                ch.SendText("Put what into what?\r\n");
                return;
            }

            if (!MUDString.StringsNotEqual(str[1], "all") || !MUDString.IsPrefixOf("all.", str[1]))
            {
                ch.SendText("You can't do that.\r\n");
                return;
            }

            Object container = ch.GetObjHere(str[1]);
            if (!container)
            {
                SocketConnection.Act("You see no $T&n here.", ch, null, str[1], SocketConnection.MessageTarget.character);
                return;
            }

            /*  Added put <missileweap> <quiver> */
            if (container.ItemType != ObjTemplate.ObjectType.container &&
                    container.ItemType != ObjTemplate.ObjectType.quiver)
            {
                ch.SendText("That's not a container.\r\n");
                return;
            }

            if (Macros.IsSet(container.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector))
            {
                SocketConnection.Act("The $d&n is &n&+ystrapped&n shut.", ch, null, container.Name, SocketConnection.MessageTarget.character);
                return;
            }

            if (str[0] != "all" && MUDString.IsPrefixOf("all.", str[0]))
            {
                /* 'put obj container' */
                obj = ch.GetObjCarrying(str[0]);
                if (!obj)
                {
                    ch.SendText("You do not have that item.\r\n");
                    return;
                }

                if (obj == container)
                {
                    ch.SendText("You can't fold it into itself.\r\n");
                    return;
                }

                if (!ch.CanDropObject(obj))
                {
                    ch.SendText("You can't seem to let go of it.\r\n");
                    return;
                }

                if (obj.GetWeight() + container.GetWeight() - container.Weight > container.Values[0])
                {
                    ch.SendText("It won't fit.\r\n");
                    return;
                }

                /* Added put <missileweap> <quiver> */
                if (container.ItemType == ObjTemplate.ObjectType.quiver
                        && obj.ItemType != ObjTemplate.ObjectType.missile_weapon)
                {
                    SocketConnection.Act("$p&n doesn't belong in $P&n.", ch, obj, container, SocketConnection.MessageTarget.character);
                    return;
                }

                obj.RemoveFromChar();
                container.AddToObject(obj);
                SocketConnection.Act("You put $p&n in $P&n.", ch, obj, container, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n slips $p&n into $P&n.", ch, obj, container, SocketConnection.MessageTarget.room);
                if (obj.Trap != null && obj.Trap.CheckTrigger(Trap.TriggerType.get_put))
                {
                    ch.SetOffTrap(obj);
                }
            }
            else
            {
                /* 'put all container' or 'put all.obj container' */
                bool stuff = false;

                foreach (Object iobj in ch.Carrying)
                {
                    if (iobj.WearLocation != ObjTemplate.WearLocation.none)
                    {
                        continue;
                    }

                    if (container.ItemType == ObjTemplate.ObjectType.quiver
                            && iobj.ItemType != ObjTemplate.ObjectType.missile_weapon)
                    {
                        continue;
                    }

                    if ((str[0][3] == '\0' || MUDString.NameContainedIn(str[0].Substring(4), iobj.Name))
                            && CharData.CanSeeObj(ch, iobj) && iobj.WearLocation == ObjTemplate.WearLocation.none
                            && iobj != container && ch.CanDropObject(iobj) && iobj.GetWeight() + container.GetWeight()
                            <= container.Values[0])
                    {
                        iobj.RemoveFromChar();
                        container.AddToObject(iobj);
                        stuff = true;
                        SocketConnection.Act("You put $p&n in $P&n.", ch, iobj, container, SocketConnection.MessageTarget.character);
                        //                Descriptor._actFlags( "$n&n puts $p&n in $P&n.", ch, iobj, container, Descriptor.MessageTarget.room );
                        if (iobj.Trap != null && iobj.Trap.CheckTrigger( Trap.TriggerType.get_put))
                        {
                            ch.SetOffTrap(iobj);
                            if (ch.CurrentPosition == Position.dead)
                            {
                                return;
                            }
                        }
                    }
                    else if (iobj.GetWeight() + container.GetWeight() > container.Values[0] && iobj != container)
                    {
                        SocketConnection.Act("$p&n won't fit into $P&n.", ch, iobj, container, SocketConnection.MessageTarget.character);
                    }
                }
                if (stuff)
                {
                    SocketConnection.Act("$n&n puts some stuff in $P&n.", ch, null, container, SocketConnection.MessageTarget.room);
                }
            }

            return;
        }
示例#5
0
        /// <summary>
        /// Command to open a door or a container.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Open(CharData ch, string[] str)
        {
            if( ch == null ) return;
            Object obj;
            Exit.Direction door;

            if (str.Length == 0 )
            {
                ch.SendText("What do you wish to open?\r\n");
                return;
            }

            if (!MUDString.StringsNotEqual(str[0], "door") && str.Length > 1 && str[1].Length > 0)
            {
                door = Movement.FindDoor(ch, str[1]);
            }
            else
            {
                door = Movement.FindDoor(ch, str[0]);
            }

            if (door != Exit.Direction.invalid && !(ch.Level < Limits.LEVEL_AVATAR
                && ch.InRoom.ExitData[(int)door] && ch.InRoom.ExitData[(int)door].ExitFlags != 0
                && ch.InRoom.ExitData[(int)door].HasFlag(Exit.ExitFlag.secret)))
            {
                /* 'open door' */
                Exit reverseExit;
                Room toRoom;

                if (ch.FlightLevel > 0)
                {
                    ch.SendText("You see no doors this high up!\r\n");
                    return;
                }
                if (ch.CurrentPosition == Position.fighting)
                {
                    ch.SendText("Stop fighting first!\r\n");
                    return;
                }
                Exit exit = ch.InRoom.GetExit(door);
                if (!exit.HasFlag(Exit.ExitFlag.closed))
                {
                    ch.SendText("It's already open.\r\n");
                    return;
                }
                if (exit.HasFlag(Exit.ExitFlag.locked))
                {
                    ch.SendText("It's locked.\r\n");
                    return;
                }

                exit.RemoveFlag(Exit.ExitFlag.closed);
                SocketConnection.Act("$n&n opens the $d.", ch, null, exit.Keyword, SocketConnection.MessageTarget.room);
                ch.SendText("Done.\r\n");

                /* open the other side */
                if ((toRoom = Room.GetRoom(exit.IndexNumber))
                    && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door)))
                    && reverseExit.TargetRoom == ch.InRoom)
                {
                    reverseExit.RemoveFlag(Exit.ExitFlag.closed);
                    reverseExit.RemoveFlag(Exit.ExitFlag.secret);
                    foreach (CharData roomChar in ch.InRoom.People)
                    {
                        SocketConnection.Act("The $d opens.", roomChar, null, reverseExit.Keyword, SocketConnection.MessageTarget.character);
                    }
                }

                return;
            }

            if ((obj = ch.GetObjHere(str[0])))
            {
                /* 'open portal' */
                if (obj.ItemType == ObjTemplate.ObjectType.portal)
                {
                    if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSEABLE))
                    {
                        ch.SendText("You can't do that.\r\n");
                        return;
                    }
                    if (!Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_CLOSED))
                    {
                        ch.SendText("It's already open.\r\n");
                        return;
                    }
                    if (Macros.IsSet(obj.Values[3], ObjTemplate.PORTAL_LOCKED))
                    {
                        ch.SendText("It's locked.\r\n");
                        return;
                    }

                    Macros.RemoveBit(ref obj.Values[3], ObjTemplate.PORTAL_CLOSED);
                    ch.SendText("Done.\r\n");
                    SocketConnection.Act("$n&n opens $p&n.", ch, obj, null, SocketConnection.MessageTarget.room);
                    return;
                }

                /* 'open object' */
                if (obj.ItemType != ObjTemplate.ObjectType.container &&
                        obj.ItemType != ObjTemplate.ObjectType.quiver)
                {
                    ch.SendText("That's not something that can be opened.\r\n");
                    return;
                }
                if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector))
                {
                    ch.SendText("It's already open.\r\n");
                    return;
                }
                if (!Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSEABLE.Vector))
                {
                    ch.SendText("You can't do that.\r\n");
                    return;
                }
                if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_LOCKED.Vector))
                {
                    ch.SendText("It's locked.\r\n");
                    return;
                }

                Macros.RemoveBit(ref obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector);
                ch.SendText("Done.\r\n");
                SocketConnection.Act("$n&n opens $p&n.", ch, obj, null, SocketConnection.MessageTarget.room);
                if (obj.Trap != null && obj.Trap.CheckTrigger( Trap.TriggerType.open))
                {
                    ch.SetOffTrap(obj);
                    if (ch.CurrentPosition == Position.dead)
                        return;
                }
                return;
            }

            ch.SendText("Open what?\r\n");
            return;
        }
示例#6
0
        /// <summary>
        /// This function's main access commands are wear, wield, and hold, which have the
        /// following flow:
        /// wear:  Command.Wear, wear_obj, equip_hand
        /// wield: Command.Wield, equip_hand
        /// hold:  Command.Hold, equip_hand 
        /// 
        /// We assume by this point that the character is physically able to use the item and will be able
        /// to equip it however specified.  Those checks are performed by WearObject(), Equip(), and Hold().
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="obj"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool EquipInHand(CharData ch, Object obj, int type)
        {
            int weight = 0;
            ObjTemplate.WearLocation firstAvail = ObjTemplate.WearLocation.none;
            ObjTemplate.WearLocation secondAvail = ObjTemplate.WearLocation.none;
            ObjTemplate.WearLocation lastAvail = ObjTemplate.WearLocation.none;

            Object hand1 = GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one);
            Object hand2 = GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two);
            Object hand3 = GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_three);
            Object hand4 = GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_four);
            if (hand1 && (hand1._itemType == ObjTemplate.ObjectType.weapon || hand1._itemType == ObjTemplate.ObjectType.ranged_weapon))
                weight += hand1.GetWeight();
            if (hand2 && (hand2._itemType == ObjTemplate.ObjectType.weapon || hand2._itemType == ObjTemplate.ObjectType.ranged_weapon))
                weight += hand2.GetWeight();
            if (hand3 && (hand3._itemType == ObjTemplate.ObjectType.weapon || hand3._itemType == ObjTemplate.ObjectType.ranged_weapon))
                weight += hand3.GetWeight();
            if (hand4 && (hand4._itemType == ObjTemplate.ObjectType.weapon || hand4._itemType == ObjTemplate.ObjectType.ranged_weapon))
                weight += hand4.GetWeight();

            if (ch.GetRace() != Race.RACE_THRIKREEN)
            {
                if (hand3)
                    Log.Error("non-thrikreen wielding item in hand3", 0);
                if (hand4)
                    Log.Error("non-thrikreen wielding item in hand4", 0);
            }

            // Find number of hand slots used and first available hand.
            // Be sure to handle twohanded stuff.
            if (hand4 && hand4.HasFlag(ObjTemplate.ITEM_TWOHANDED))
            {
                Log.Error("Twohanded weapon in fourth hand -- this is not possible.", 0);
            }
            if (hand3 && hand3.HasFlag(ObjTemplate.ITEM_TWOHANDED))
            {
                if (hand4)
                {
                    Log.Error("Twohanded weapon in third hand with fourth hand holding twohanded weapon -- this is not possible, all twohanded must have a blank hand after it.", 0);
                }
                hand4 = hand3;
            }
            if (hand2 && hand2.HasFlag(ObjTemplate.ITEM_TWOHANDED))
            {
                if (hand3)
                {
                    Log.Error("Twohanded weapon in second hand with third hand holding twohanded weapon -- this is not possible, all twohanded must have a blank hand after it.", 0);
                }
                hand2 = hand3;
            }
            if (!ch.HasInnate(Race.RACE_EXTRA_STRONG_WIELD))
            {
                if (hand1 && hand1.HasFlag(ObjTemplate.ITEM_TWOHANDED))
                {
                    if (hand2)
                    {
                        Log.Error("Twohanded weapon in second hand with first hand holding twohanded weapon -- this is not possible, all twohanded must have a blank hand after it.", 0);
                    }
                    hand2 = hand1;
                }
            }

            if (obj.HasFlag(ObjTemplate.ITEM_TWOHANDED)
                    && !ch.HasInnate(Race.RACE_EXTRA_STRONG_WIELD))
            {
                if (ch.GetRace() == Race.RACE_THRIKREEN && !hand4)
                {
                    firstAvail = ObjTemplate.WearLocation.hand_four;
                    lastAvail = ObjTemplate.WearLocation.hand_four;
                }
                if (ch.GetRace() == Race.RACE_THRIKREEN && !hand3)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_three;
                    secondAvail = firstAvail;
                    firstAvail = ObjTemplate.WearLocation.hand_three;
                }
                if (!hand2)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_two;
                    secondAvail = firstAvail;
                    firstAvail = ObjTemplate.WearLocation.hand_two;
                }
                if (!hand1)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_one;
                    secondAvail = firstAvail;
                    firstAvail = ObjTemplate.WearLocation.hand_one;
                }

                if (firstAvail == 0)
                {
                    ch.SendText("Your hands are full!\r\n");
                    return false;
                }
                if (secondAvail == 0)
                {
                    ch.SendText("You need two hands free to wield that!\r\n");
                    return false;
                }
            }
            else if (obj.HasFlag(ObjTemplate.ITEM_TWOHANDED))
            {
                if (ch.GetRace() == Race.RACE_THRIKREEN && !hand4)
                {
                    firstAvail = ObjTemplate.WearLocation.hand_four;
                }
                if (ch.GetRace() == Race.RACE_THRIKREEN && !hand3)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_three;
                    secondAvail = firstAvail;
                    firstAvail = ObjTemplate.WearLocation.hand_three;
                }
                if (!hand2)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_two;
                    secondAvail = firstAvail;
                    firstAvail = ObjTemplate.WearLocation.hand_two;
                }
                if (!hand1)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_one;
                    secondAvail = ObjTemplate.WearLocation.hand_one;
                    firstAvail = ObjTemplate.WearLocation.hand_one;
                }

                if (firstAvail == 0)
                {
                    ch.SendText("Your hands are full!\r\n");
                    return false;
                }
                if (secondAvail == 0)
                {
                    ch.SendText("You need two hands free to wield that!\r\n");
                    return false;
                }
            }
            else
            {
                if (ch.GetRace() == Race.RACE_THRIKREEN && !hand4)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_four;
                    firstAvail = ObjTemplate.WearLocation.hand_four;
                }
                if (ch.GetRace() == Race.RACE_THRIKREEN && !hand3)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_three;
                    firstAvail = ObjTemplate.WearLocation.hand_three;
                }
                if (!hand2)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_two;
                    firstAvail = ObjTemplate.WearLocation.hand_two;
                }
                if (hand1 == null)
                {
                    if (lastAvail == 0)
                        lastAvail = ObjTemplate.WearLocation.hand_one;
                    firstAvail = ObjTemplate.WearLocation.hand_one;
                }

                if (firstAvail == 0)
                {
                    ch.SendText("Your hands are full!\r\n");
                    return false;
                }
            }

            // Successful hand availability, send message and ready the item.
            // Twohanded shields, held items, and lights are equipped primary.
            // This could annoy ogres/thris but twohanded versions of these items
            // are so rare it's not likely to be an issue.
            switch (type)
            {
                case EQUIP_HOLD:
                    if (!obj.HasFlag(ObjTemplate.ITEM_TWOHANDED))
                        ch.EquipObject(ref obj, lastAvail);
                    else
                        ch.EquipObject(ref obj, firstAvail);
                    break;
                case EQUIP_SHIELD:
                    SocketConnection.Act("You strap $p&n to your arm.", ch, obj, null, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n straps $p&n to $s arm.", ch, obj, null, SocketConnection.MessageTarget.room);
                    if (!obj.HasFlag(ObjTemplate.ITEM_TWOHANDED))
                        ch.EquipObject(ref obj, lastAvail);
                    else
                        ch.EquipObject(ref obj, firstAvail);
                    break;
                case EQUIP_LIGHT:
                    if (obj._itemType == ObjTemplate.ObjectType.light && obj._values[2] != 0)
                    {
                        SocketConnection.Act("You &n&+rli&+Rght&n $p&n and hold it before you.", ch, obj, null, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$n&n &+Rlig&n&+rhts&n $p&n and holds it before $m.", ch, obj, null, SocketConnection.MessageTarget.room);
                    }
                    else
                    {
                        SocketConnection.Act("You hold the &+Lspent&n remains of $p&n.", ch, obj, null, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$n&n holds the spent husk of $p&n.", ch, obj, null, SocketConnection.MessageTarget.room);
                    }
                    if (!obj.HasFlag(ObjTemplate.ITEM_TWOHANDED))
                        ch.EquipObject(ref obj, lastAvail);
                    else
                        ch.EquipObject(ref obj, firstAvail);
                    break;
                case EQUIP_WIELD:
                    // Have to check for dual wield skill, and for total weight of weapons.
                    if (firstAvail != ObjTemplate.WearLocation.hand_one)
                    {
                        // Those without dual wield cannot wield anything in their second hand.  Include thrikreen
                        if (!ch.IsNPC() && !ch.HasSkill("dual wield"))
                        {
                            ch.SendText("You lack the skills to wield a weapon in anything but your primary hand.\r\n");
                            return false;
                        }
                    }
                    if ((weight + obj.GetWeight()) > StrengthModifier.Table[ch.GetCurrStr()].WieldWeight)
                    {
                        SocketConnection.Act("Your meager strength is overwhelmed by $p&n.", ch, obj, null, SocketConnection.MessageTarget.character);
                        return false;
                    }
                    SocketConnection.Act("You wield $p&n.", ch, obj, null, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n brandishes $p&n.", ch, obj, null, SocketConnection.MessageTarget.room);
                    ch.EquipObject(ref obj, firstAvail);
                    break;
            }

            // Objects with a trap activated on wear.
            if (obj._trap != null && obj._trap.CheckTrigger( Trap.TriggerType.wear))
            {
                ch.SetOffTrap(obj);
                if (ch.CurrentPosition == Position.dead)
                    return false;
            }

            return true;
        }