Пример #1
0
        /// <summary>
        /// Hide yourself or an object.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Hide(CharData ch, string[] str)
        {
            if( ch == null ) return;
            /* Check player's skill */
            if (!ch.HasSkill("hide"))
            {
                if(str.Length != 0)
                {
                    HideItem(ch, new[] { str[0] });
                    return;
                }
                ch.SendText("You're far too obvious to hide anywhere.\r\n");
                return;
            }

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

            if (ch.CurrentPosition <= Position.sleeping)
            {
                return;
            }
            ch.SendText("You attempt to hide.\r\n");

            if (ch.IsAffected(Affect.AFFECT_HIDE))
            {
                ch.RemoveAffect(Affect.AFFECT_HIDE);
            }

            if (ch.CheckSkill("hide"))
            {
                ch.SetAffectBit(Affect.AFFECT_HIDE);
            }

            ch.WaitState(12);

            return;
        }
Пример #2
0
        /// <summary>
        /// Get down from a mount.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Dismount(CharData ch, string[] str)
        {
            if( ch == null ) return;

            CharData victim = ch.Riding;
            if (!victim)
            {
                ch.SendText("You're not mounted.\r\n");
                return;
            }

            if (ch.Riding.InRoom != ch.InRoom)
            {
                ch.SendText("Weird! You dismount, but your mount isn't here.");
                if (ch.Riding.Rider && ch.Riding.Rider == ch)
                {
                    ch.Riding.Rider = null;
                }
                ch.Riding = null;
                return;
            }

            ch.WaitState(Skill.SkillList["mount"].Delay);
            if (ch.CheckSkill("mount", PracticeType.easy))
            {
                SocketConnection.Act("You dismount $N&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n skillfully dismounts $N&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                SocketConnection.Act("$n&n dismounts you.  Whew!", ch, null, victim, SocketConnection.MessageTarget.victim);
                victim.Rider = null;
                ch.Riding = null;
                ch.CurrentPosition = Position.standing;
            }
            else
            {
                SocketConnection.Act("You fall off while dismounting $N&n.  Ouch!", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n falls off of $N&n while dismounting.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                SocketConnection.Act("$n&n falls off your back.", ch, null, victim, SocketConnection.MessageTarget.victim);
                victim.Rider = null;
                ch.Riding = null;
                ch.CurrentPosition = Position.resting;
                Combat.InflictDamage(ch, ch, 1, String.Empty, ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
            }

            return;
        }
Пример #3
0
        public static void Heighten(CharData ch, string[] str)
        {
            if( ch == null ) return;
            Affect af = new Affect();

            if (!ch.IsNPC() && !ch.HasSkill("heighten senses"))
            {
                ch.SendText("Your senses are as heightened as they're going to get.\r\n");
                return;
            }

            if (ch.HasAffect( Affect.AffectType.skill, "heighten senses"))
                return;

            if (ch.CheckSkill("heighten senses"))
            {
                af.Value = "heighten senses";
                af.Type = Affect.AffectType.skill;
                af.Duration = 24 + ch.Level;
                af.SetBitvector(Affect.AFFECT_DETECT_INVIS);
                ch.AddAffect(af);

                af.SetBitvector(Affect.AFFECT_SENSE_LIFE);
                ch.AddAffect(af);

                af.SetBitvector(Affect.AFFECT_INFRAVISION);
                ch.AddAffect(af);

                ch.SendText("Your senses are heightened.\r\n");
            }
            return;
        }
Пример #4
0
        /// <summary>
        /// Command for corpse carving.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Carve(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object weap;
            Race.Parts value;

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

            Object corpse = ch.GetObjHere(str[0]);
            if (!corpse)
            {
                ch.SendText("I don't see that around here.\r\n");
                return;
            }

            if (corpse.ItemType != ObjTemplate.ObjectType.pc_corpse)
            {
                ch.SendText("That's not a player corpse!\r\n");
                return;
            }

            if (str.Length < 2)
            {
                ch.SendText("Parts of that corpse that are left:\r\n");
                if (corpse.Values[0] == 0)
                {
                    ch.SendText("None.\r\n");
                }
                else
                {
                    ch.SendText(StringConversion.PartsBitString((Race.Parts)corpse.Values[0]));
                }
                return;
            }

            // 11 is for piercing eapons
            if (!(weap = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one)) || weap.Values[3] != 11)
            {
                ch.SendText("You need some sort of stabbing weapon for carving.\r\n");
                return;
            }

            if (!MUDString.StringsNotEqual(str[1], "head"))
                value = Race.Parts.skull;
            else if (!MUDString.StringsNotEqual(str[1], "arms"))
                value = Race.Parts.arms;
            else if (!MUDString.StringsNotEqual(str[1], "legs"))
                value = Race.Parts.legs;
            else if (!MUDString.StringsNotEqual(str[1], "heart"))
                value = Race.Parts.heart;
            else if (!MUDString.StringsNotEqual(str[1], "brains"))
                value = Race.Parts.brains;
            else if (!MUDString.StringsNotEqual(str[1], "guts"))
                value = Race.Parts.guts;
            else if (!MUDString.StringsNotEqual(str[1], "hands"))
                value = Race.Parts.hands;
            else if (!MUDString.StringsNotEqual(str[1], "feet"))
                value = Race.Parts.feet;
            else if (!MUDString.StringsNotEqual(str[1], "fingers"))
                value = Race.Parts.fingers;
            else if (!MUDString.StringsNotEqual(str[1], "ears"))
                value = Race.Parts.ears;
            else if (!MUDString.StringsNotEqual(str[1], "eyes"))
                value = Race.Parts.eyes;
            else if (!MUDString.StringsNotEqual(str[1], "tongue"))
                value = Race.Parts.tongue;
            else if (!MUDString.StringsNotEqual(str[1], "eyestalks"))
                value = Race.Parts.eyestalks;
            else if (!MUDString.StringsNotEqual(str[1], "tentacles"))
                value = Race.Parts.tentacles;
            else if (!MUDString.StringsNotEqual(str[1], "fins"))
                value = Race.Parts.fins;
            else if (!MUDString.StringsNotEqual(str[1], "wings"))
                value = Race.Parts.wings;
            else if (!MUDString.StringsNotEqual(str[1], "tail"))
                value = Race.Parts.tail;
            else if (!MUDString.StringsNotEqual(str[1], "claws"))
                value = Race.Parts.claws;
            else if (!MUDString.StringsNotEqual(str[1], "fangs"))
                value = Race.Parts.fangs;
            else if (!MUDString.StringsNotEqual(str[1], "scales"))
                value = Race.Parts.scales;
            else if (!MUDString.StringsNotEqual(str[1], "horns"))
                value = Race.Parts.horns;
            else if (!MUDString.StringsNotEqual(str[1], "tusks"))
                value = Race.Parts.tusks;
            else
            {
                ch.SendText("No such part.\r\n");
                return;
            }

            if (!Macros.IsSet(corpse.Values[0], (int)value))
            {
                ch.SendText("That part has either already been removed or never existed.\r\n");
                return;
            }

            Macros.RemoveBit(ref corpse.Values[0], (int)value);
            if (ch.CheckSkill("carve"))
            {
                ch.SendText("You managed to pry it loose!\r\n");
            }
            else
            {
                ch.SendText("You mangled that part badly.\r\n");
                return;
            }

            /* corpse of {0} */
            string name = MUDString.LastArgument(corpse.Name);
            // This is where we would normally create the object...
            Object part;
            switch (value)
            {
                default:
                    part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SEVERED_SKULL), 0);
                    break;
                case Race.Parts.arms:
                    // Arms are wieldable as a club.
                    part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SLICED_ARM), 0);
                    break;
                case Race.Parts.legs:
                    // Legs are wieldable as a club, more damage than arms.
                    part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SLICED_LEG), 0);
                    break;
                case Race.Parts.scalp:
                    // Scalp can be attached to belt.
                    part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_SEVERED_SCALP), 0);
                    break;
                case Race.Parts.heart:
                    // Heart can be eaten as food.
                    part = Database.CreateObject(Database.GetObjTemplate(StaticObjects.OBJECT_NUMBER_TORN_HEART), 0);
                    break;
            }
            string buf = String.Format("{0} {1}", StringConversion.PartsBitString(value), name);
            part.Name = buf;
            part.ShortDescription = String.Empty;
            buf = String.Format("the{0} of {1}", StringConversion.PartsBitString(value), name);
            part.ShortDescription = buf;
            buf = String.Format("The{0} of {1}&n {2} lying here.", StringConversion.PartsBitString(value), name, MUDString.IsAre(StringConversion.PartsBitString(value)));
            part.FullDescription = buf;
            part.Cost = 0;
            part.Level = corpse.Level;
            if (value == Race.Parts.skull) // Should be skull.
                part.Timer = -1;
            else
                part.Timer = MUDMath.Dice(5, 20);
            part.AddFlag(ObjTemplate.ITEM_NOSELL);
            corpse.AddToObject(part);
        }
