Exemple #1
0
        /// <summary>
        /// Eat something.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Eat(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj;

            if (ch.IsBlind())
                return;

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

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

            if (!(obj = ch.GetObjCarrying(str[0])))
            {
                ch.SendText("You do not have that item.\r\n");
                return;
            }

            if (!ch.IsImmortal())
            {
                if (obj.ItemType != ObjTemplate.ObjectType.food && obj.ItemType != ObjTemplate.ObjectType.pill)
                {
                    ch.SendText("That's not edible.\r\n");
                    return;
                }

                if (!ch.IsNPC() && ((PC)ch).Hunger > 40)
                {
                    ch.SendText("You are too full to eat more.\r\n");
                    return;
                }
            }

            SocketConnection.Act("You consume $p&n.", ch, obj, null, SocketConnection.MessageTarget.character);
            SocketConnection.Act("$n&n inhales $p&n.", ch, obj, null, SocketConnection.MessageTarget.room);

            switch (obj.ItemType)
            {

                case ObjTemplate.ObjectType.food:
                    if (!ch.IsNPC())
                    {
                        int condition = ((PC)ch).Hunger;
                        if (!ch.IsUndead())
                        {
                            ch.AdjustHunger(obj.Values[0]);
                        }
                        if (((PC)ch).Hunger > 40)
                        {
                            ch.SendText("You are full.\r\n");
                        }
                        else if (condition == 0 && ((PC)ch).Hunger > 0)
                        {
                            ch.SendText("You are no longer hungry.\r\n");
                        }
                    }

                    if (obj.Values[3] != 0 && !CharData.CheckImmune(ch, Race.DamageType.poison))
                    {
                        /* The shit was poisoned! */
                        Affect af = new Affect();

                        SocketConnection.Act("$n chokes and gags.", ch, null, null, SocketConnection.MessageTarget.room);
                        ch.SendText("You choke and gag.\r\n");

                        af.Type = Affect.AffectType.spell;
                        af.Value = "poison";
                        af.Duration = 2 * obj.Values[0];
                        af.AddModifier(Affect.Apply.strength, -(obj.Level / 7 + 2));
                        af.SetBitvector(Affect.AFFECT_POISON);
                        ch.CombineAffect(af);
                    }
                    break;

                case ObjTemplate.ObjectType.pill:
                    {
                        for (int i = 1; i <= 4; i++)
                        {
                            String spellName = SpellNumberToTextMap.GetSpellNameFromNumber(obj.Values[i]);
                            if (String.IsNullOrEmpty(spellName))
                            {
                                Log.Error("Eat: Spell number " + obj.Values[i] + " not found for pill object " + obj.ObjIndexNumber + ". Make sure it's in the SpellNumberToTextMap.");
                            }
                            Spell spell = StringLookup.SpellLookup(spellName);
                            if (!spell)
                            {
                                Log.Error("Eat: Spell '" + spellName + "' not found for pill object " + obj.ObjIndexNumber + ". Make sure it's in the spells file.");
                            }
                            else
                            {
                                spell.Invoke(ch, obj.Values[0], ch);
                            }
                        }
                    }
                    break;
            }

            if (!ch.IsNPC() || (ch.IsNPC() && ch.IsAffected(Affect.AFFECT_CHARM)))
            {
                obj.RemoveFromWorld();
            }
            return;
        }
Exemple #2
0
        /// <summary>
        /// Shows available room exits.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Exits(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Exit exit;
            int door;

            bool auto = (str.Length != 0 && !MUDString.StringsNotEqual(str[0], "auto"));

            if (ch.IsBlind() || !ch.InRoom)
            {
                return;
            }

            string text;
            if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED && auto)
            {
                text = "<exits>";
            }
            else
            {
                text = auto ? "&+cExits: &n" : "&+cVisible exits:&n\r\n";
            }

            bool found = false;

            // Show the direction with an asterisk if it
            // has a closed door, and in exits command it shows up as a
            // closed <whatever>.
            for (door = 0; door < Limits.MAX_DIRECTION; ++door)
            {
                exit = ch.InRoom.ExitData[door];
                if (exit && exit.TargetRoom)
                {
                    if (exit.HasFlag(Exit.ExitFlag.secret))
                    {
                        /* Mortals do not see secret exits. */
                        if (ch.Level < Limits.LEVEL_AVATAR)
                            continue;
                        /* Mark secret exits for immortals. */
                        text += "&+LS&n&+c";
                    }
                    if (exit.HasFlag(Exit.ExitFlag.blocked))
                    {
                        /* Mortals do not see secret exits. */
                        if (ch.Level < Limits.LEVEL_AVATAR)
                            continue;
                        /* Mark secret exits for immortals. */
                        text += "&+yB&n&+c";
                    }
                    found = true;
                    if (auto)
                    {
                        if (exit.HasFlag(Exit.ExitFlag.walled) && exit.HasFlag(Exit.ExitFlag.illusion))
                            continue;
                        if (exit.HasFlag(Exit.ExitFlag.closed))
                            text += "&n&+y#&n&+c";
                        // Don't show exits to impassable rooms.
                        // Show a yellow exclamation point to those with holylight on though.
                        if (exit.TargetRoom && exit.TargetRoom.TerrainType == TerrainType.underground_impassable)
                        {
                            if (!ch.HasActionBit(PC.PLAYER_GODMODE))
                            {
                                continue;
                            }
                            text += "&+Y!&n";
                        }
                        text += door.ToString();
                        text += " ";
                    }
                    else
                    {
                        if (exit.HasFlag(Exit.ExitFlag.walled))
                        {
                            text += String.Format("&n{0} - (Walled)&n\r\n",
                                MUDString.PadStr(door.ToString().ToUpper(), 5));
                        }
                        else if (!exit.HasFlag(Exit.ExitFlag.closed))
                        {
                            // gods with holylight on can go to useless exits.
                            if (exit.TargetRoom && exit.TargetRoom.TerrainType == TerrainType.underground_impassable)
                            {
                                if (!ch.HasActionBit(PC.PLAYER_GODMODE))
                                {
                                    continue;
                                }
                                text += "&+Y!&n";
                            }
                            text += String.Format("&n {0} - {1}&n\r\n", MUDString.PadStr(door.ToString().ToUpper(), 5),
                                    (!ch.HasInnate(Race.RACE_ULTRAVISION) && Room.GetRoom(exit.IndexNumber).IsDark())
                                      ? "&nToo dark to tell" : exit.TargetRoom.Title);
                        }
                        else
                        {
                            text += String.Format("&+y#&n{0} - Closed {1}\r\n",
                                MUDString.PadStr(door.ToString().ToUpper(), 5), exit.Keyword);
                        }
                    }
                }
            }

            if (!found)
            {
                text += auto ? " none" : "&nNone.\r\n";
            }

            if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED && auto)
            {
                text += "&n</exits>";
            }
            else if (auto)
            {
                text += "&n\r\n";
            }

            ch.SendText(text);
            return;
        }
Exemple #3
0
        /// <summary>
        /// Assist someone in combat by joining them against their primary target.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Assist(CharData ch, string[] str)
        {
            if( ch == null ) return;

            CharData victim;

            if (!ch.IsBlind())
            {
                ch.SendText("You can't assist the invisible.\r\n");
                return;
            }
            if (ch.Fighting)
            {
                ch.SendText("You're a bit busy at the moment.\r\n");
                return;
            }

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

            if (victim == ch)
            {
                ch.SendText("You're too busy assisting yourself to assist yourself.\r\n");
                return;
            }

            if (!victim.Fighting)
            {
                ch.SendText("They're not fighting anyone.\r\n");
                return;
            }

            if (victim.Fighting == ch)
            {
                ch.SendText("Assist!? They're fighting YOU, fool!\r\n");
                return;
            }

            SocketConnection.Act("You scream a battle cry, and assist $N&n heroically.", ch, null, victim, SocketConnection.MessageTarget.character);
            SocketConnection.Act("$n&n leaps into the fray, valiantly assisting you.", ch, null, victim, SocketConnection.MessageTarget.victim);
            SocketConnection.Act("$n&n charges into battle and assists $N&n heroically.", ch, null, victim, SocketConnection.MessageTarget.room_vict);

            Combat.SingleAttack(ch, victim.Fighting, String.Empty, ObjTemplate.WearLocation.hand_one);

            return;
        }