Пример #5
0
        public static void Chameleon(CharData ch, string[] str)
        {
            if( ch == null ) return;
            if (!ch.IsNPC() && !ch.HasSkill("chameleon power"))
            {
                ch.SendText("You don't know how to act like a chameleon.\r\n");
                return;
            }

            ch.SendText("You attempt to blend in with your surroundings.\r\n");

            if (ch.IsAffected(Affect.AFFECT_HIDE))
            {
                ch.RemoveAffect(Affect.AFFECT_HIDE);
            }

            if (ch.CheckSkill("chameleon power"))
            {
                ch.SetAffectBit(Affect.AFFECT_HIDE);
            }

            return;
        }
Пример #6
0
        /// <summary>
        /// Rescue command.  Interpose yourself between the target and their opponent so you become
        /// the one taking damage.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Rescue(CharData ch, string[] str)
        {
            if( ch == null ) return;

            CharData victim;

            /* Don't allow the unskilled to rescue */
            if ((!ch.HasSkill("rescue")))
            {
                ch.SendText("You'd better leave the heroic acts to warriors.\r\n");
                return;
            }

            if (ch.IsAffected(Affect.AFFECT_BERZERK))
            {
                ch.SendText("You can't rescue anyone, you're in a &+RBl&n&+ro&+Ro&n&+rd&+L Rage&n!!\r\n");
                return;
            }

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

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

            if (!(victim = ch.GetCharRoom(str[0])))
            {
                ch.SendText("They aren't here.\r\n");
                return;
            }

            if (victim == ch)
            {
                ch.SendText("What about fleeing instead?\r\n");
                return;
            }

            if (ch.Fighting == victim)
            {
                ch.SendText("Too late.\r\n");
                return;
            }

            if (!victim.Fighting)
            {
                ch.SendText("That person is not fighting right now.\r\n");
                return;
            }

            if (ch.IsBlind())
            {
                return;
            }

            ch.WaitState(Skill.SkillList["rescue"].Delay);

            int count = 0;
            CharData fighter = null;
            foreach (CharData ifch in ch.InRoom.People)
            {
                if (ifch.Fighting == victim)
                {
                    if (MUDMath.NumberRange(0, count) == 0)
                    {
                        fighter = ifch;
                        break;
                    }
                    ++count;
                }
            }

            if (!fighter || !ch.CheckSkill("rescue"))
            {
                SocketConnection.Act("$n&n fails miserably in $s attempt to rescue $N&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                SocketConnection.Act("$n&n fails miserably in $s attempt to rescue you.", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("You fail in your attempt to rescue $N&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                return;
            }

            SocketConnection.Act("&+WYou leap in front of $N&n!", ch, null, victim, SocketConnection.MessageTarget.character);
            SocketConnection.Act("&+W$n&+W rescues you!", ch, null, victim, SocketConnection.MessageTarget.victim);
            SocketConnection.Act("&+w$n&+w leaps in front of $N&+w taking his place in battle!&n", ch, null, victim, SocketConnection.MessageTarget.room_vict);

            Combat.StopFighting(fighter, false);
            Combat.StopFighting(victim, false);

            Combat.SetFighting(fighter, ch);
            if (!ch.Fighting)
            {
                Combat.SetFighting(ch, fighter);
            }
            return;
        }
Пример #7
0
        public static void Shadow(CharData ch, string[] str)
        {
            if( ch == null ) return;
            Affect af = new Affect();

            if (!ch.IsNPC()
                    && !ch.HasSkill("shadow form"))
            {
                ch.SendText("You don't know how to take shadow form.\r\n");
                return;
            }

            ch.SendText("You attempt to move in the shadows.\r\n");
            ch.AffectStrip( Affect.AffectType.skill, "shadow form");

            if (ch.CheckSkill("shadow form"))
            {
                af.Value = "shadow form";
                af.Type = Affect.AffectType.skill;
                af.Duration = ch.Level;
                af.SetBitvector(Affect.AFFECT_SNEAK);
                ch.AddAffect(af);
            }
            ch.WaitState(10);

            return;
        }
Пример #8
0
        /// <summary>
        /// Apply poison to a weapon.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void PoisonWeapon(CharData ch, string[] str)
        {
            if (ch == null)
            {
                return;
            }

            Object obj;
            Object pobj = null;
            Affect af = new Affect();

            /* Don't allow mobs or unskilled pcs to do this */
            if (ch.IsNPC() || (!ch.IsNPC() && !ch.HasSkill("poison weapon")))
            {
                ch.SendText("What do you think you are, a thief?\r\n");
                return;
            }

            if (str.Length == 0)
            {
                ch.SendText("What are you trying to poison?\r\n");
                return;
            }
            if (ch.Fighting != null)
            {
                ch.SendText("While you're fighting?  Nice try.\r\n");
                return;
            }
            if (!(obj = ch.GetObjCarrying(str[0])))
            {
                ch.SendText("You do not have that weapon.\r\n");
                return;
            }
            if (obj.ItemType != ObjTemplate.ObjectType.weapon)
            {
                ch.SendText("That item is not a weapon.\r\n");
                return;
            }
            if (obj.HasFlag(ObjTemplate.ITEM_POISONED))
            {
                ch.SendText("That weapon is already poisoned.\r\n");
                return;
            }
            if (obj.Values[0] != 2)
            {
                ch.SendText("You don't have enough poison to cover that!\r\n");
                return;
            }

            /* Now we have a valid weapon...check to see if we have the poison. */
            foreach (Object iobj in ch.Carrying)
            {
                // here is where we should check to see if they have poison
                if (iobj.ItemType == ObjTemplate.ObjectType.drink_container
                        && iobj.Values[2] == 27)
                {
                    pobj = iobj;
                    break;
                }
            }
            if (!pobj)
            {
                ch.SendText("You do not have any poison.\r\n");
                return;
            }

            if (pobj.Values[1] <= 0 && pobj.Values[1] != -1)
            {
                SocketConnection.Act("Sorry, $p&n seems to be empty.", ch, pobj, null, SocketConnection.MessageTarget.character);
                return;
            }

            ch.WaitState(Skill.SkillList["poison weapon"].Delay);

            /* Check the skill percentage */
            if (!ch.CheckSkill("poison weapon"))
            {
                ch.SendText("You failed and spill some on yourself.  &+ROuch!&n\r\n");
                Combat.InflictDamage(ch, ch, ch.Level, "poison weapon", ObjTemplate.WearLocation.none, AttackType.DamageType.poison);
                SocketConnection.Act("$n spills the &+Gpoison&n all over!", ch, null, null, SocketConnection.MessageTarget.room);
                pobj.Values[1] -= 2;
                return;
            }

            /* Can't have people smearing gunk on artifacts */
            if (obj.InsultArtifact(ch))
            {
                pobj.Values[1]--;
                return;
            }

            SocketConnection.Act("You apply the &+Gpoison&n to $p&n, which glistens wickedly!",
                 ch, obj, null, SocketConnection.MessageTarget.character);
            SocketConnection.Act("$n&n pours the &+Gli&n&+gq&+Gu&n&+gid&n over $p&n, which glistens wickedly!",
                 ch, obj, null, SocketConnection.MessageTarget.room);

            af.Value = "poison weapon";
            af.Type = Affect.AffectType.skill;
            af.Duration = ch.Level + MUDMath.Dice(4, ch.Level / 2);
            af.AddModifier(Affect.Apply.none, pobj.Values[3]);
            af.Level = ch.Level;
            af.SetBitvector(Affect.AFFECT_POISON);
            obj.AddAffect(af);
            // Consume one unit of the poison source.
            pobj.Values[1]--;
            return;
        }
Пример #9
0
        /// <summary>
        /// Use a scroll to invoke its magical spells.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Recite(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object scroll;
            Object obj = null;
            CharData victim;
            string arg1 = String.Empty;
            string arg2 = String.Empty;

            if (!(scroll = ch.GetObjCarrying(arg1)))
            {
                ch.SendText("You do not have that &+Wscroll&n.\r\n");
                return;
            }

            if (scroll.ItemType != ObjTemplate.ObjectType.scroll)
            {
                ch.SendText("You can recite only &+Wscrolls&n.\r\n");
                return;
            }

            if (String.IsNullOrEmpty(arg2))
            {
                victim = ch;
                if (ch.Fighting != null)
                {
                    victim = ch.Fighting;
                }
            }
            else
            {
                if (((victim = ch.GetCharRoom(arg2)) == null) && !(obj = ch.GetObjHere(arg2)))
                {
                    ch.SendText("You can't find it.\r\n");
                    return;
                }
            }

            if (!ch.CanSpeak())
            {
                ch.SendText("Your lips move but no sound comes out.\r\n");
                return;
            }

            if (ch.IsNPC() && !ch.IsFreewilled())
            {
                SocketConnection.Act("You try to recite $p&n, but you have no free will.", ch, scroll, null, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n tries to recite $p&n, but has no free will.", ch, scroll, null, SocketConnection.MessageTarget.room);
                return;
            }

            ch.WaitState(2 * Event.TICK_COMBAT);

            SocketConnection.Act("You recite $p&n.", ch, scroll, null, SocketConnection.MessageTarget.character);
            SocketConnection.Act("$n&n recites $p&n.", ch, scroll, null, SocketConnection.MessageTarget.room);

            if (ch.CheckSkill("scrolls"))
            {
                switch (MUDMath.NumberBits(3))
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                        SocketConnection.Act("You can't understand $p&n at all.",
                             ch, scroll, null, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$n&n can't understand $p&n at all.",
                             ch, scroll, null, SocketConnection.MessageTarget.room);
                        return;
                    case 4:
                    case 5:
                    case 6:
                        ch.SendText("You must have said something incorrectly.\r\n");
                        SocketConnection.Act("$n&n must have said something incorrectly.", ch, null, null, SocketConnection.MessageTarget.room);
                        SocketConnection.Act("$p&n blazes brightly, then is gone.",
                             ch, scroll, null, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$p&n blazes brightly and disappears.",
                             ch, scroll, null, SocketConnection.MessageTarget.room);
                        scroll.RemoveFromWorld();
                        ;
                        return;
                    case 7:
                        SocketConnection.Act(
                            "You completely botch the recitation, and $p&n bursts into &+Rflames&n!!",
                            ch, scroll, null, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$p&n &+rglows&n and then bursts into &+Rflame&n!",
                             ch, scroll, null, SocketConnection.MessageTarget.room);
                        /*
                        * Command.damage( ) call after Object.extract_obj in case the damage would
                        * have extracted ch.  This is okay because we merely mark
                        * obj.deleted; it still retains all values until list_update.
                        * Sloppy?  Okay, create another integer variable.
                        */
                        scroll.RemoveFromWorld();
                        Combat.InflictDamage(ch, ch, scroll.Level, "scrolls", ObjTemplate.WearLocation.none, AttackType.DamageType.fire);
                        return;
                }
            }

            if (scroll.Level > ch.Level)
            {
                SocketConnection.Act("$p&n is too high level for you.", ch, scroll, null, SocketConnection.MessageTarget.character);
            }
            else
            {
                /* scroll.Values[0] is not used for scrolls */
                for (int i = 1; i <= 4; i++)
                {
                    String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(scroll.Values[i]);
                    if (String.IsNullOrEmpty(spellName))
                    {
                        Log.Error("Recite: Spell number " + obj.Values[i] + " not found for object " + scroll.ObjIndexNumber + ". Make sure it's in the SpellNumberToTextMap.");
                    }
                    Spell spell = StringLookup.SpellLookup(spellName);
                    if (!spell)
                    {
                        Log.Error("Recite: Spell '" + spellName + "' not found for object " + scroll.ObjIndexNumber + ". Make sure it's in the spells file.");
                    }
                    else
                    {
                        spell.Invoke(ch, scroll.Level, ch);
                    }
                }
            }

            if (!ch.IsNPC() || (ch.IsNPC() && ch.IsAffected(Affect.AFFECT_CHARM)))
            {
                scroll.RemoveFromWorld();
            }
            return;
        }
Пример #10
0
        /// <summary>
        /// Climb on and ride a mount (horse, griffon, etc.)
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Mount(CharData ch, string[] str)
        {
            if (!ch)
            {
                Log.Error("Commandmount: no ch!", 0);
                return;
            }

            if (ch.Riding)
            {
                ch.SendText("You're already mounted!\r\n");
                return;
            }

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

            CharData victim = ch.GetCharRoom(str[0]);
            if (victim == null)
            {
                ch.SendText("You can't find that here.\r\n");
                return;
            }

            if (!victim.IsNPC() || !victim.HasActionBit(MobTemplate.ACT_MOUNT))
            {
                ch.SendText("You can't mount that!\r\n");
                return;
            }

            if (ch.Rider)
            {
                ch.SendText("You are being ridden by someone else!\r\n");
                return;
            }

            if (victim.Rider)
            {
                ch.SendText("That mount already has a rider.\r\n");
                return;
            }

            if (victim.CurrentPosition < Position.standing)
            {
                ch.SendText("Your mount must be standing.\r\n");
                return;
            }

            if (victim.CurrentPosition == Position.fighting || victim.Fighting)
            {
                ch.SendText("Your mount is moving around too much.\r\n");
                return;
            }

            ch.WaitState(Skill.SkillList["mount"].Delay);
            // NPCs and Immortals automatically succeed.  The former is partly because the mount command
            // can be issued by a zone reset.  We wouldn't want a mob to fail a mount when the area declares
            // that they should be mounted.
            if (ch.IsNPC() || ch.IsImmortal() || ch.CheckSkill("mount", PracticeType.easy ))
            {
                victim.Rider = ch;
                ch.Riding = victim;
                SocketConnection.Act("You mount $N&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n skillfully mounts $N&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                SocketConnection.Act("$n&n mounts you.", ch, null, victim, SocketConnection.MessageTarget.victim);
            }
            else
            {
                SocketConnection.Act("You unsuccessfully try to mount $N&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n unsuccessfully attempts to mount $N&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                SocketConnection.Act("$n&n tries to mount you.", ch, null, victim, SocketConnection.MessageTarget.victim);
            }

            return;
        }
Пример #11
0
        public static void Berzerk(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Affect af = new Affect();

            /* Don't allow charmed mobs to do this, check player's level */
            if ((ch.IsNPC() && ch.IsAffected( Affect.AFFECT_CHARM))
                    || (!ch.IsNPC() && !ch.HasSkill("berzerk")))
            {
                ch.SendText("You're not enough of a warrior to enter a &+RBl&n&+ro&+Ro&n&+rd&+L Rage&n.\r\n");
                return;
            }

            if (ch.IsAffected(Affect.AFFECT_BERZERK))
            {
                if (MUDMath.NumberPercent() + 10 > ((PC)ch).SkillAptitude["berzerk"])
                {
                    ch.SendText("You failed to calm yourself down!\r\n");
                    ch.WaitState(Skill.SkillList["berzerk"].Delay);
                    return;
                }
                ch.SendText("You no longer see targets everywhere.\r\n");
                ch.RemoveAffect(Affect.AFFECT_BERZERK);
                ch.WaitState(Skill.SkillList["berzerk"].Delay);
                return;
            }

            ch.SendText("Your slam your weapon into yourself and &+Rbl&n&+ro&+Ro&n&+rd&n splatters all over!\r\n");
            ch.SendText("The sight of &+Rbl&n&+ro&+Ro&n&+rd&n begins to drive you crazy!\r\n");

            if (ch.CheckSkill("berzerk"))
            {
                af.Value = "berzerk";
                af.Type = Affect.AffectType.skill;
                af.Duration = MUDMath.Dice(1, 2);
                af.AddModifier( Affect.Apply.hitroll, Math.Max(ch.Level / 6, 2));
                af.AddModifier( Affect.Apply.damroll, Math.Max(ch.Level / 6, 2));
                af.AddModifier( Affect.Apply.ac, (ch.Level / 2));
                af.AddModifier( Affect.Apply.max_constitution, MUDMath.Dice(5, 9));
                af.AddModifier( Affect.Apply.agility, 0 - MUDMath.Dice(5, 9));
                af.AddModifier( Affect.Apply.max_strength, MUDMath.Dice(5, 9));
                af.SetBitvector(Affect.AFFECT_BERZERK);
                ch.AddAffect(af);

                ch.SendText("You are overcome by &+RBl&n&+ro&+Ro&n&+rd&+L Rage&n!!\r\n");
                SocketConnection.Act("$n has slipped into a &+RBl&n&+ro&+Ro&n&+rd&+L Rage&n!!", ch, null, null, SocketConnection.MessageTarget.room);

                return;
            }
            ch.SendText("You get a little angry, but fail to call up a &+Rblood rage&n.\r\n");

            return;
        }
Пример #12
0
        /// <summary>
        /// Hit one guy once.
        ///
        /// Hitroll is now done on a 200-sided die rather than a 20-sided die
        /// This allows for more dynamic modifiers to hitroll.
        /// i.e. a couple extra points of strength and whatnot _may_ make the
        /// difference between a hit and a miss rather than incrementing something
        /// every 10-20 points of an ability we can modify it every 1-2 points.
        /// </summary>
        /// <param name="ch">attacker</param>
        /// <param name="victim">person being attacked</param>
        /// <param name="skill">damage type being used (skill)</param>
        /// <param name="weapon">wear location of weapon (usually primary or secondary hand)</param>
        /// <returns>true if victim is killed, otherwise false</returns>
        public static bool SingleAttack(CharData ch, CharData victim, string skill, ObjTemplate.WearLocation weapon)
        {
            string text;
            int dam;
            int chance;

            /*
            * Can't beat a dead char!
            * Guard against weird room-leavings.
            */
            if( victim.CurrentPosition == Position.dead || victim.Hitpoints < -10 )
            {
                text = String.Format("SingleAttack: ch {0} fighting dead victim {1}.", ch.Name, victim.Name );
                Log.Error( text, 0 );
                ch.Fighting = null;
                if( ch.CurrentPosition == Position.fighting )
                    ch.CurrentPosition = Position.standing;
                return true;
            }
            if( ch.InRoom != victim.InRoom )
            {
                text = String.Format("SingleAttack: ch {0} not with victim {1}.", ch.Name, victim.Name );
                Log.Error( text, 0 );
                ch.Fighting = null;
                if( ch.CurrentPosition == Position.fighting )
                    ch.CurrentPosition = Position.standing;
                return false;
            }

            /* No casting/being para'd and hitting at the same time. */
            if ((ch.IsAffected(Affect.AFFECT_CASTING)) || ch.IsAffected(Affect.AFFECT_MINOR_PARA)
                    || ch.IsAffected(Affect.AFFECT_HOLD))
            {
                return false;
            }

            // Inertial barrier will prevent some attacks.  At the following levels a person
            // affected by inertial barrier will be able to avoid this percentage of attacks:
            // 1 = 7%  5 = 10%  10 = 13%  20 = 20%  30 = 27%  40 = 33%  50 = 39%  51 = 40%
            if (victim.IsAffected(Affect.AFFECT_INERTIAL_BARRIER) && MUDMath.NumberPercent() > (victim.Level * 2 / 3 + 7))
                return false;

            // Keep in mind that CheckRiposte returns a boolean.
            if (skill != "kick" && skill != "backstab" && skill != "circle" && CheckRiposte( ch, victim ) )
            {
                SingleAttack( victim, ch, String.Empty, ObjTemplate.WearLocation.hand_one );
                return false;
            }
            if (CheckParry(ch, victim) && skill != "backstab" && skill != "circle")
                return false;
            if (CheckShieldBlock(ch, victim) && skill != "backstab" && skill != "circle")
                return false;
            if (CheckDodge(ch, victim) && skill != "backstab" && skill != "circle")
                return false;

            /*
            * Figure out the type of damage message if we don't have an associated attack skill.
            */
            Object wield = Object.GetEquipmentOnCharacter( ch, weapon );
            if (String.IsNullOrEmpty(skill))
            {
                skill = "barehanded fighting";
                if( wield && wield.ItemType == ObjTemplate.ObjectType.weapon )
                    skill = AttackType.Table[wield.Values[3]].SkillName;
            }

            /*
            * Weapon proficiencies.
            */
            string weaponGsn = "barehanded fighting";
            AttackType.DamageType damType = AttackType.DamageType.bludgeon;
            if( wield && wield.ItemType == ObjTemplate.ObjectType.weapon )
            {
                if( wield.Values[ 3 ] >= 0 && wield.Values[ 3 ] < AttackType.Table.Length )
                {
                    weaponGsn = (AttackType.Table[wield.Values[3]].SkillName);
                    damType = AttackType.Table[ wield.Values[ 3 ] ].DamageInflicted;
                }
                else
                {
                    text = String.Format( "SingleAttack: bad weapon damage type {0} caused by {1} ({2}).",
                              skill, wield.Name, wield.ObjIndexData ?
                              wield.ObjIndexData.IndexNumber : -1 );
                    Log.Error( text, 0 );
                    wield.Values[ 3 ] = 0;
                }
            }

            /*
            * Calculate to-hit-armor-class-0 versus armor.
            */
            int hitroll00 = ch.CharacterClass.HitrollLevel0;
            int hitroll40 = ch.CharacterClass.HitrollLevel40;

            /* Weapon-specific hitroll and damroll */

            int hitroll = MUDMath.Interpolate( ch.Level, hitroll00, hitroll40 )
                          - ( ch.GetHitroll( weapon ) * 3 );
            int victimAC = Math.Max( -100, victim.GetAC() );

            // Added blindfighting skill - Xangis
            if( !CharData.CanSee( ch, victim ) )
            {
                if( ch.CheckSkill( "blindfighting" ) )
                {
                    victimAC -= 5;
                }
                else
                {
                    victimAC -= 40;
                }
            }

            /* Weapon proficiencies *
            *
            * The twohanded version of a weapon proficiency *MUST* follow the onehanded
            * version in the definitions.  This is stupid.
            */
            if( wield && wield.ItemType == ObjTemplate.ObjectType.weapon )
            {
                if( !wield.HasFlag( ObjTemplate.ITEM_TWOHANDED ) )
                {
                    if( ch.CheckSkill( weaponGsn ))
                    {
                        victimAC += 20;
                        ch.PracticeSkill( weaponGsn );
                    }
                }
                else
                {
                    // This is not going to work.
                    if (ch.CheckSkill(weaponGsn+1))
                    {
                        victimAC += 20;
                        ch.PracticeSkill(weaponGsn);
                    }
                }
            }
            else if( ch.CheckSkill("barehanded fighting"))
            {
                victimAC += 20;
            }

            /*
            * The moment of excitement!
            */
            int diceroll = MUDMath.NumberRange( 0, 199 );

            // Give them a small bonus if they can make a successful luck check.
            if( MUDMath.NumberPercent() <= ch.GetCurrLuck() )
                diceroll += 5;

            /* Made really lucky chars get saved by the godz. */
            if( diceroll == 0 || ( diceroll <= 196 && diceroll < hitroll - victimAC )
                     || ( MUDMath.NumberPercent() < victim.GetCurrLuck() / 40 ) )
            {
                /* Miss. */
                return InflictDamage(ch, victim, 0, skill, weapon, damType);
            }

            /*
            * Hit.
            * Calc damage.
            *
            * NPCs are more badass barehanded than players.  If they weren't
            * the game would be too damned easy since mobs almost never have
            * weapons.
            *
            * Increased mob damage by about 1/6
            * It was previously level/2 to level*3/2 (25-75 at 50, average 50)
            * It is now level*3/5 to level*10/6      (30-87 at 50, average 59)
            *
            * Added the + ch.level - 1 'cause mobs still not hittin' hard enough
            */
            if( ch.IsNPC() )
            {
                dam = MUDMath.NumberRange( ( ch.Level * 3 / 5 ), ( ch.Level * 14 / 8 ) )
                      + ( ch.Level - 1 );
                if (wield)
                {
                    dam += MUDMath.Dice(wield.Values[1], wield.Values[2]);
                }
                else if (ch.CheckSkill("unarmed damage"))
                {
                    dam += MUDMath.NumberRange(1, (ch.GetSkillChance("unarmed damage") / 12));
                }
            }
            else
            {
                if (wield)
                {
                    dam = MUDMath.Dice(wield.Values[1], wield.Values[2]);
                }
                else
                {
                    if (!ch.IsClass(CharClass.Names.monk))
                    {
                        dam = MUDMath.NumberRange(1, (2 + (int)ch.CurrentSize / 3));
                        if (ch.CheckSkill("unarmed damage"))
                        {
                            dam += MUDMath.NumberRange(1, (ch.GetSkillChance("unarmed damage") / 12));
                        }
                    }
                    else
                    {
                        int min;
                        // monk barehanded damage - Xangis
                        ch.PracticeSkill("unarmed damage");
                        chance = ch.GetSkillChance("unarmed damage");
                        if (chance < 13)
                        {
                            min = 1;
                        }
                        else
                        {
                            min = chance / 13;
                        }
                        // at max skill for barehanded and unarmed, a monk will get
                        // a damage of 7-38, an average of 22.5 damage per hit before
                        // modifiers.  This is slightly better than a 6d6 weapon (average of 21 dmg)
                        // this is slightly worse than a 6d7 weapon (average of 24 dmg)
                        dam = MUDMath.NumberRange(min, ((chance / 3) + min));
                    }
                }
                if( ( wield && dam > 1000 ) && ch.Level < Limits.LEVEL_AVATAR )
                {
                    text = String.Format( "SingleAttack damage range > 1000 from {0} to {1}",
                              wield.Values[ 1 ], wield.Values[ 2 ] );
                    Log.Error( text, 0 );
                }
            }

            /*
            * Played a character with an armor class of 126 (awful agility).
            * Wasn't getting pounded much at all.  Added a damage bonus applied
            * when the target's ac is worse than 100.
            *
            * This also means that someone who makes their weapon proficiency
            * check against someone with an ac of 81 or higher will also get a
            * damage bonus of 1% per ac point.
            *
            * This applies to mobs too, so if a mob has a terrible AC it will
            * get whacked harder.  I call this the "soft as a pudding" code.
            *
            * This would also make AC debuffs stronger if they can make ac worse
            * than 100.
            */
            if( victimAC > 100 )
            {
                dam += ( (victimAC - 100) * dam) / 100;
            }

            /*
            * Bonuses.
            */
            dam += ch.GetDamroll( weapon );

            /* Weapon proficiencies, players only */
            /* Up to 50% increase based on weapon skill */
            if (wield && !ch.IsNPC())
            {
                dam += dam * ch.GetSkillChance(weaponGsn) / 180;
            }

            /* Up to 33% for offense skill */
            /* This means someone that has mastered a weapon and offense
            automatically does double damage in combat */
            chance = ch.GetSkillChance("offense");
            dam += dam * chance / 270;

            /* Bad idea to get caught napping in a fight */
            if( !victim.IsAwake() )
                dam *= 2;

            /* Backstab: 2 + one per 9 levels, 7x damage at 50 */
            if (skill == "backstab")
            {
                // Cap was previously too low.  It has been raised because a merc that was previously
                // stabbing for 180 now stabs for 64.  Assassins will still be able to stab for
                // 175 and mercs for 116 with this revised cap.  Keep in mind that a sorc can easily
                // fist for 250.
                int cap = 100 + 12 * ch.Level;
                if( ch.IsClass(CharClass.Names.mercenary) || ch.IsClass(CharClass.Names.bard ))
                    cap = cap * 2 / 3;
                dam *= ( 2 + ( ch.Level / 9 ) );
                /* damage cap applied here */
                dam = Math.Min( dam, cap );
            }
            else if (skill == "circle")              /* 150% to 200% at lev. 50 */
                dam += dam / 2 + ( dam * ch.Level ) / 100;

            if( dam <= 0 )
                dam = 1;

            return InflictDamage(ch, victim, dam, skill, weapon, damType);
        }
Пример #13
0
        /// <summary>
        /// Regeneration and natural healing.
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        public static int HitGain( CharData ch )
        {
            int gain;
            int percent = 0;

            if( ch == null )
            {
                Log.Error( "HitGain(): null ch", 0 );
                return 0;
            }

            // They aren't going to gain hits in a no heal room...
            if (ch.InRoom.HasFlag(RoomTemplate.ROOM_NO_HEAL))
            {
                return 0;
            }

            gain = 1;
            percent = 100;

            if (ch.CheckSkill("fast healing", PracticeType.none))
            {
                gain += 1;
            }
            if (MUDMath.NumberPercent() < 3)
            {
                ch.PracticeSkill("fast healing");
            }

            switch( ch.CurrentPosition )
            {
                case Position.sleeping:
                    gain += 3;
                    break;
                case Position.reclining:
                    gain += 2;
                    break;
                case Position.resting:
                    gain += 1;
                    break;
                case Position.fighting:
                    gain = 0;
                    break;
            }

            if( ch.HasInnate( Race.RACE_REGENERATE ) )
            {
                // Automatically one extra hp, two at level 30.
                gain += 1 + (ch.Level / 30);
                // One percent chance of gaining another per level.
                percent += (ch.Level);
            }

            // Hunger and thirst for PCs.
            if (!ch.IsNPC())
            {
                if (((PC)ch).Hunger == 0)
                {
                    gain /= 2;
                    gain -= 1;
                    percent -= 25;
                    ch.SendText("&nYou double over from &+Rhunger pains&n!\r\n");
                }

                if (((PC)ch).Thirst == 0)
                {
                    gain /= 2;
                    gain -= 1;
                    percent -= 25;
                    ch.SendText("&nYou suffer from severe &+cth&+Ci&n&+cr&+Cst&n!\r\n");
                }
            }

            if( ch.IsAffected( Affect.AFFECT_POISON ) )
            {
                gain /= 4;
                percent /= 2;
            }

            if( gain == 0 )
                if( MUDMath.NumberPercent() < percent )
                    gain = 1;

            // Heal rooms heal you a little quicker
            if (ch.InRoom.HasFlag(RoomTemplate.ROOM_HEAL))
            {
                gain += Math.Max(1, gain / 2);
            }

            if( ( ch.InRoom.TerrainType != TerrainType.underwater_has_ground
                    && ch.InRoom.TerrainType != TerrainType.unswimmable_water
                    && ch.InRoom.TerrainType != TerrainType.swimmable_water
                    && ch.HasInnate( Race.RACE_WATERBREATH )
                    && MUDString.StringsNotEqual( Race.RaceList[ ch.GetRace() ].Name, "Object" )
                    && ch.GetRace() != Race.RACE_GOD )
                    || ( ch.InRoom.TerrainType == TerrainType.underwater_has_ground
                         && ( !ch.IsImmortal() && !ch.IsAffected( Affect.AFFECT_BREATHE_UNDERWATER )
                              && !ch.HasInnate( Race.RACE_WATERBREATH ) ) ) )
                gain = 0;

            return Math.Min( gain, ch.GetMaxHit() - ch.Hitpoints );
        }
Пример #14
0
        /// <summary>
        /// Called by the cast function to process a spell's targets and react accordingly.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="spell"></param>
        /// <param name="argument"></param>
        private static void ProcessSpellTargets(CharData ch, Spell spell, string argument)
        {
            Object obj = null;
            Target target = null;
            CharData victim = null;

            if (!ch.IsClass(CharClass.Names.bard))
                switch (spell.ValidTargets)
                {
                    default:
                        Log.Error("Magic.Cast: bad target type for spell {0}.  Type is: {1}", spell.Name, spell.ValidTargets.ToString());
                        return;
                    case TargetType.none:
                        target = new Target(argument);
                        break;
                    case TargetType.singleCharacterWorld:
                        victim = ch.GetCharWorld(argument);
                        if (victim == null)
                        {
                            ch.SendText("Cast the spell on whom?\r\n");
                            return;
                        }
                        target = new Target(victim);
                        break;
                    case TargetType.trap:
                        ch.SendText("You cannot cast a trap!\r\n");
                        return;
                    case TargetType.singleCharacterOffensive:
                        if (String.IsNullOrEmpty(argument))
                        {
                            victim = ch.Fighting;
                            if (victim == null)
                            {
                                if (ch.IsClass(CharClass.Names.psionicist))
                                    ch.SendText("Will the spell upon whom?\r\n");
                                else
                                    ch.SendText("Cast the spell upon whom?\r\n");
                                return;
                            }
                        }
                        else
                        {
                            victim = ch.GetCharRoom(argument);
                            if (!victim)
                            {
                                ch.SendText("They aren't here.\r\n");
                                return;
                            }
                        }

                        if (ch.IsAffected( Affect.AFFECT_CHARM) && ch.Master == victim)
                        {
                            ch.SendText("You can't do that to your master!.\r\n");
                            return;
                        }

                        if (Combat.IsSafe(ch, victim))
                            return;
                        // Combat.IsSafe could wipe out victim, as it calls procs if a boss
                        // check and see that victim is still valid
                        if (!victim)
                            return;

                        Crime.CheckAttemptedMurder(ch, victim);
                        target = new Target(victim);
                        ch.BreakInvisibility();
                        break;

                    case TargetType.singleCharacterDefensive:
                        if (String.IsNullOrEmpty(argument))
                        {
                            victim = ch;
                        }
                        else
                        {
                            victim = ch.GetCharRoom(argument);
                            if (victim == null)
                            {
                                ch.SendText("They aren't here.\r\n");
                                return;
                            }
                        }

                        target = new Target(victim);
                        break;

                    case TargetType.self:
                        if (!String.IsNullOrEmpty(argument) && !MUDString.NameContainedIn(argument, ch.Name) &&
                                "me".Equals(argument, StringComparison.CurrentCultureIgnoreCase) &&
                                "self".Equals(argument, StringComparison.CurrentCultureIgnoreCase))
                        {
                            ch.SendText("You cannot cast this spell on another.\r\n");
                            return;
                        }

                        target = new Target(ch);
                        break;

                    case TargetType.objectInInventory:
                        if (String.IsNullOrEmpty(argument))
                        {
                            ch.SendText("What item should the spell be cast upon?\r\n");
                            return;
                        }

                        obj = ch.GetObjCarrying(argument);
                        if (obj == null)
                        {
                            ch.SendText("You are not carrying that.\r\n");
                            return;
                        }

                        target = new Target(obj);
                        break;

                    case TargetType.objectInRoom:
                        if (String.IsNullOrEmpty(argument))
                        {
                            ch.SendText("What should the spell be cast upon?\r\n");
                            return;
                        }

                        obj = ch.GetObjHere(argument);
                        if (obj == null)
                        {
                            ch.SendText("You do not see that here.\r\n");
                            return;
                        }

                        target = new Target(obj);
                        break;

                    case TargetType.objectCorpse:
                        target = new Target(argument);
                        break;
                    case TargetType.objectOrCharacter:
                        if (String.IsNullOrEmpty(argument))
                        {
                            if (ch.Fighting != null)
                                victim = ch.Fighting;
                            else
                            {
                                ch.SendText("Cast upon what?\r\n");
                                return;
                            }
                        }
                        else if (!(victim = ch.GetCharRoom(argument)))
                        {
                            obj = ch.GetObjHere(argument);
                        }

                        if (victim != null)
                        {
                            target = new Target(victim);
                        }
                        else if (obj != null)
                        {
                            target = new Target(obj);
                        }
                        else
                        {
                            ch.SendText("You do not see that here.\r\n");
                            return;
                        }

                        break;
                    case TargetType.singleCharacterRanged:
                        if (String.IsNullOrEmpty(argument))
                        {
                            victim = ch.Fighting;
                            if (victim == null)
                            {
                                ch.SendText("Cast the spell on whom?\r\n");
                                return;
                            }
                        }
                        else
                        {
                            victim = ch.GetCharRoom(argument);
                            if (!victim)
                            {
                                ch.SendText("They aren't here.\r\n");
                                return;
                            }
                            // Ranged combat.
                            //
                            // TODO: FIXME: The next line does not successfully get the required argument.
                            //int dir = Movement.FindExit(ch, arg3);
                            //if (ch._level >= Limits.LEVEL_IMMORTAL)
                            //{
                            //    buf = String.Format("Looking for {0} to the {1}.\r\n", arg2, arg3);
                            //    ch.SendText(buf);
                            //}
                            //if (ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.walled)
                            //        || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.blocked)
                            //        || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.secret)
                            //        || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.closed)
                            //        || !ch._inRoom._exitData[dir]._targetRoom
                            //        || ch._inRoom._area != ch._inRoom._exitData[dir]._targetRoom._area)
                            //{
                            //    ch.SendText("You see nothing in that direction.\r\n");
                            //    return;
                            //}
                            //room2 = Movement.FindRoom(ch, arg3);
                            //if (room2 == null)
                            //{
                            //    ch.SendText("You see nothing in that direction.\r\n");
                            //    return;
                            //}
                            //victim = CharData.GetCharAtRoom(room2, ch, arg2);
                            //if (victim == null)
                            //{
                            //    Room room3;
                            //    if (room2._exitData[dir] && ((room3 = Room.GetRoom(room2._exitData[dir]._vnum))) &&
                            //        spell == Spell.SpellList["fireball"])
                            //    {
                            //        victim = CharData.GetCharAtRoom(room3, ch, arg2);
                            //    }
                            //}
                            //if (victim == null)
                            //{
                            //    ch.SendText("They aren't here.\r\n");
                            //    return;
                            //}
                            //} //end else
                        } //end else
                        if (ch.IsAffected(Affect.AFFECT_CHARM) && ch.Master == victim)
                        {
                            ch.SendText("You can't do that to your master!.\r\n");
                            return;
                        }

                        if (Combat.IsSafe(ch, victim))
                            return;
                        // Combat.IsSafe could wipe out victim, as it calls procs if a boss
                        // check and see that victim is still valid
                        if (!victim)
                            return;

                        Crime.CheckAttemptedMurder(ch, victim);

                        target = new Target(victim);
                        ch.BreakInvisibility();
                        break;
                }

            int beats = 0;  // For quick chant
            if (!ch.IsClass(CharClass.Names.bard) && !ch.IsClass(CharClass.Names.psionicist))
            {
                ch.SendText( "You begin casting...\r\n" );
                if( "ventriloquate".Equals(spell.Name, StringComparison.CurrentCultureIgnoreCase ))
                {
                    if( spell.ValidTargets == TargetType.singleCharacterOffensive
                            || spell.ValidTargets == TargetType.singleCharacterRanged )
                        SocketConnection.Act( "$n&n begins casting an offensive spell...", ch, null, null, SocketConnection.MessageTarget.room );
                    else
                        SocketConnection.Act( "$n&n begins casting...", ch, null, null, SocketConnection.MessageTarget.room );
                }
                beats = spell.CastingTime;
            }
            else if (ch.IsClass(CharClass.Names.bard))
            {
                ch.SendText( "You begin singing...\r\n" );
                SocketConnection.Act( "$n&n starts singing...", ch, null, null, SocketConnection.MessageTarget.room );
                beats = 0;
            }

            if (!ch.IsClass(CharClass.Names.psionicist) && !ch.IsClass(CharClass.Names.bard))
            {
                // Characters with int of 110 have normal memtimes.
                // int of 100 worsens casting times by 10%
                // with an int of 55 casting times are doubled.
                // This may seem a bit harsh, but keep in mind any
                // casters are very likely to have an int above 100, as it
                // is their prime requisite.  120 is the max int for Grey Elves
                // to start.
                if (ch.IsClass(CharClass.Names.cleric) || ch.IsClass(CharClass.Names.druid)
                        || ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin))
                {
                    beats = ( beats * 110 ) / ch.GetCurrWis();
                }
                else if (ch.IsClass( CharClass.Names.shaman))
                {
                    beats = ( beats * 330 ) / ( ch.GetCurrInt() + ( ch.GetCurrWis() * 2 ) );
                }
                else
                {
                    beats = ( beats * 110 ) / ch.GetCurrInt();
                }

                if( ch.CheckSkill("quick chant", PracticeType.only_on_success) )
                {
                    beats = beats / 2;
                }

                /*
                * A check for impossibly long cast times...came about from a player
                * trying to cast when feebleminded.  100 casting time is arbitrary.
                */
                if( beats > 100 )
                {
                    ch.SendText( "Forget it!  In your present state you haven't a dream of success.\r\n" );
                    return;
                }
                ch.WaitState( beats );

                if( CheckHypnoticPattern( ch ) )
                {
                    return;
                }

                CastData caster = new CastData();
                caster.Who = ch;
                caster.Eventdata = Event.CreateEvent( Event.EventType.spell_cast, beats, ch, target, spell );
                Database.CastList.Add( caster );
                ch.SetAffectBit( Affect.AFFECT_CASTING );
            }
            else if (ch.IsClass( CharClass.Names.psionicist))
            {
                ch.WaitState( beats );

                if( CheckHypnoticPattern( ch ) )
                {
                    return;
                }

                ch.PracticeSpell( spell );

                int mana = 0;
                if( !ch.IsImmortal() && !ch.IsNPC()
                        && ch.Level < ( spell.SpellCircle[ (int)ch.CharacterClass.ClassNumber ] * 4 + 1 )
                        && MUDMath.NumberPercent() > ((PC)ch).SpellAptitude[spell.Name])
                {
                    ch.SendText( "You lost your concentration.\r\n" );
                    SocketConnection.Act( "&+r$n&n&+r's face flushes white for a moment.&n", ch, null, null, SocketConnection.MessageTarget.room );
                    ch.CurrentMana -= mana / 2;
                }
                else
                {
                    ch.CurrentMana -= mana;
                    string buf = String.Format( "Spell {0} ({1}) being willed by {2}", spell,
                                                spell.Name, ch.Name );
                    Log.Trace( buf );
                    ch.SetAffectBit( Affect.AFFECT_CASTING );
                    FinishSpell( ch, spell, target );
                }
                if( ch.CurrentPosition > Position.sleeping && ch.CurrentMana < 0 )
                {
                    ch.WaitState( 2 * Event.TICK_PER_SECOND );
                    ch.SendText( "&+WThat last spe&+wll w&+Las a _bitvector&+l much...&n\r\n" );
                    ch.CurrentPosition = Position.standing;
                    ch.Fighting = null;
                    SocketConnection.Act( "$n&n collapses from exhaustion&n.",
                         ch, null, null, SocketConnection.MessageTarget.room );
                    ch.CurrentPosition = Position.sleeping;
                }

                if( spell.ValidTargets == TargetType.singleCharacterOffensive
                        && victim && victim.Master != ch && victim != ch && victim.IsAwake() )
                {
                    foreach( CharData roomChar in ch.InRoom.People )
                    {
                        if( victim == roomChar && !victim.Fighting )
                        {
                            victim.AttackCharacter( ch );
                            break;
                        }
                    }
                }
            }
            else if( ch.IsClass(CharClass.Names.bard ))
            {
                ch.WaitState( 0 );

                // Create an event to handle the spell
                CastData caster = new CastData();
                caster.Who = ch;
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG, ch, target, spell );
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 2, ch, target, spell);
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 3, ch, target, spell);
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 4, ch, target, spell);
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 5, ch, target, spell);
                Database.CastList.Add( caster );
                ch.SetAffectBit( Affect.AFFECT_SINGING );
            }
            return;
        }