Exemple #4
0
        /// <summary>
        /// Ingest a liquid.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Drink(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj = null;

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

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

            if (str.Length == 0 && ch.InRoom != null)
            {
                foreach (Object iobj in ch.InRoom.Contents)
                {
                    if (iobj.ItemType == ObjTemplate.ObjectType.drink_container)
                    {
                        obj = iobj;
                        break;
                    }
                }

                if (!obj)
                {
                    ch.SendText("Drink what?\r\n");
                    return;
                }
            }
            else
            {
                if (!(obj = ch.GetObjHere(str[0])))
                {
                    ch.SendText("You can't find it.\r\n");
                    return;
                }
            }

            // Allow bards to get twice as drunk as other classes - Xangis
            if (!ch.IsNPC() && !ch.IsImmortal()
                    && ((PC)ch).Drunk > 15 && ch.IsClass(CharClass.Names.bard)
                    && MUDMath.NumberPercent() < ch.GetCurrAgi() - ((PC)ch).Drunk)
            {
                ch.SendText("You fail to reach your mouth.  *Hic*\r\n");
                return;
            }
            if (!ch.IsNPC() && !ch.IsImmortal()
                && ((PC)ch).Drunk > 25 && ch.IsClass(CharClass.Names.bard)
                && MUDMath.NumberPercent() < ch.GetCurrAgi() - ((PC)ch).Drunk)
            {
                ch.SendText("You fail to reach your mouth.  *Hic*\r\n");
                return;

            }

            switch (obj.ItemType)
            {
                default:
                    ch.SendText("You can't drink from that.\r\n");
                    break;

                case ObjTemplate.ObjectType.drink_container:
                    // -1 Means a container never goes empty.
                    if (obj.Values[1] <= 0 && obj.Values[1] != -1)
                    {
                        ch.SendText("It is already &+Lempty&n.\r\n");
                        return;
                    }

                    /* No drinking if you're full */
                    if ((!ch.IsImmortal()) && (
                                (!ch.IsNPC() && ((PC)ch).Thirst > 40) ||
                                (!ch.IsNPC() && ((PC)ch).Hunger > 50)))
                    {
                        ch.SendText("You couldn't possibly drink any more.\r\n");
                        return;
                    }

                    int liquid;
                    if ((liquid = obj.Values[2]) >= Liquid.Table.Length)
                    {
                        Log.Error("Drink: bad liquid number {0}.", liquid);
                        liquid = obj.Values[2] = 0;
                    }

                    SocketConnection.Act("You drink $T from $p&n.",
                         ch, obj, Liquid.Table[liquid].Name, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n drinks $T from $p&n.",
                         ch, obj, Liquid.Table[liquid].Name, SocketConnection.MessageTarget.room);

                    int amount = MUDMath.NumberRange(3, 10);
                    if (obj.Values[0] != -1)
                    {
                        amount = Math.Min(amount, obj.Values[1]);
                    }

                    ch.AdjustDrunk(amount * Liquid.Table[liquid].DrunkValue);

                    if (!ch.IsUndead())
                    {
                        ch.AdjustHunger(amount * Liquid.Table[liquid].HungerValue);
                        if (ch.IsAffected(Affect.AFFECT_THIRST))
                        {
                            ch.AdjustThirst((amount * Liquid.Table[liquid].ThirstValue) / 12);
                            ch.SendText("That doesn't taste as &+bwet&n as it used to.\r\n");
                        }
                        else
                        {
                            ch.AdjustThirst(amount * Liquid.Table[liquid].ThirstValue);
                        }
                    }
                    else
                    {
                        /* If blood */
                        if (Liquid.Table[liquid].Name == "blood")
                        {
                            ch.AdjustHunger(amount * 2);
                            ch.AdjustThirst(amount);
                        }
                    }

                    if (!ch.IsNPC() && ((PC)ch).Drunk > 10)
                    {
                        ch.SendText("You feel &n&+gdrunk&n.\r\n");
                    }
                    if (!ch.IsNPC() && ((PC)ch).Hunger > 20)
                    {
                        ch.SendText("You are &n&+yfull&n.\r\n");
                    }
                    if (!ch.IsNPC() && ((PC)ch).Thirst > 20)
                    {
                        ch.SendText("You do not feel &n&+cth&+Ci&n&+cr&+Cst&n&+cy&n.\r\n");
                    }

                    if (obj.Values[3] != 0 && !CharData.CheckImmune(ch, Race.DamageType.poison))
                    {
                        /* The shit was poisoned ! */
                        Affect af = new Affect();

                        ch.SendText("You choke and gag.\r\n");
                        SocketConnection.Act("$n chokes and gags.", ch, null, null, SocketConnection.MessageTarget.room);
                        af.Type = Affect.AffectType.spell;
                        af.Value = "poison";
                        af.Duration = 3 * amount;
                        af.AddModifier(Affect.Apply.strength, -(obj.Level / 7 + 1));
                        af.SetBitvector(Affect.AFFECT_POISON);
                        ch.CombineAffect(af);
                    }

                    /* HOLY_WATER and UNHOLY_WATER effects */
                    if ((ch.IsGood() && obj.Values[2] == 27) ||
                            (ch.IsEvil() && obj.Values[2] == 28))
                    {
                        int heal = MUDMath.Dice(1, 8);
                        if (ch.Hitpoints < ch.GetMaxHit())
                        {
                            ch.Hitpoints = Math.Min(ch.Hitpoints + heal, ch.GetMaxHit());
                            ch.UpdatePosition();
                            ch.SendText("You feel a little better!\r\n");
                        }
                    }
                    if ((ch.IsEvil() && obj.Values[2] == 27) ||
                            (ch.IsGood() && obj.Values[2] == 28))
                    {
                        int harm = MUDMath.Dice(1, 10);
                        ch.Hitpoints = Math.Max(ch.Hitpoints - harm, -10);
                        ch.SendText("You choke and feel as if you'd swallowed boiling oil!\r\n");
                        ch.UpdatePosition();
                    }
                    /* End (UN)HOLY_WATER effects */

                    // -1 Means a container never goes empty.
                    if (obj.Values[1] != -1)
                    {
                        obj.Values[1] -= amount;
                        if (obj.Values[1] <= 0)
                        {
                            ch.SendText("The container is now &+Lempty&n.\r\n");
                            obj.Values[1] = 0;
                        }
                    }
                    break;
            }

            return;
        }
Exemple #5
0
        /// <summary>
        /// Kick someone.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Kick(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int chance;
            int wallkickchance;

            /* Check player's level and class, allow mobs to do this too */
            if ((!ch.HasSkill("kick")))
            {
                ch.SendText("You'd better leave the martial arts to fighters.\r\n");
                return;
            }

            if (ch.IsBlind() && !ch.Fighting)
            {
                return;
            }

            CharData victim = ch.Fighting;

            if (str.Length != 0)
            {
                victim = ch.GetCharRoom(str[0]);
                if (!victim || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("They aren't here.\r\n");
                    return;
                }
            }
            else
            {
                if (!victim || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("You aren't fighting anyone.\r\n");
                    return;
                }
            }

            if (victim == ch)
            {
                ch.SendText("You kick yourself for being a dummy.\r\n");
                return;
            }

            ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["kick"].Delay));

            if (!ch.IsNPC())
            {
                chance = ((PC)ch).SkillAptitude["kick"];
                ch.PracticeSkill("kick");
            }
            else
            {
                chance = ch.Level * 3 / 2 + 20;
            }
            // It's much harder to kick really tiny things; imagine trying to kick
            // a fly.
            if (ch.CurrentSize > victim.CurrentSize + 5)
            {
                chance -= (ch.CurrentSize - victim.CurrentSize) * 5;
            }

            // It's harder to kick things that move faster than you.
            chance += ((ch.GetCurrAgi() - victim.GetCurrAgi()) / 5);

            // Huge bonus against incapacitated and mortally wounded foes.
            if (victim.CurrentPosition <= Position.incapacitated)
            {
                chance += 50;
            }

            // Damned high penalty for kicking blind
            if (ch.IsAffected(Affect.AFFECT_BLIND) && !victim.IsAffected(Affect.AFFECT_BLIND))
            {
                chance /= 10;
            }
            if (ch.IsAffected(Affect.AFFECT_BLIND) && victim.IsAffected(Affect.AFFECT_BLIND))
            {
                chance /= 4;
            }

            // If the victim is two or more sizes smaller than the kicker give them a chance
            // to be kicked into a wall or out of the room.
            //
            // Chance of 5% per size class difference, no maximum
            // (wall/room kick is 50% at a difference of 10 sizes)
            if (victim.CurrentSize - 1 >= ch.CurrentSize)
            {
                wallkickchance = 0;
            }
            else
            {
                wallkickchance = ((ch.CurrentSize - victim.CurrentSize) * 5) - 5;
            }

            // Check for kick success
            if (MUDMath.NumberPercent() < chance)
            {
                /* Check for wall kick. */
                /* to be kicked out of the room (random direction). */
                if (MUDMath.NumberPercent() < wallkickchance)
                {
                    Exit.Direction door = Database.RandomDoor();

                    // Check for valid room stuff on victim
                    Room kickedInto;
                    Exit exit;
                    if (victim && victim.InRoom && victim.InRoom.ExitData != null
                        && (exit = victim.InRoom.GetExit(door))
                        && exit.TargetRoom
                        && exit.ExitFlags != 0
                        && !exit.HasFlag(Exit.ExitFlag.secret)
                        && !exit.HasFlag(Exit.ExitFlag.blocked)
                        && !exit.HasFlag(Exit.ExitFlag.walled)
                        && exit.HasFlag(Exit.ExitFlag.closed)
                        && !Room.GetRoom(exit.IndexNumber).IsPrivate()
                        && exit.TargetRoom.TerrainType != TerrainType.underground_impassable
                        && (kickedInto = Room.GetRoom(exit.IndexNumber)))
                    {
                        Combat.StopFighting(victim, true);
                        string buf = String.Format("$N&n is sent flying out of the room {0}ward by $n&n's mighty kick.", door.ToString());
                        SocketConnection.Act(buf, ch, null, victim, SocketConnection.MessageTarget.room_vict);
                        buf = String.Format("$N&n is sent flying out of the room {0}ward by your mighty kick.", door.ToString());
                        SocketConnection.Act(buf, ch, null, victim, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("You are sent flying out of the room by $n's mighty kick!", ch, null, victim, SocketConnection.MessageTarget.victim);
                        victim.RemoveFromRoom();
                        victim.AddToRoom(kickedInto);

                        SocketConnection.Act("$n&n is stunned!", victim, null, null, SocketConnection.MessageTarget.room);
                        victim.SendText("You are stunned!\r\n");
                        victim.WaitState((Skill.SkillList["kick"].Delay * 9) / 10);
                        if (victim.CurrentPosition > Position.resting)
                        {
                            victim.CurrentPosition = Position.resting;
                        }
                    }
                    else
                    {
                        // If no exit in our chosen direction, must be a wall.
                        SocketConnection.Act("$N&n is sent flying into the wall by $n&n's mighty kick.", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                        SocketConnection.Act("$N&n is sent flying into the wall by your mighty kick.", ch, null, victim, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("You are smacked into the wall by $n's mighty kick!", ch, null, victim, SocketConnection.MessageTarget.victim);
                        if (victim.CurrentPosition > Position.resting)
                        {
                            victim.CurrentPosition = Position.resting;
                        }
                        // At least a two second stun
                        victim.WaitState(8);
                        /* Check for stunning victim. */
                        if ((MUDMath.NumberPercent() * 2) > victim.GetCurrAgi())
                        {
                            SocketConnection.Act("$N&n is stunned!", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                            victim.SendText("You are stunned!\r\n");
                            victim.WaitState((Skill.SkillList["kick"].Delay * 9) / 10);
                        }
                        else
                        {
                            victim.WaitState(1);
                        }
                    }
                    // Do excessive damage compared to a normal kick
                    Combat.InflictDamage(ch, victim, MUDMath.Dice(2, ch.Level), String.Empty, ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);

                } // Check for wall kick (execute regular kick)
                else
                {
                    Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, ch.Level), "kick", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                }
            } // Check for successful kick (missed kick)
            else
            {
                Combat.InflictDamage(ch, victim, 0, "kick", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
            }

            return;
        }
Exemple #6
0
        /// <summary>
        /// Throw dirt in someone's eyes.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void DirtToss(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int percent;

            /* Don't allow the unskilled to do this, check player's level */
            if (!ch.HasSkill("dirt toss"))
            {
                ch.SendText("You get your feet dirty.\r\n");
                return;
            }

            if (ch.IsBlind())
            {
                ch.SendText("You can't see anything!\r\n");
                return;
            }

            if (ch.FlightLevel != 0)
            {
                ch.SendText("Perhaps you should land first matey.\r\n");
                return;
            }

            CharData victim = ch.Fighting;

            if (str.Length != 0)
            {
                if (!(victim = ch.GetCharRoom(str[0])) || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("They aren't here.\r\n");
                    return;
                }
            }
            if (!victim || victim.CurrentPosition == Position.dead)
            {
                ch.SendText("You aren't fighting anyone.\r\n");
                return;
            }

            if (victim == ch)
            {
                ch.SendText("How about sticking a fork your eye instead?\r\n");
                return;
            }

            if (victim.IsAffected( Affect.AFFECT_BLIND))
            {
                SocketConnection.Act("$E's already been &+Lblinded&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                return;
            }

            if (!ch.IsNPC())
            {
                percent = ((PC)ch).SkillAptitude["dirt toss"];
            }
            else
            {
                percent = (ch.Level * 3) / 2 + 25;
            }

            percent += (ch.Level - victim.Level) * 2;
            percent += (ch.GetCurrDex() / 10);
            percent -= (victim.GetCurrDex() / 10);
            percent -= (victim.GetCurrAgi() / 10);

            // Why waste time listing sectors with no modifier?
            switch (ch.InRoom.TerrainType)
            {
                case TerrainType.inside:
                case TerrainType.arctic:
                case TerrainType.swamp:
                    percent -= 20;
                    break;
                case TerrainType.city:
                case TerrainType.mountain:
                    percent -= 10;
                    break;
                case TerrainType.plane_of_fire:
                case TerrainType.plane_of_air:
                case TerrainType.plane_of_water:
                case TerrainType.plane_ethereal:
                case TerrainType.plane_astral:
                case TerrainType.underwater_has_ground:
                case TerrainType.underwater_no_ground:
                case TerrainType.swimmable_water:
                case TerrainType.unswimmable_water:
                case TerrainType.air:
                case TerrainType.ocean:
                case TerrainType.underground_swimmable_water:
                case TerrainType.underground_unswimmable_water:
                    percent = 0;
                    break;
                case TerrainType.field:
                    percent += 5;
                    break;
                case TerrainType.desert:
                    percent += 10;
                    break;
                case TerrainType.plane_of_earth:
                    percent += 15;
                    break;
                default:
                    break;
            }

            if (percent > 75)
            {
                percent = 75;
            }
            else if (percent < 5)
            {
                percent = 5;
            }

            if (percent <= 0)
            {
                ch.SendText("There isn't any &n&+ydirt&n to kick.\r\n");
                return;
            }

            ch.PracticeSkill("dirt toss");

            if (percent < MUDMath.NumberPercent())
            {
                Affect af = new Affect();

                SocketConnection.Act("$n is &+Lblinded&n by the &n&+ydirt&n in $s eyes!", victim, null, null,
                     SocketConnection.MessageTarget.room);
                SocketConnection.Act("$n kicks &n&+ydirt&n into your eyes!", ch, null, victim, SocketConnection.MessageTarget.victim);

                victim.SendText("&+LYou can't see a thing!&n\r\n");

                af.Value = "dirt toss";
                af.Type = Affect.AffectType.skill;
                af.Duration = MUDMath.NumberRange(1, 2);
                af.AddModifier(Affect.Apply.hitroll, -4);
                af.SetBitvector(Affect.AFFECT_BLIND);
                victim.AddAffect(af);

            }
            else
            {
                ch.SendText("&+LYou kick dirt at your target!&n\r\n");
            }

            Combat.SetFighting(victim, ch);

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

            return;
        }
Exemple #7
0
        /// <summary>
        /// Attempt to trip a foe.  Can initiate combat with this and can use during combat.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Trip(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int chance;

            /* Check player's level and class, mobs can use this skill */
            if ((!ch.HasSkill("trip")))
            {
                ch.SendText("You would just fall over if you tried to trip someone.\r\n");
                return;
            }

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

            CharData victim = ch.Fighting;

            if (str.Length != 0)
            {
                victim = ch.GetCharRoom(str[0]);
                if (!victim)
                {
                    ch.SendText("You look around, unable to find them.\r\n");
                    return;
                }
            }
            else
            {
                if (!victim)
                {
                    ch.SendText("You aren't fighting anyone.\r\n");
                    return;
                }
            }

            /* anti 'trip me' code */
            if (victim == ch)
            {
                ch.SendText("You don't think you're clumsy enough already?\r\n");
                return;
            }

            ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["trip"].Delay));
            ch.PracticeSkill("trip");

            if (ch.IsNPC())
            {
                chance = (ch.Level * 3) / 2 + 10;
            }
            else
            {
                chance = ((PC)ch).SkillAptitude["trip"];
            }

            if (chance > 90)
            {
                chance = 90;
            }

            if ((ch.Fighting == null) && (ch != victim))
            {
                Combat.SetFighting(ch, victim);
            }
            if ((!victim.Fighting) && (victim != ch))
            {
                Combat.SetFighting(victim, ch);
            }

            /* Mobs do NOT auto-trip! */
            if (MUDMath.NumberPercent() < chance)
            {
                victim.WaitState((Skill.SkillList["trip"].Delay * 5 / 6));
                SocketConnection.Act("You trip $N&n and send $M sprawling to the &n&+yearth&n!", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n trips you and you go down!", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n trips $N&n and $E falls face-first to the &n&+yground&n!", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                if (victim.CurrentPosition > Position.reclining)
                {
                    victim.CurrentPosition = Position.reclining;
                }
            }
            else
            {
                SocketConnection.Act("You try to trip $N&n and fall down!", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n attempts to knock you from your feet, and falls down $sself!", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n tries to trip $N&n and tumbles to the &n&+yground&n!", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                ch.CurrentPosition = Position.reclining;
            }

            return;
        }
Exemple #8
0
        /*
        * Modified to up the damage and allow for a
        * chance to stun victim or self
        *   damage = (level) d2, for an average of 75 hp at level 50
        *   stun damage = (level) d3, for an average of 100 hp at level 50
        * Player vs player damage is reduced in damage()
        */
        /// <summary>
        /// Headbutt. Usable to initiate combat and during combat.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Headbutt(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int chance;
            int ko;
            string text;

            /* Check player's level and class, mobs can use this skill */
            if ((!ch.HasSkill("headbutt")))
            {
                ch.SendText("Your skull is much too soft to headbutt anyone.\r\n");
                return;
            }

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

            CharData victim = ch.Fighting;

            if (str.Length != 0)
            {
                if (!(victim = ch.GetCharRoom(str[0])) || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("They are nowhere to be seen.\r\n");
                    return;
                }
            }
            else
            {
                if (!victim || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("You aren't fighting anyone.\r\n");
                    return;
                }
            }

            /* anti headbutt me code */
            if (ch == victim)
            {
                ch.SendText("You get dizzy as you ponder the mechanics of headbutting yourself.\r\n");
                return;
            }

            if (ch.CurrentPosition < Position.fighting)
            {
                ch.SendText("You need to stand up to do that.\r\n");
                return;
            }
            /* Check size of ch vs. victim. */
            /* If ch is too small. */
            /* Made it 2 sizes */
            if (ch.CurrentSize - 2 > victim.CurrentSize)
            {
                SocketConnection.Act("You would crush such a small and delicate being with your mass.", ch, null, victim, SocketConnection.MessageTarget.character);
                return;
            }
            /* Ch 2 or more sizes larger than victim => bad! */
            if (ch.CurrentSize + 1 < victim.CurrentSize)
            {
                SocketConnection.Act("You can't reach their head!", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n slams $s head into your thigh.", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n slams $s head into $N's thigh.", ch, null, victim, SocketConnection.MessageTarget.room_vict);

                ch.WaitState((Skill.SkillList["headbutt"].Delay * 9) / 10);
                if (victim.Fighting == null)
                {
                    Combat.SetFighting(victim, ch);
                }
                return;
            }

            ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["headbutt"].Delay));
            ch.PracticeSkill("headbutt");

            if (!ch.Fighting)
            {
                Combat.SetFighting(ch, victim);
            }
            if (!victim.Fighting)
            {
                Combat.SetFighting(victim, ch);
            }

            /* Added a PC skill level
            */
            // Chance was over-downgraded at some point.  Was skill level - 5%,
            // then it was changed to skill level / 2 giving a level 50 a headbutt
            // success rate of about 47%.  I've upped it to 4/5 of skill level,
            // meaning that a level 50 has a success rate of 76%, which is a good
            // target success rate.  Keep in mind minotaur will have a success rate of
            // about 83%.
            if (ch.IsNPC())
            {
                chance = 50 + ch.Level;
            }
            else
            {
                chance = ((PC)ch).SkillAptitude["headbutt"] * 4 / 5;
            }

            // Minotaur headbutt bonus
            if (ch.GetRace() == Race.RACE_MINOTAUR)
            {
                chance += 7;
            }

            if (victim.CurrentPosition < Position.fighting)
            {
                chance /= 3;
            }

            if (MUDMath.NumberPercent() < chance)
            /*  Headbutt successful, possible KO */
            {
                /* First give the victim a chance to dodge */
                if (Combat.CheckDodge(ch, victim))
                {
                    return;
                }
                /* OK, lets settle for stun right now
                * a skill level of 100% has a 20% chance of stun
                * a skill level of 50% has a 2.5% chance of stun
                * a skill level of 23% has a 1% chance of stun
                * immortals get a 15% bonus
                */
                // The stun math was bad.  Stun was way more often that it should have
                // been.  Now we have a flat /4 chance, meaning a the following stun chances
                // at each skill level:
                // 25 = 5%  50 = 10 %  75 = 15%  95 = 19%
                ko = chance / 4;
                if (ch.IsImmortal())
                {
                    ko += 15;
                }
                text = String.Format("Commandheadbutt: {0}&n attempting a KO with {1}%% chance.", ch.Name, ko);
                ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, text);
                if (MUDMath.NumberPercent() < ko + 1)
                {
                    // deal some decent damage
                    // This was previously level d 3 which was fairly pathetic.
                    // Level d 8 = 50 min, 400 max at level 50 with an average of 225
                    // PvP damage is quartered, so headbutt will do about 56 against a player.
                    if (ch.GetRace() != Race.RACE_MINOTAUR)
                    {
                        Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 8), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                    }
                    else
                    {
                        Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 9), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                    }
                    if (victim.CurrentPosition > Position.stunned)
                    {
                        SocketConnection.Act("$n&n staggers about, then collapses in a heap.", victim, null, null, SocketConnection.MessageTarget.room);
                        victim.SendText("You fall to the ground &+Wstunned&n.\r\n");
                        SocketConnection.Act("$n&n is &+Wstunned!&n", victim, null, null, SocketConnection.MessageTarget.room);
                        victim.CurrentPosition = Position.stunned;
                        victim.WaitState((Skill.SkillList["headbutt"].Delay));
                        text = String.Format("Commandheadbutt: {0}&n stunned {1}&n.", ch.Name, victim.Name);
                        ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, text);
                    }
                }
                else
                {
                    // just your ordinary headbutt damage
                    // This was previously level d 2 which was fairly pathetic.
                    // Level d 6 = 50 min, 300 max at level 50 with an average of 175
                    // PvP damage is quartered, so headbutt will do about 43 against a player.
                    if (ch.GetRace() != Race.RACE_MINOTAUR)
                    {
                        if (!Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 6), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon))
                        {
                            // Someone blasts you in the head it'll definitely stun you for 3/4 of a second.
                            victim.WaitState(3);
                        }
                    }
                    else
                    {
                        if (!Combat.InflictDamage(ch, victim, MUDMath.Dice(ch.Level, 7), "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon))
                        {
                            // Someone blasts you in the head with horns it'll definitely stun you for a second.
                            // -- Xangis
                            victim.WaitState(4);
                        }
                    }
                }
            }
            else /* Headbutt failed, possible damgage to self, possible KO of self */
            {    /* Don't allow char to kill self, just mort self */
                /* Give them a chance to not take any damage */
                // Checking chance instead of player's level.  Since this should be based on skill
                // this should be about right (average of 24% chance of screwing yourself at level 50
                // instead of 50%, 17% chance for minos).
                if (MUDMath.NumberPercent() < chance)
                {
                    ch.SendText("Your headbutt fails to strike its target.\r\n");
                    SocketConnection.Act("$n&n tries to headbutt $N&n but can't quite connect.", ch, null,
                        victim, SocketConnection.MessageTarget.everyone_but_victim);
                    SocketConnection.Act("$n&n bobs around you in a feeble attempt at a headbutt.", ch,
                        null, victim, SocketConnection.MessageTarget.victim);
                    return;
                }
                SocketConnection.Act("You bang your head against the brick wall of $N&n.", ch, null,
                    victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n tries a headbutt but $N&n gets the best of $m.", ch, null,
                    victim, SocketConnection.MessageTarget.everyone_but_victim);
                SocketConnection.Act("$n&n bangs into you in a feeble attempt at a headbutt.", ch,
                    null, victim, SocketConnection.MessageTarget.victim);
                // KO chance of 24% for normals, 17% for minos.
                // You have to fail three checks to get your ass kicked by KO, one for the actual skill check,
                // one for the damage check and finally one for the KO check.
                // keep in mind this KO does damage of about 100 to self at level 50, which is a hell of a lot
                // for a failed skill.
                // The chance of ko'ing yourself at each skill level is as follows: (after all 3 checks)
                // Skill 25 = 59.2%  Skill 50 = 29.6%  Skill 75 = 14.4%  Skill 95 = 9.38%
                ko = 108 - chance;
                int dam;
                if (MUDMath.NumberPercent() < ko)
                {
                    // doh! This is gonna hurt
                    //deal some decent damage...to self!
                    if (ch.GetRace() != Race.RACE_MINOTAUR)
                    {
                        dam = MUDMath.Dice(ch.Level, 3);
                    }
                    else
                    {
                        dam = MUDMath.Dice(ch.Level, 2);
                    }
                    if (dam > ch.Hitpoints)
                    {
                        dam = ch.Hitpoints + 1;
                    }
                    if (Combat.InflictDamage(ch, ch, dam, "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon))
                    {
                        // ch invalidated, can't send messages.
                        return;
                    }
                    SocketConnection.Act("$n&n staggers about, then collapses in a heap.", ch, null, null, SocketConnection.MessageTarget.room);
                    ch.SendText("You fall to the ground stunned.\r\n");
                    SocketConnection.Act("$n&n is stunned!", ch, null, null, SocketConnection.MessageTarget.room);
                    ch.CurrentPosition = Position.stunned;
                    ch.WaitState((Skill.SkillList["headbutt"].Delay * 2));
                    text = String.Format("Commandheadbutt: {0}&n stunned self.", ch.Name);
                    ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, text);
                }
                else
                {
                    // Was previously level d 2, which averaged 30 damage at 20 and 75 at 50.  PC to PC
                    // damage is not quartered when it is done to yourself, so this it kind of high at the
                    // upper levels.  This has been reduced by level / 5, so the damage at 50 averages 65
                    // instead of 65.
                    // Keep in mind that the real penalties come from KO and comparitively someone that
                    // fails a bash doesen't take insane damage.
                    dam = MUDMath.Dice(ch.Level, 2) - ch.Level / 5;
                    if (dam > ch.Hitpoints)
                    {
                        dam = ch.Hitpoints + 1;
                    }
                    Combat.InflictDamage(ch, ch, dam, "headbutt", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                }
            } //end if() headbutt failed
            return;
        }
Exemple #9
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;
        }
Exemple #10
0
        /// <summary>
        /// Springleap.  Can be used to initiate combat and can be used during combat.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Springleap(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int chance;

            /* Check player's level and class, mobs can use this skill */
            if ((!ch.HasSkill("springleap")))
            {
                ch.SendText("You'd better leave the martial arts to Bruce Lee.\r\n");
                return;
            }

            if (ch.GetRace() == Race.RACE_CENTAUR)
            {
                ch.SendText("Your anatomy prevents you from springleaping.\r\n");
                return;
            }

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

            CharData victim = ch.Fighting;

            if (str.Length != 0)
            {
                if (!(victim = ch.GetCharRoom(str[0])) || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("You don't see them here.\r\n");
                    return;
                }
            }
            else
            {
                if (!victim || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("You aren't fighting anyone.\r\n");
                    return;
                }
            }

            /* springleap self */
            if (ch == victim)
            {
                ch.SendText("You can't quite figure out how to do that.\r\n");
                return;
            }

            /* Check size of ch vs. victim. */
            /* If ch is too small. */
            if (ch.CurrentSize - 2 > victim.CurrentSize)
            {
                SocketConnection.Act("Your acrobatic maneuver cannot accurately leap into such a small being.", ch, null, victim, SocketConnection.MessageTarget.character);
                return;
            }
            /* Ch 2 or more sizes larger than victim => bad! */
            if (ch.CurrentSize + 2 < victim.CurrentSize)
            {
                SocketConnection.Act("Your acrobatic maneuver does not seem to work on someone so large.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n jumps into you, and slides down your leg.", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n jumps into $N&n and slides down $S leg.", ch, null, victim, SocketConnection.MessageTarget.room_vict);

                ch.WaitState(Skill.SkillList["springleap"].Delay);
                ch.CurrentPosition = Position.reclining;
                if (victim.Fighting == null)
                {
                    Combat.SetFighting(victim, ch);
                }
                return;
            }

            ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["springleap"].Delay));
            ch.PracticeSkill("springleap");

            if (ch.IsNPC())
            {
                chance = (ch.Level * 3) / 2 + 15;
            }
            else
            {
                chance = ((PC)ch).SkillAptitude["springleap"] - 5;
            }

            if (chance > 95)
            {
                chance = 95;
            }

            if (victim.CurrentPosition < Position.fighting)
            {
                chance /= 4;
            }

            if (MUDMath.NumberPercent() < chance)
            {
                ch.CurrentPosition = Position.fighting;
                SocketConnection.Act("&+WYour springleap knocks $N&n&+W on $S butt.&n", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("&+W$n&n&+W leaps gracefully at $N&n&+W, sending $M to the ground.&n", ch, null, victim, SocketConnection.MessageTarget.room);
                SocketConnection.Act("&+W$n&n&+W leaps at you, knocking you to the ground!&n", ch, null, victim, SocketConnection.MessageTarget.victim);
                if (victim.IsAffected(Affect.AFFECT_SINGING))
                {
                    victim.RemoveAffect(Affect.AFFECT_SINGING);
                    SocketConnection.Act("$n&n gasps and falls silent as $e falls over backward!", victim, null, null, SocketConnection.MessageTarget.room);
                    victim.SendText("You abort your singing!\r\n");
                }
                if (victim.IsAffected(Affect.AFFECT_CASTING))
                {
                    victim.RemoveAffect(Affect.AFFECT_CASTING);
                    SocketConnection.Act("$n&n no longer has any idea what $e was casting.", victim, null, null, SocketConnection.MessageTarget.room);
                    victim.SendText("Lying on the ground, you realize you have no idea what you were just casting.\r\n");
                }

                if (!ch.Fighting)
                {
                    Combat.SetFighting(ch, victim);
                }
                if (!victim.Fighting)
                {
                    Combat.SetFighting(victim, ch);
                }
                if (!Combat.CheckTumble(victim))
                {
                    victim.WaitState((Skill.SkillList["springleap"].Delay * 5 / 6));
                    if (victim.CurrentPosition > Position.sitting)
                    {
                        victim.CurrentPosition = Position.sitting;
                    }
                    Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, ch.Level), "springleap", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                }
                else
                {
                    Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, (ch.Level / 3)), "springleap", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                    ch.SendText("You roll with the blow, finally landing on your feet.\r\n");
                    SocketConnection.Act("$n&n rolls with the blow, finally landing on $s feet.", victim, null, null, SocketConnection.MessageTarget.room);
                }
            }
            else
            {
                bool pissedOff = false;
                if (ch.Fighting == victim || victim.GetCurrInt() > MUDMath.NumberPercent())
                {
                    pissedOff = true;
                }
                if (pissedOff)
                {
                    SocketConnection.Act("As $N&n avoids your leap you crash to the ground.", ch, null, victim, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n crashes to the ground as you avoid $s springleap.", ch, null, victim, SocketConnection.MessageTarget.victim);
                    if (!ch.Fighting)
                    {
                        Combat.SetFighting(ch, victim);
                    }
                    if (!victim.Fighting)
                    {
                        Combat.SetFighting(victim, ch);
                    }
                }
                else
                {
                    SocketConnection.Act("You ungracefully leap at $N and miss, landing head first!", ch, null, victim, SocketConnection.MessageTarget.character);
                }
                SocketConnection.Act("$n&n misses a springleap and falls awkwardly to the ground.", ch, null, null, SocketConnection.MessageTarget.room);
                ch.CurrentPosition = Position.reclining;
                Combat.InflictDamage(ch, ch, MUDMath.NumberRange(1, 4), "springleap",
                        ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
            }

            return;
        }
Exemple #11
0
        /// <summary>
        /// Bodyslam an opponent.  Can only be used to initiate combat.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Bodyslam(CharData ch, string[] str)
        {
            if( ch == null ) return;

            CharData victim;

            /* Check player's level and class, mobs can use this skill */
            if (!ch.HasInnate(Race.RACE_BODYSLAM))
            {
                ch.SendText("You don't feel massive enough to manhandle that.\r\n");
                return;
            }

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

            if (str.Length != 0)
            {
                if (!(victim = ch.GetCharRoom(str[0])) || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("They aren't here.\r\n");
                    return;
                }
            }
            else
            {
                ch.SendText("Bodyslam who?\r\n");
                return;
            }

            // Added size restrictions -- Xangis
            if (victim.CurrentSize > ch.CurrentSize)
            {
                if (ch.HasInnate(Race.RACE_SLAM_LARGER))
                {
                    // allowing centaurs to slam one size up if it's an ogre
                    if (victim.CurrentSize > (ch.CurrentSize + 1))
                    {
                        ch.SendText("You can't bodyslam something that much bigger than you.\r\n");
                        return;
                    }
                }
                else
                {
                    ch.SendText("You can't bodyslam something bigger than you.\r\n");
                    return;
                }
            }

            if ((ch.CurrentSize > victim.CurrentSize) && ((ch.CurrentSize - victim.CurrentSize) > 3))
            {
                ch.SendText("They're too small to slam.\r\n");
                return;
            }

            /* Bodyslam self?  Ok! */
            if (ch == victim)
            {
                ch.SendText("You slam yourself to the ground!\r\n");
                SocketConnection.Act("$n&n throws $mself to the ground in a fit of clumsiness.",
                     ch, null, victim, SocketConnection.MessageTarget.room_vict);
                ch.WaitState((Skill.SkillList["bodyslam"].Delay / 2));
                ch.CurrentPosition = Position.reclining;
                Combat.InflictDamage(ch, ch, MUDMath.NumberRange(1, 6), "bodyslam", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                return;
            }

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

            int chance = (ch.Level * 3) / 2 + 15;
            chance += ch.GetCurrAgi() - victim.GetCurrAgi();
            chance -= (victim.Level - ch.Level);

            switch (victim.CurrentPosition)
            {
                case Position.dead:
                    return;
                case Position.mortally_wounded:
                    chance += 15;
                    break;
                case Position.incapacitated:
                    chance += 10;
                    break;
                case Position.unconscious:
                    chance += 5;
                    break;
                case Position.stunned:
                    chance += 3;
                    break;
                case Position.sleeping:
                    chance += 2;
                    break;
                case Position.reclining:
                    chance -= 45;
                    break;
                case Position.resting:
                    chance -= 30;
                    break;
                case Position.sitting:
                    chance -= 20;
                    break;
                case Position.kneeling:
                    chance -= 15;
                    break;
                case Position.fighting:
                case Position.standing:
                default:
                    break;
            }

            // Small penalty for the small buggers -- Xangis
            if (victim.CurrentSize < (ch.CurrentSize - 1))
            {
                chance -= 15;
            }

            if (chance > 90)
            {
                chance = 90;
            }

            // Shaman bodyslam penalty.
            if (ch.IsClass(CharClass.Names.shaman) || ch.IsClass(CharClass.Names.druid))
            {
                chance = (chance * 2) / 3;
            }

            if (victim.IsAffected(Affect.AFFECT_AWARE))
            {
                chance -= 15;
            }
            else if (victim.IsAffected( Affect.AFFECT_SKL_AWARE))
            {
                if (ch.HasSkill("springleap"))
                {
                    if (ch.IsNPC())
                    {
                        if (MUDMath.NumberPercent() < ((ch.Level * 3) / 2 + 15))
                        {
                            chance -= 15;
                        }
                    }
                    else if (MUDMath.NumberPercent() < ((PC)ch).SkillAptitude["awareness"])
                    {
                        ch.PracticeSkill("awareness");
                        chance -= 15;
                    }
                    else
                    {
                        ch.PracticeSkill("awareness");
                    }
                }
            }

            if (!ch.Fighting)
            {
                Combat.SetFighting(ch, victim);
            }
            if (victim.Fighting == null)
            {
                Combat.SetFighting(victim, ch);
            }

            if (ch.IsNPC() || MUDMath.NumberPercent() < chance)
            {
                if (victim.IsAffected( Affect.AFFECT_SINGING))
                {
                    victim.RemoveAffect(Affect.AFFECT_SINGING);
                    SocketConnection.Act("$n&n suddenly loses track of the key $e was singing in.", victim, null, null, SocketConnection.MessageTarget.room);
                    victim.SendText("You get the wind knocked out of you!\r\n");
                }
                if (victim.IsAffected( Affect.AFFECT_CASTING))
                {
                    victim.RemoveAffect(Affect.AFFECT_CASTING);
                    SocketConnection.Act("$n&n's thoughts of casting are scattered about as $e is slammed into the ground.", victim, null, null, SocketConnection.MessageTarget.room);
                    victim.SendText("Your brain slamming against your skull disrupts your concentration.\r\n");
                }
                // Moved damage to bottom because it would crash when a person died, because
                // it still tried to access them as a valid character.  Also added tumble check for
                // thieves.
                if (!Combat.CheckTumble(victim))
                {
                    victim.WaitState(Skill.SkillList["bodyslam"].Delay);
                    victim.CurrentPosition = Position.reclining;
                    Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, ch.Level), "bodyslam", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                }
                else
                {
                    if (!Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, (ch.Level / 3)), "bodyslam", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon))
                    {
                        ch.SendText("You roll with the blow, finally landing on your feet.\r\n");
                        SocketConnection.Act("$n&n rolls with the blow, finally landing on $s feet.", ch, null, null, SocketConnection.MessageTarget.room);
                    }
                }
            }
            else
            {
                ch.Hitpoints -= MUDMath.NumberRange(1, 5);
                SocketConnection.Act("As $N&n avoids your slam, you smack headfirst into the &n&+yground&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n throws $mself to the &n&+yground&n in a fit of clumsiness.", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n misses a bodyslam on $N&n and slams $s head into the &n&+yground&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                ch.CurrentPosition = Position.reclining;
            }

            return;
        }
Exemple #12
0
        /// <summary>
        /// Pour a liquid.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Pour(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object obj;
            string arg1 = String.Empty;
            string arg2 = String.Empty;

            if (ch.IsBlind())
                return;

            if (!(obj = ch.GetObjCarrying(arg1)))
            {
                ch.SendText("You do not have that item.\r\n");
                return;
            }

            if (obj.ItemType != ObjTemplate.ObjectType.drink_container)
            {
                ch.SendText("You can't fill that.\r\n");
                return;
            }

            if (!MUDString.StringsNotEqual("out", arg2))
            {
                ch.SendText("You pour it out.\r\n");
                obj.Values[1] = 0;
                return;
            }

            Object otherobj = ch.GetObjHere(arg2);
            if (!otherobj)
            {
                ch.SendText("Pour it where?\r\n");
                return;
            }

            if (otherobj.Values[2] != obj.Values[2] && otherobj.Values[1] != 0)
            {
                ch.SendText("It's got another liquid in it.\r\n");
                return;
            }

            SocketConnection.Act("You fill $p&n.", ch, otherobj, null, SocketConnection.MessageTarget.character);
            otherobj.Values[2] = obj.Values[2];
            otherobj.Values[1] += obj.Values[1];
            obj.Values[1] = 0;
            // Over pour in code => just pour it back in the first container.
            if (otherobj.Values[1] > otherobj.Values[0])
            {
                obj.Values[1] = otherobj.Values[1] - otherobj.Values[0];
                otherobj.Values[1] = otherobj.Values[0];
            }
            return;
        }
Exemple #13
0
        /// <summary>
        /// Looks at an object, mobile, or room.
        /// </summary>
        /// <param name="ch">The acting character.</param>
        /// <param name="str">Command arguments.</param>
        public static void LookCommand(CharData ch, string[] str)
        {
            if( ch == null ) return;

            // Build argument list, stripping articles.
            bool inside = false;
            List<String> args = new List<string>(str);
            for (int i = (args.Count - 1); i >= 0; i-- )
            {
                if (args[i].Equals("in", StringComparison.CurrentCultureIgnoreCase) || args[i].Equals("i", StringComparison.CurrentCultureIgnoreCase))
                {
                    args.RemoveAt(i);
                    inside = true;
                }
                else if (args[i].Equals("at", StringComparison.CurrentCultureIgnoreCase))
                {
                    args.RemoveAt(i);
                }
            }

            // If it's a mob that isn't switched, bail.
            if (ch.Socket == null)
                return;

            if (ch.CurrentPosition < Position.sleeping)
            {
                ch.SendText("&nYou can't see anything but &+Ystars&n!  See how pretty!\r\n");
                return;
            }

            if (ch.CurrentPosition == Position.sleeping)
            {
                ch.SendText("&nYou can't see anything, you're &+Lsleeping&n!  Zzz.\r\n");
                return;
            }

            if (ch.IsBlind())
                return;

            // Look panel for ships.
            if ( args.Count > 0 && args[0].Equals("panel", StringComparison.CurrentCultureIgnoreCase))
            {
                CommandType.Interpret(ch, "Lookpanel");
                return;
            }
            // Look out for ships.
            if (args.Count > 0 && args[0].Equals("out", StringComparison.CurrentCultureIgnoreCase))
            {
                CommandType.Interpret(ch, "Lookout");
                return;
            }

            Object obj;
            Exit exit;
            string pdesc;
            int number = 0;
            string output = String.Empty;

            // 'look' or 'look auto' or 'look room'
            if (args.Count == 0 || args[0].Equals( "auto", StringComparison.CurrentCultureIgnoreCase) ||
                args[0].Equals("room", StringComparison.CurrentCultureIgnoreCase))
            {
                if (ch.InRoom == null)
                {
                    ch.SendText("You are not in a room.  You are just floating in empty space.  This should never happen.  You should <petition> someone for help.\r\n");
                    Log.Error("Character executing Commandlook command from null room: " + ch.Name);
                    return;
                }
                if (ch.FlightLevel > 0)
                {
                    switch (ch.FlightLevel)
                    {
                        case CharData.FlyLevel.low:
                            ch.SendText("Hovering above ");
                            break;
                        case CharData.FlyLevel.medium:
                            ch.SendText("Flying above ");
                            break;
                        case CharData.FlyLevel.high:
                            ch.SendText("Flying high above ");
                            break;
                    }
                }
                if (!ch.HasActionBit(PC.PLAYER_GODMODE) && ch.InRoom.IsDark()
                        && !ch.HasInnate(Race.RACE_ULTRAVISION)
                        && !ch.IsAffected( Affect.AFFECT_ULTRAVISION))
                {
                    ch.SendText("&+lSomewhere\r\n");
                }
                else if (!ch.HasActionBit(PC.PLAYER_GODMODE))
                {
                    String roomOpen = String.Empty;
                    String roomClose = String.Empty;
                    if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED)
                    {
                        roomOpen = "<zone>" + ch.InRoom.Area.Name + "</zone><roomTitle>";
                        roomClose = "</roomTitle>";
                    }
                    else
                    {
                        roomClose = "&n\r\n";
                    }
                    // Added support for both manual and automatic descriptions on the worldmap.
                    if (!ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP) || ch.InRoom.Title.Length > 1)
                    {
                        output += roomOpen + ch.InRoom.Title + roomClose;
                    }
                    else
                    {
                        output += roomOpen + "No room title." + roomClose;
                    }
                }
                else
                {
                    if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED)
                    {
                        ch.SendText("<zone>" + ch.InRoom.Area.Name + "</zone>");
                    }
                    Look.ShowRoomInfo(ch, ch.InRoom);
                }

                if (!ch.IsNPC() && !ch.HasActionBit(PC.PLAYER_GODMODE) && ch.InRoom.IsDark()
                    && !ch.HasInnate(Race.RACE_ULTRAVISION) && !ch.IsAffected( Affect.AFFECT_ULTRAVISION))
                {
                    ch.SendText("&+LIt is pitch black...&n \r\n");
                    Look.ShowCharacterToCharacter(ch.InRoom.People, ch);
                    return;
                }

                if (!ch.IsNPC() && (args.Count > 0 && (args[0].Equals("room", StringComparison.CurrentCultureIgnoreCase) ||
                    args[0].Equals("auto", StringComparison.CurrentCultureIgnoreCase))))
                {
                    String roomDescOpen = String.Empty;
                    String roomDescClose = String.Empty;
                    String mapSpace = String.Empty;

                    if (!ch.IsNPC() && ch.Socket.Terminal == SocketConnection.TerminalType.TERMINAL_ENHANCED)
                    {
                        roomDescOpen = "<roomDescription>";
                        roomDescClose = "</roomDescription>";
                    }
                    else
                    {
                        roomDescClose = "&n\r\n";
                        mapSpace = "    ";
                    }
                    if( !ch.HasActionBit(PC.PLAYER_BRIEF) && !ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP))
                    {
                        // Added support for both manual and automatic descriptions on the worldmap.
                        if (ch.InRoom.Description.Length > 0)
                        {
                            output += roomDescOpen + "    " + (ch.InRoom.Description.Trim()) + roomDescClose;
                        }
                        //else if (ch._inRoom.WorldmapTerrainType < Database.SystemData.MapInfo.Length)
                        //    output += roomDescOpen + mapSpace + Database.SystemData.MapInfo[ch._inRoom.WorldmapTerrainType].RoomDescription + roomDescClose;
                        else
                        {
                            output += roomDescOpen + "    No room description." + roomDescClose;
                        }
                    }
                }
                if (!String.IsNullOrEmpty(output))
                {
                    ch.SendText(output);
                }

                if (ch.InRoom.Area.HasFlag(Area.AREA_WORLDMAP))
                {
                    if (ch.HasActionBit(PC.PLAYER_MAP))
                    {
                        Command.Worldmap(ch, null);
                    }
                    else if (!ch.IsNPC() && ch.Socket.Terminal != SocketConnection.TerminalType.TERMINAL_ENHANCED)
                    {
                        ch.SendText("\r\n");
                    }
                }

                if (ch.InRoom.HasFlag(RoomTemplate.ROOM_SILENT))
                {
                    ch.SendText("&nIt seems preternaturally quiet.\r\n");
                }

                CommandType.Interpret(ch, "exits auto");

                Look.ShowRoomAffects(ch, ch.InRoom);

                Look.ShowListToCharacter(ch.InRoom.Contents, ch, false, false);
                Look.ShowCharacterToCharacter(ch.InRoom.People, ch);
                return;
            }

            // 'look direction'
            int door = -1;
            if (args.Count > 0)
            {
                if ("north".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 0;
                else if ("east".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 1;
                else if ("south".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 2;
                else if ("west".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 3;
                else if ("up".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 4;
                else if ("down".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 5;
                else if ("northwest".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 6;
                else if ("southwest".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 7;
                else if ("northeast".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 8;
                else if ("southeast".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 9;
                else if ("nw".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 6;
                else if ("sw".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 7;
                else if ("ne".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 8;
                else if ("se".StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    door = 9;
            }
            if (door != -1)
            {
                // If no exit data, then return.
                exit = ch.InRoom.ExitData[door];
                if (!exit)
                {
                    ch.SendText("There's nothing to see in that direction.\r\n");
                    return;
                }

                if (exit.HasFlag(Exit.ExitFlag.walled))
                {
                    ch.SendText("There's a wall in the way.\r\n");
                    return;
                }

                // Check for farsee
                if ((ch.IsAffected( Affect.AFFECT_FARSEE) || ch.HasActionBit(PC.PLAYER_GODMODE))
                        && !exit.HasFlag(Exit.ExitFlag.closed))
                {
                    if (exit.TargetRoom)
                    {
                        Room room = ch.InRoom;
                        ch.RemoveFromRoom();
                        ch.AddToRoom(Room.GetRoom(exit.IndexNumber));
                        CommandType.Interpret(ch, "look");
                        ch.RemoveFromRoom();
                        ch.AddToRoom(room);
                        return;
                    }
                    ch.SendText("Nothing special there.\r\n");
                }

                if (exit.Description.Length != 0)
                {
                    ch.SendText(exit.Description);
                }
                else
                {
                    ch.SendText("Nothing special there.\r\n");
                }

                if (exit.Keyword.Length != 0)
                {
                    if (exit.HasFlag(Exit.ExitFlag.bashed))
                        SocketConnection.Act("The $d has been bashed from its &n&+whinges&n.",
                             ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    else if (exit.HasFlag(Exit.ExitFlag.closed))
                        SocketConnection.Act("The $d is closed.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    else if (exit.HasFlag(Exit.ExitFlag.secret))
                        SocketConnection.Act("The $d is secret.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    else if (exit.HasFlag(Exit.ExitFlag.blocked))
                        SocketConnection.Act("The $d is blocked.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                }
                else
                {
                    if (exit.HasFlag(Exit.ExitFlag.bashed))
                    {
                        SocketConnection.Act("The door has been bashed from its &n&+whinges&n.",
                             ch, null, null, SocketConnection.MessageTarget.character);
                    }
                    else if (exit.HasFlag(Exit.ExitFlag.closed))
                        SocketConnection.Act("The door is closed.", ch, null, null, SocketConnection.MessageTarget.character);
                    else if (exit.HasFlag(Exit.ExitFlag.is_door))
                        SocketConnection.Act("The door is open.", ch, null, null, SocketConnection.MessageTarget.character);
                    else if (exit.HasFlag(Exit.ExitFlag.secret))
                        SocketConnection.Act("The door is secret.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    else if (exit.HasFlag(Exit.ExitFlag.blocked))
                        SocketConnection.Act("The $d is blocked.", ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                }
                // If exit found, don't keep looking.
                return;
            }

            // Look inside something ('look in').
            if (inside)
            {
                // 'look in'
                if (args.Count < 1)
                {
                    ch.SendText("Look in what?\r\n");
                    return;
                }

                obj = ch.GetObjHere(args[0]);
                if (!obj)
                {
                    ch.SendText("You do not see that here.\r\n");
                    return;
                }

                switch (obj.ItemType)
                {
                    default:
                        ch.SendText("That is not a container.\r\n");
                        break;

                    case ObjTemplate.ObjectType.drink_container:
                        if (obj.Values[1] == -1)
                        {
                            ch.SendText("It is full.\r\n");
                            break;
                        }

                        if (obj.Values[1] <= 0)
                        {
                            ch.SendText("It is empty.\r\n");
                            break;
                        }

                        output += "It's ";
                        if (obj.Values[1] < obj.Values[0] / 4)
                            output += "less than half";
                        else if (obj.Values[1] < (3 * obj.Values[0] / 4))
                            output += "about half";
                        else if (obj.Values[1] < obj.Values[0])
                            output += "more than half";
                        else
                            output += "completely";
                        output += " full of a " + Liquid.Table[obj.Values[2]].Color + "liquid.\r\n";

                        ch.SendText(output);
                        break;

                    case ObjTemplate.ObjectType.quiver:
                    case ObjTemplate.ObjectType.container:
                    case ObjTemplate.ObjectType.npc_corpse:
                    case ObjTemplate.ObjectType.pc_corpse:
                        if (Macros.IsSet(obj.Values[1], ObjTemplate.CONTAINER_CLOSED.Vector))
                        {
                            ch.SendText("It is closed.\r\n");
                            break;
                        }

                        SocketConnection.Act("$p&n contains:", ch, obj, null, SocketConnection.MessageTarget.character, true);
                        Look.ShowListToCharacter(obj.Contains, ch, true, true);
                        break;
                    case ObjTemplate.ObjectType.portal:
                        SocketConnection.Act("A $p&n leads to:", ch, obj, null, SocketConnection.MessageTarget.character);
                        output += Room.GetRoom(obj.Values[0]).Title + "\r\n";
                        output += Room.GetRoom(obj.Values[0]).Description;
                        output += "\r\n";
                        ch.SendText(output);
                        break;
                }
                return;
            }

            // Look at another char.
            if (args.Count > 0)
            {
                CharData victim = ch.GetCharRoom(args[0]);
                if (victim != null)
                {
                    Look.ShowCharacterToCharacterFull(victim, ch);
                    return;
                }
            }

            // Look at an object.
            if (args.Count > 0)
            {
                // Check inventory.
                obj = ch.GetObjCarrying(args[0]);
                // If not in inventory, check eq.
                if (obj == null)
                    obj = ch.GetObjWear(args[0]);
                // If not on character, check room.
                if (obj == null)
                    obj = Object.GetObjFromList(ch.InRoom.Contents, ch, args[0]);
                // If object found, show it to the char.
                if (obj != null)
                {
                    pdesc = (Database.GetExtraDescription(args[0], obj.ExtraDescription));
                    if (pdesc.Length != 0)
                    {
                        ch.SendText(pdesc);
                    }
                    else if ((pdesc = (Database.GetExtraDescription(args[0], obj.ObjIndexData.ExtraDescriptions))).Length > 0)
                    {
                        ch.SendText(pdesc);
                    }
                    else if (obj.FullDescription.Length > 0)
                    {
                        ch.SendText(obj.FullDescription);
                        ch.SendText("\r\n");
                    }
                    if (obj.HasAffect(Affect.AffectType.skill, "poison weapon"))
                    {
                        if (ch.IsClass(CharClass.Names.thief) || ch.IsClass(CharClass.Names.assassin)
                                || MUDMath.NumberPercent() < ch.GetCurrInt() / 2)
                            ch.SendText("It has a &+Gsickly &+Lcolored&n hue.\r\n");
                    }
                    return;
                }
            }

            // Look at an object in the room
            if (args.Count > 0)
            {
                int count = 0;
                foreach (Object iobj in ch.InRoom.Contents)
                {
                    if (CharData.CanSeeObj(ch, iobj))
                    {
                        pdesc = (Database.GetExtraDescription(args[0], iobj.ExtraDescription));
                        if (pdesc.Length != 0)
                        {
                            if (++count == number)
                            {
                                ch.SendText(pdesc);
                                return;
                            }
                            continue;
                        }
                        pdesc = (Database.GetExtraDescription(args[0], iobj.ObjIndexData.ExtraDescriptions));
                        if (pdesc.Length != 0)
                        {
                            if (++count == number)
                            {
                                ch.SendText(pdesc);
                                return;
                            }
                            continue;
                        }
                        if (MUDString.NameContainedIn(args[0], iobj.Name))
                        {
                            if (++count == number)
                            {
                                ch.SendText(iobj.FullDescription);
                                ch.SendText("\r\n");
                                return;
                            }
                            continue;
                        }
                    }
                }
            }

            // Check for room extra descriptions
            if (args.Count > 0)
            {
                pdesc = (Database.GetExtraDescription(args[0], ch.InRoom.ExtraDescriptions));
                if (!String.IsNullOrEmpty(pdesc))
                {
                    ch.SendText(pdesc);
                    return;
                }
            }

            ch.SendText("You do not see that here.\r\n");
            return;
        }
Exemple #14
0
        public static void Fill(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object fountain = null;

            if (ch.IsBlind())
            {
                ch.SendText("You can't see what you're trying to fill.\r\n");
                return;
            }

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

            Object obj = ch.GetObjCarrying(str[0]);
            if (!obj)
            {
                ch.SendText("You do not have that item.\r\n");
                return;
            }

            bool found = false;
            foreach (Object fount in ch.InRoom.Contents)
            {
                if (fount.FlyLevel != ch.FlightLevel)
                    continue;
                if (fount.ItemType == ObjTemplate.ObjectType.drink_container)
                {
                    fountain = fount;
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                ch.SendText("There is nothing to fill from here!\r\n");
                return;
            }

            if (obj.ItemType != ObjTemplate.ObjectType.drink_container)
            {
                ch.SendText("You can't fill that.\r\n");
                return;
            }

            if (obj.Values[1] != 0 && obj.Values[2] != fountain.Values[2])
            {
                ch.SendText("There is already another liquid in it.\r\n");
                return;
            }

            if (obj.Values[1] >= obj.Values[0])
            {
                ch.SendText("Your container is full.\r\n");
                return;
            }

            SocketConnection.Act("You fill $p&n.", ch, obj, null, SocketConnection.MessageTarget.character);
            obj.Values[2] = fountain.Values[2];
            obj.Values[1] = obj.Values[0];
            return;
        }
Exemple #15
0
        public static void WherePlayer(CharData ch, string[] str)
        {
            if( ch == null ) return;

            CharData victim;
            SocketConnection socket;
            string buf;
            bool found;

            if (ch.IsBlind())
                return;

            if (str.Length == 0)
            {
                ch.SendText("&nPlayers near you:\r\n");
                found = false;
                foreach (SocketConnection it in Database.SocketList)
                {
                    socket = it;

                    if (socket.ConnectionStatus == SocketConnection.ConnectionState.playing && (victim = socket.Character)
                            && !victim.IsNPC() && victim.InRoom
                            && victim.InRoom.Area == ch.InRoom.Area && CharData.CanSee(ch, victim))
                    {
                        found = true;
                        buf = String.Format("%{0} {1}\r\n",
                                  MUDString.PadStr(victim.Name, 28), victim.InRoom.Title);
                        ch.SendText(buf);
                    }
                }
                if (!found)
                    ch.SendText("None\r\n");
            }
            else if (!MUDString.IsPrefixOf(str[0], "all"))
            {
                ch.SendText("&nPlayer locations:\r\n");
                found = false;
                foreach (SocketConnection it in Database.SocketList)
                {
                    socket = it;

                    if (socket.ConnectionStatus == SocketConnection.ConnectionState.playing && (victim = socket.Character) && !victim.IsNPC()
                            && victim.InRoom && CharData.CanSee(ch, victim))
                    {
                        found = true;
                        buf = String.Format("{0} [{1}]{2}&n\r\n",
                                  MUDString.PadStr(victim.Name, 28),
                                  MUDString.PadInt(victim.InRoom.IndexNumber, 7),
                                  victim.InRoom.Title);
                        ch.SendText(buf);
                    }
                }
                if (!found)
                    ch.SendText("None\r\n");
            }
            else
            {
                found = false;
                foreach (CharData it in Database.CharList)
                {
                    victim = it;
                    if (victim.InRoom.Area == ch.InRoom.Area
                            && CharData.CanSee(ch, victim)
                            && MUDString.NameContainedIn(str[0], victim.Name))
                    {
                        found = true;
                        buf = String.Format("{0} {1}\r\n",
                                  MUDString.PadStr(victim.ShowNameTo(ch, true), 28), victim.InRoom.Title);
                        ch.SendText(buf);
                        break;
                    }
                }
                if (!found)
                    SocketConnection.Act("&nYou didn't find any $T.", ch, null, str[0], SocketConnection.MessageTarget.character);
            }

            return;
        }
Exemple #16
0
        /// <summary>
        /// Stab someone in the back.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Backstab(CharData ch, string[] str)
        {
            if( ch == null ) return;

            if (!ch.HasSkill("backstab"))
            {
                ch.SendText("You better leave the assassination trade to those more skilled.\r\n");
                return;
            }

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

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

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

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

            if (victim == ch)
            {
                ch.SendText("How can you sneak up on yourself?\r\n");
                return;
            }

            Combat.Backstab(ch, victim);
            return;
        }
Exemple #17
0
        /// <summary>
        /// Charge into someone. Helps to have horns on your head.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Charge(CharData ch, string[] str)
        {
            if( ch == null ) return;

            CharData victim;

            /* Check player's level and class, mobs can use this skill */
            if (!ch.HasInnate(Race.RACE_CHARGE))
            {
                ch.SendText("You can't do that.\r\n");
                return;
            }

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

            if (str.Length != 0)
            {
                if (!(victim = ch.GetCharRoom(str[0])) || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("They aren't here.\r\n");
                    return;
                }
            }
            else
            {
                ch.SendText("Charge who?\r\n");
                return;
            }

            /* charge me trap */
            if (ch == victim)
            {
                ch.SendText("You chase your tail for a while.\r\n");
                return;
            }

            ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["charge"].Delay));

            if (!ch.Fighting)
            {
                Combat.SetFighting(ch, victim);
            }
            if (!victim.Fighting)
            {
                Combat.SetFighting(victim, ch);
            }

            // Chance is based on level of charger and victim.
            int chance = (ch.Level * 2) - victim.Level + 25;
            if (chance > 95)
            {
                chance = 95;
            }

            if (ch.IsNPC() || MUDMath.NumberPercent() < chance)
            {
                Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, ch.Level), "charge", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
            }
            else
            {
                Combat.InflictDamage(ch, victim, 0, "charge", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
            }

            return;
        }
Exemple #18
0
        /// <summary>
        /// Bash. Usable to initiate combat and during combat.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Bash(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int chance;

            /* Check player's level and class, mobs can use this skill */
            if ((!ch.HasSkill("bash")))
            {
                ch.SendText("You'd better leave that to those with more skills.\r\n");
                return;
            }

            if (ch.IsBlind() && !ch.Fighting)
            {
                return;
            }

            /* Verify a target. */
            CharData victim = ch.Fighting;
            if (str.Length != 0)
            {
                victim = ch.GetCharRoom(str[0]);
                if (!victim || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("They aren't anywhere to be found.\r\n");
                    return;
                }
            }
            else
            {
                if (!victim || victim.CurrentPosition == Position.dead)
                {
                    ch.SendText("You aren't fighting anyone.\r\n");
                    return;
                }
            }

            /* Bash self? Ok! */
            // Toned down the damage cuz you can't really bash yourself
            // like you could with someone else.
            if (victim == ch)
            {
                ch.SendText("You throw yourself to the ground!\r\n");
                SocketConnection.Act("$N&n knocks $mself to the ground.", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                ch.CurrentPosition = Position.kneeling;
                ch.WaitState((Skill.SkillList["bash"].Delay * 8) / 10);
                Combat.InflictDamage(ch, ch, MUDMath.NumberRange(1, 3), "bash", ObjTemplate.WearLocation.none,
                        AttackType.DamageType.bludgeon);
                return;
            }

            /* Check size of ch vs. victim. */
            /* If ch is too small. */
            if (ch.CurrentSize < victim.CurrentSize)
            {
                SocketConnection.Act("$N&n is too big for you to bash!", ch, null, victim, SocketConnection.MessageTarget.character);
                return;
            }
            /* Ch 2 or more sizes larger than victim => bad! */
            if (ch.CurrentSize - 2 > victim.CurrentSize)
            {
                SocketConnection.Act("You nearly topple over as you try to bash $N&n.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n nearly topples over as $e attempts to bash you.", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n nearly topples over as $e attempts to bash $N&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                ch.WaitState((Skill.SkillList["bash"].Delay));
                ch.CurrentPosition = Position.kneeling;
                if (victim.Fighting == null)
                {
                    Combat.SetFighting(victim, ch);
                }
                return;
            }

            /* Lag to basher from bash. Pets get more lag because pets are cheesy */
            if (!ch.IsNPC())
            {
                ch.WaitState(MUDMath.FuzzyNumber(Skill.SkillList["bash"].Delay));
            }
            else
            {
                ch.WaitState((Skill.SkillList["bash"].Delay * 6 / 5));
            }

            /* Base chance to bash, followed by chance modifications. */
            if (ch.IsNPC())
            {
                chance = (ch.Level * 3) / 2 + 15;
            }
            else
            {
                chance = ((PC)ch).SkillAptitude["bash"] - 5;
            }

            if (victim.CurrentPosition < Position.fighting)
            {
                chance /= 5; //used to be 0
            }
            else
            {
                chance += ch.GetCurrAgi() - victim.GetCurrAgi();
            }

            if (chance > 95)
            {
                chance = 95;
            }

            Object obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one);
            if (!obj)
            {            /* No primary item. */
                if (!(obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two)))
                {          /* No items in hand. */
                    if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin))
                    {
                        if (!ch.IsClass(CharClass.Names.warrior))
                        {
                            chance -= 25;
                        }
                        else
                        {
                            chance -= 20;
                        }
                        ch.SendText("You lower your shoulder and attempt to bash without a shield...\r\n");
                    }
                    else
                    {
                        chance -= 3; // Hidden penalty for not having a shield
                    }
                }
                else if (obj.ItemType != ObjTemplate.ObjectType.shield)
                {          /* Secondary item isn't a shield, no primary. */
                    if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin))
                    {
                        if (!ch.IsClass(CharClass.Names.warrior))
                        {
                            chance -= 25;
                        }
                        else
                        {
                            chance -= 20;
                        }
                        ch.SendText("Bashing without a shield is tough, but you try anyway...\r\n");
                    }
                    else
                    {
                        chance -= 5; // Small hidden penalty for not having a shield
                    }
                }          /* Secondary item is a shield, no primary. */
                else if (ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin))
                {
                    chance += 3; // Small hidden bonus for having a shield
                }
            }
            else if (obj.ItemType != ObjTemplate.ObjectType.shield)
            {            /* Primary item isn't a shield. */
                if (!(obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two)))
                {          /* No secondary. */
                    if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin))
                    {
                        if (!ch.IsClass(CharClass.Names.warrior))
                        {
                            chance -= 25;
                        }
                        else
                        {
                            chance -= 20;
                        }
                        ch.SendText("Without a shield, bashing is a wistful thought, but you try anyway...\r\n");
                    }
                    else
                    {
                        chance -= 5; // Hidden penalty for not having a shield
                    }
                }
                else if (obj.ItemType != ObjTemplate.ObjectType.shield)
                {          /* Secondary item is not a shield. */
                    if (!ch.IsClass(CharClass.Names.paladin) && !ch.IsClass(CharClass.Names.antipaladin))
                    {
                        if (!ch.IsClass(CharClass.Names.warrior))
                        {
                            chance -= 25;
                        }
                        else
                        {
                            chance -= 20;
                        }
                        ch.SendText("Without a shield, your shoulder bash is but wishful thinking...\r\n");
                    }
                    else
                    {
                        chance -= 5; // Hidden penalty for not having a shield
                    }
                }
                else if (ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin))
                {          /* Secondary is a shield. */
                    chance += 3; // Small hidden bonus for having a shield
                }
                else if (ch.IsClass(CharClass.Names.ranger))
                {
                    chance -= 8;
                }
                else if (ch.IsClass(CharClass.Names.warrior))
                {
                    chance -= 5;
                }
            }

            // Centaurs are awful damned hard to bash -- Xangis
            if (victim.GetRace() == Race.RACE_CENTAUR)
            {
                chance -= 25;
            }

            // damned high penalty for bashing blind
            if (ch.IsAffected(Affect.AFFECT_BLIND) && !victim.IsAffected(Affect.AFFECT_BLIND))
            {
                chance /= 10;
            }
            if (ch.IsAffected(Affect.AFFECT_BLIND) && victim.IsAffected(Affect.AFFECT_BLIND))
            {
                chance /= 4;
            }

            ch.PracticeSkill("bash");

            /* Start a fight if not already in one. */
            if (ch != victim)
            {
                if (!ch.Fighting)
                {
                    Combat.SetFighting(ch, victim);
                }
                if (!victim.Fighting)
                {
                    Combat.SetFighting(victim, ch);
                }
            }

            string lbuf = "Bash: " + ch.Name + " bashing " + victim.Name + " with " + chance + " chance.";
            ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf);

            /* Do the bash, deal the damage. */
            if (MUDMath.NumberPercent() < chance)
            {
                /* Hit the bash. */
                if (victim.IsAffected(Affect.AFFECT_SINGING))
                {
                    victim.RemoveAffect(Affect.AFFECT_SINGING);
                    SocketConnection.Act("$n&n chokes on a note and falls silent as $e slams into the ground!", victim, null, null, SocketConnection.MessageTarget.room);
                    victim.SendText("You abort your singing!\r\n");
                }
                if (victim.IsAffected(Affect.AFFECT_CASTING))
                {
                    victim.RemoveAffect(Affect.AFFECT_CASTING);
                    SocketConnection.Act("$n&n's eyes roll back in $s head and $e forgets all about $s spell.", victim, null, null, SocketConnection.MessageTarget.room);
                    victim.SendText("Being knocked over so forcefully makes it hard to cast.\r\n");
                }
                if (!Combat.CheckTumble(victim))
                {
                    victim.WaitState(((Skill.SkillList["bash"].Delay * 5) / 6));
                    if (victim.CurrentPosition > Position.kneeling)
                    {
                        victim.CurrentPosition = Position.kneeling;
                    }
                    victim.SendText("You are knocked to the ground!\r\n");
                    Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, ch.Level), "bash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                }
                else
                {
                    Combat.InflictDamage(ch, victim, MUDMath.NumberRange(1, (ch.Level / 3)), "bash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                    victim.SendText("You roll with the blow, finally landing on your feet.\r\n");
                    SocketConnection.Act("$n&n rolls with the blow, finally landing on $s feet.", victim, null, null, SocketConnection.MessageTarget.room);
                }
            }
            else
            { /* Miss the bash. */
                SocketConnection.Act("As $N&n avoids your bash, you topple to the &n&+yground&n with a loud crash.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n crashes to the &n&+yground&n as you sidestep $s bash.", ch, null, victim, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n&n misses $s bash at $N&n and is driven to the &n&+yground&n.", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                ch.CurrentPosition = Position.kneeling;
            }

            return;
        }
Exemple #19
0
        /// <summary>
        /// The backstab function was cloned from Command.Backstab for use by mobile AI code.
        /// the difference is that a mob that wants to backstab already knows their
        /// victim, so no need for the argument stuff
        ///
        /// Modified by to allow auto-stab for backstabbers with aggr_level set.  Called
        /// from Commandbackstab()
        /// 
        /// Added ability to stab if piercer is secondary. Useful for mercs.
        ///
        /// Reduced damage for bards and mercs.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="victim"></param>
        /// <returns></returns>
        public static bool Backstab(CharData ch, CharData victim)
        {
            Object obj;
            Object obj2;
            int chance = 0;
            int stabChance;

            // Can't stab if lacking the skill

            if (!ch.HasSkill("backstab"))
            {
                ch.SendText("Leave backstabbing to the assassins!\r\n");
                return false;
            }

            if (victim == null)
            {
                ch.SendText("Pick a target!\r\n");
                return false;
            }

            // Can't stab if blind
            if (ch.IsBlind())
                return false;

            // Can't stab on horseback
            if (ch.Riding)
            {
                ch.SendText("You can't get close enough while mounted.\r\n");
                return false;
            }

            // Can't stab yourself
            if (victim == ch)
                return false;

            victim = CheckGuarding(ch, victim);

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

            /* Check size of ch vs. victim. */
            if (victim.CurrentPosition > Position.sleeping)
            {
                /* If ch is more than 2 sizes smaller it's too small. */
                if ((ch.CurrentSize - 2) > victim.CurrentSize && victim.CurrentPosition >= Position.stunned
                        && !(ch.IsNPC() && ch.MobileTemplate.IndexNumber == 10165))
                {
                    ch.SendText("Such tiny beings evade your skills.\r\n");
                    return false;
                }
                /* Ch 2 or more sizes larger than victim => bad! */
                if ((ch.CurrentSize + 2) < victim.CurrentSize && victim.CurrentPosition >= Position.stunned)
                {
                    ch.SendText("It is rather ineffective to stab someone in the calf.\r\n");
                    return false;
                }
            }

            ObjTemplate.WearLocation hand = 0;
            if ((obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one)) && obj.ItemType == ObjTemplate.ObjectType.weapon
                    && (AttackType.Table[obj.Values[3]].SkillName) == "1h piercing")
                hand = ObjTemplate.WearLocation.hand_one;
            if (hand == 0 && (obj2 = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two))
                    && obj2.ItemType == ObjTemplate.ObjectType.weapon && (AttackType.Table[obj2.Values[3]].SkillName) == "1h piercing")
                hand = ObjTemplate.WearLocation.hand_two;
            if (hand == 0)
            {
                ch.SendText("You need to wield a piercing weapon.\r\n");
                return false;
            }

            if (!ch.IsNPC())
                ch.PracticeSkill("backstab");

            Crime.CheckAttemptedMurder(ch, victim);

            ch.WaitState(Skill.SkillList["backstab"].Delay);
            if (ch.IsNPC())
            {
                stabChance = 2 * ch.Level;
            }
            else
            {
                stabChance = ((PC)ch).SkillAptitude["backstab"];
            }
            if (Math.Abs(ch.CurrentSize - victim.CurrentSize) == 2)
                stabChance -= 10;
            switch (victim.CurrentPosition)
            {
                default:
                    break;
                case Position.mortally_wounded:
                case Position.incapacitated:
                case Position.unconscious:
                    stabChance += 80;
                    break;
                case Position.stunned:
                case Position.sleeping:
                    stabChance += 40;
                    break;
                case Position.reclining:
                    stabChance += 20;
                    break;
                case Position.resting:
                case Position.sitting:
                    stabChance += 10;
                    break;
            } //end switch
            // Half as likely to succeed on those that are aware
            if (victim.IsAffected(Affect.AFFECT_AWARE) || victim.IsAffected( Affect.AFFECT_SKL_AWARE))
            {
                chance /= 2;
            }
            string lbuf = String.Format("Command.Backstab: {0} is attempting with a {1}%% chance.", ch.Name, stabChance);
            ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf);
            if (MUDMath.NumberPercent() < stabChance)
            {
                /* First hit on backstab.  Check for instant kill. - Xangis */
                if (ch.HasSkill("instant kill"))
                {
                    if (!ch.IsNPC())
                        chance = ((PC)ch).SkillAptitude["instant kill"];
                    else
                        chance = (ch.Level * 3) / 2 + 20;

                    // People over level 50 get a bonus, equates to about 1-2%
                    if (ch.Level > 50)
                        chance += 25;

                    chance += (ch.Level - victim.Level);

                    // Immortals will get a bonus too
                    if (ch.IsImmortal())
                        chance *= 4;

                    // Half as likely to succeed on those that are aware
                    if (victim.IsAffected(Affect.AFFECT_AWARE) || victim.IsAffected(Affect.AFFECT_SKL_AWARE))
                    {
                        chance /= 2;
                    }

                    if (MUDMath.NumberRange(1, 20000) < chance)
                    {
                        if (!ch.IsNPC())
                            ch.PracticeSkill("instant kill");
                        {
                            lbuf = String.Format("backstab: {0} hit an instakill on {1} with a {2} chance in hundredths of a percent.",
                                      ch.Name, victim.Name, (chance / 30));
                            ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf);
                            Log.Trace(lbuf);
                            ch.WaitState(15);
                            SingleAttack(ch, victim, "instant kill", hand);
                            return true;
                        }
                    }
                }

                SingleAttack(ch, victim, "backstab", hand);
                /* No double stabs when the first stab kills'm. */
                if (victim.CurrentPosition == Position.dead)
                    return true;

                /* Case of thieves/assassins doing a double backstab. */
                obj = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_two);
                /* Stop 2nd-hand non-pierce backstabs. */
                if (!ch.IsNPC() && (obj != null) && (hand != ObjTemplate.WearLocation.hand_two)
                        && obj.ItemType == ObjTemplate.ObjectType.weapon
                        && (AttackType.Table[obj.Values[3]].SkillName) == "1h piercing")
                {
                    /* Thieves get 1/2 chance at double, assassins get 2/3. */
                    // Xangis - removed double stab for thieves 6-9-00
                    if ((ch.IsClass(CharClass.Names.assassin)) && (MUDMath.NumberPercent() < ((PC)ch).SkillAptitude["backstab"] * 2 / 3))
                    {
                        lbuf = String.Format("backstab: {0} hit a double backstab.", ch.Name);
                        ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf);
                        SingleAttack(ch, victim, "backstab", ObjTemplate.WearLocation.hand_two);
                    }
                }
            }
            else    /* Send a "you miss your backstab" messge & engage. */
            {
                InflictDamage(ch, victim, 0, "backstab", ObjTemplate.WearLocation.hand_one, AttackType.DamageType.pierce);
            }
            return true;
        }