Exemple #1
0
        /// <summary>
        /// Reports current condition verbally.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Report(CharData ch, string[] str)
        {
            string arg = String.Empty;

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

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

            string buf = String.Empty;
            if (str.Length == 0)
            {
                buf += "&nYou report: " + ch.Hitpoints + "/" + ch.GetMaxHit() + " hp " + ch.CurrentMana + "/" +
                       ch.MaxMana + " mana " + ch.CurrentMoves + "/" + ch.MaxMoves + " mv.\r\n";
                ch.SendText(buf);

                buf += "$n&n reports: " + ch.Hitpoints + "/" + ch.GetMaxHit() + " hp " + ch.CurrentMana + "/" +
                       ch.MaxMana + " mana " + ch.CurrentMoves + "/" + ch.MaxMoves + " mv.\r\n";
                SocketConnection.Act(buf, ch, null, null, SocketConnection.MessageTarget.room);
                return;
            }
            //report is essentially a tell, why not use that code?

            buf += arg + " reporting: " + ch.Hitpoints + "/" + ch.GetMaxHit() + " hp " + ch.CurrentMana + "/" +
                   ch.MaxMana + " mana " + ch.CurrentMoves + "/" + ch.MaxMoves + " mv.\r\n";
            CommandType.Interpret(ch, "tell " + buf);
            return;
        }
Exemple #2
0
        /// <summary>
        /// Shows a character's score screen.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Score(CharData ch, string[] str)
        {
            if( ch == null ) return;

            string text = String.Empty;

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

            Affect prev;

            text += "&+WName: &+G" + ch.Name + "&n" + (ch.IsNPC() ? String.Empty : ((PC)ch).Title) + "\r\n";
            text += "&+WRace:&n " + MUDString.PadStr(Race.RaceList[ch.GetRace()].ColorName, 16);
            text += "&+WClass:&n " + MUDString.PadStr(ch.CharacterClass.WholistName, 32) + "&n\r\n";
            text += "&+WLevel: " + MUDString.PadInt(ch.Level, 5) + "     Played: " + (ch.TimePlayed.Hours) + " hours       &+WSex: ";
            text += System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(ch.GetSexString()) + "\r\n";
            if (ch.Fighting == null)
            {
                text += "&+WExperience: &+B" + StringConversion.ExperienceString(ch) + "&n\r\n\r\n";
            }
            text += "&+WCurrent/Max Health: [&n&+g" + MUDString.PadInt(ch.Hitpoints, 5) + "&+W / &n&+g" + MUDString.PadInt(ch.GetMaxHit(), 5);
            text += "&+W]     Coins:     Carried     In Bank\r\n";
            text += "&+WCurrent/Max Moves:  [&n&+g" + MUDString.PadInt(ch.CurrentMoves, 5) + "&+W / &n&+g" + MUDString.PadInt(ch.MaxMoves, 5);
            text += "&+W]     &+WPlatinum      " + MUDString.PadInt(ch.GetPlatinum(), 5) + "        ";
            text += (ch.IsNPC() ? 0 : ((PC)ch).Bank.Platinum) + "\r\n";
            text += "Current/Max Mana:   [&n&+g" + MUDString.PadInt(ch.CurrentMana, 5) + "&+W / &n&+g" + MUDString.PadInt(ch.MaxMana, 5);
            text += "&+W]     &+YGold          " + MUDString.PadInt(ch.GetGold(), 5) + "        " + (ch.IsNPC() ? 0 : ((PC)ch).Bank.Gold) + "\r\n";
            text += "                                        &n&+wSilver        " + MUDString.PadInt(ch.GetSilver(), 5) + "        ";
            text += (ch.IsNPC() ? 0 : ((PC)ch).Bank.Silver) + "\r\n";
            text += "&+WFrags: &+W" + MUDString.PadInt((ch.IsNPC() ? 0 : ((PC)ch).Frags), 3) + "&n                               &n&+yCopper        ";
            text += MUDString.PadInt(ch.GetCopper(), 5) + "        " + (ch.IsNPC() ? 0 : ((PC)ch).Bank.Copper) + "\r\n";
            if (!ch.IsNPC())
            {
                text += "&+WTotal Deaths: &+W" + MUDString.PadInt(((PC)ch).MobDeaths + ((PC)ch).PlayerDeaths, 5) + "&n     &+WMobs Killed: &+W";
                text += MUDString.PadInt(((PC)ch).MobKills, 5) + "&n\r\n&+WPlayers Killed: &+W" + MUDString.PadInt(((PC)ch).PlayerKills, 5);
                text += "&n   &+WPlayer Deaths: &+W" + MUDString.PadInt(((PC)ch).PlayerDeaths, 5) + "&n\r\n";
            }

            if (!ch.IsNPC())
            {
                int divisor = ((PC)ch).Created.Quantity;
                if (divisor == 0)
                    divisor = 1;
                text += String.Format("&+WItems Created: &n{0}    &+WTotal Value: &n{1}  &+WBest: &n{2}  &+WAvg: &n{3}\r\n",
                    MUDString.PadInt(((PC)ch).Created.Quantity, 5),
                    MUDString.PadInt(((PC)ch).Created.TotalCost, 5),
                    MUDString.PadInt(((PC)ch).Created.MaxCost, 5),
                    MUDString.PadInt((((PC)ch).Created.TotalCost / divisor), 5));
                divisor = ((PC)ch).Destroyed.Quantity;
                if (divisor == 0)
                    divisor = 1;
                text += String.Format("&+WItems Destroyed: &n{0}  &+WTotal Value: &n{1}  &+WBest: &n{2}  &+WAvg: &n{3}\r\n",
                    MUDString.PadInt(((PC)ch).Destroyed.Quantity, 5),
                    MUDString.PadInt(((PC)ch).Destroyed.TotalCost, 5),
                    MUDString.PadInt(((PC)ch).Destroyed.MaxCost, 5),
                    MUDString.PadInt((((PC)ch).Destroyed.TotalCost / divisor), 5));
            }

            if (!ch.IsNPC())
            {
                text += "&+WTotal Score: &+W" + ((PC)ch).Score + "&n\r\n";
            }

            if (ch.IsClass(CharClass.Names.monk) || ch.IsClass(CharClass.Names.mystic))
            {
                text += "&+WTradition: &+B" + TraditionData.Names[((PC)ch).Tradition] + "&n\r\n";
                text += "&+WTraining Points: &+B" + (ch.IsNPC() ? 0 : ((PC)ch).SkillPoints) + "&n\r\n";
            }

            if (ch.Followers != null && ch.Followers.Count > 0)
            {
                text += "&+BFollowers:&n\r\n";
                foreach (CharData follower in ch.Followers)
                {
                    if (follower == null)
                    {
                        continue;
                    }
                    text += follower.ShowNameTo(ch, true) + " &n\r\n";
                }
                text += "\r\n";
            }
            if (ch.IsAffected( Affect.AFFECT_POISON))
            {
                text += "&+GYou are poisoned.&n\r\n";
            }

            if ((ch.IsAffected( Affect.AFFECT_DETECT_MAGIC) || ch.IsImmortal())
                    && MUDString.StringsNotEqual(BitvectorFlagType.AffectString(ch.AffectedBy, true), "none"))
            {
                text += "&+BEnchantments: &+W" + BitvectorFlagType.AffectString(ch.AffectedBy, true) + "&n\r\n\r\n";
            }

            if (ch.Affected != null)
            {
                bool printed = false;
                prev = null;
                foreach (Affect affect in ch.Affected)
                {
                    if (!printed)
                    {
                        text += "&+BActive Spells:&+W\r\n";
                        printed = true;
                    }

                    /* Show only new affects to mortals. */
                    if (prev != null && prev.Value == affect.Value
                            && prev.Type == affect.Type && !ch.IsImmortal())
                    {
                        prev = affect;
                        continue;
                    }
                    prev = affect;

                    if (affect.Type == Affect.AffectType.skill && !String.IsNullOrEmpty(affect.Value) && ch.IsImmortal())
                    {
                        text += MUDString.CapitalizeANSIString( Skill.SkillList[affect.Value].Name );
                    }
                    else if (affect.Type == Affect.AffectType.skill && !String.IsNullOrEmpty(affect.Value))
                    {
                        continue;
                    }
                    else if (affect.Type == Affect.AffectType.spell && !String.IsNullOrEmpty(affect.Value))
                    {
                        text += MUDString.CapitalizeANSIString(Spell.SpellList[affect.Value].Name);
                    }
                    else if (affect.Type == Affect.AffectType.song && !String.IsNullOrEmpty(affect.Value))
                    {
                        text += MUDString.CapitalizeANSIString(affect.Value);
                    }
                    else
                    {
                        text += "Something";
                    }

                    if (ch.IsImmortal())
                    {
                        foreach (AffectApplyType apply in affect.Modifiers)
                        {
                            text += " modifies " + StringConversion.AffectApplyString(apply.Location) + " by " + apply.Amount;
                        }
                        text += " for " + affect.Duration + " hours with bits " + affect.AffectString(false) + ".\r\n";
                    }
                    else
                    {
                        if (affect.Duration == 0 && ch.IsAffected( Affect.AFFECT_DETECT_MAGIC))
                        {
                            text += " (fading rapidly)\r\n";
                        }
                        else if (affect.Duration == 1 && ch.IsAffected( Affect.AFFECT_DETECT_MAGIC))
                        {
                            text += " (fading)\r\n";
                        }
                        else
                        {
                            text += "\r\n";
                        }
                    }
                }
            }
            text += "&n";
            ch.SendText(text);
            return;
        }
        /// <summary>
        /// Builds a condition string for a player.
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        public static string ConditionString( CharData ch )
        {
            int percent;

            if( ch.GetMaxHit() > 0 )
                percent = ( 100 * ch.Hitpoints ) / ch.GetMaxHit();
            else
                percent = -1;

            if( percent >= 100 )
                return "&+gexcellent&n";
            if( percent >= 90 )
                return "&+ybarely &n&+gscratched&n";
            if( percent >= 79 )
                return "&+yslightly&+L &n&+gbruised&n";
            if( percent >= 69 )
                return "&+ylightly wounded&n";
            if( percent >= 58 )
                return "&+ymoderately &n&+mwou&+rnded&n";
            if( percent >= 48 )
                return "&+mseverely &n&+rwo&n&+yu&+rn&+yde&n&+rd&n";
            if( percent >= 37 )
                return "&n&+rbleeding&+y copiously&n";
            if( percent >= 27 )
                return "&+rbadly &n&+rwo&+Ru&n&+rn&+Rded&n";
            if( percent >= 16 )
                return "&+yin &n&+R awful shape&n";
            if( ch.Hitpoints > -3 )
                return "&+Rnearly&+L &n&+rdead&n";
            if( ch.Hitpoints > -5 )
                return "&+Lincapacitated, and &+Rbl&n&+re&+Re&n&+rdi&+Rn&n&+rg&+L to death&n";
            if( ch.Hitpoints >= -10 )
                return "&+rmortally &+Rw&n&+rou&+Rnd&N&+re&+Rd&n";
            return "&+Wdead&n";
        }
Exemple #4
0
        /// <summary>
        /// Command to set your level of aggressiveness.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Aggressive(CharData ch, string[] str)
        {
            if( ch == null ) return;

            string arg1 = String.Empty;

            if (ch.IsNPC())
                return;
            if (ch.IsClass(CharClass.Names.paladin))
            {
                ch.SendText("Your beliefs prevent you from acting in such a manner.\r\n");
                return;
            }

            if (arg1.Length > 0)
            {
                if (MUDString.NameContainedIn("off", arg1) || MUDString.NameContainedIn("none", arg1))
                {
                    ((PC)ch).AggressiveLevel = -1;
                }
                else
                {
                    int aggr;
                    Int32.TryParse(arg1, out aggr);
                    if (aggr < -1 || aggr > ch.GetMaxHit())
                    {
                        ch.SendText("Value out of range.\r\n");
                        return;
                    }
                    ((PC)ch).AggressiveLevel = aggr;
                }
            }
            string buf;
            if (((PC)ch).AggressiveLevel == -1)
            {
                buf = "You are not aggressive.\r\n";
            }
            else
            {
                buf = "You are aggressive to creatures if hit points above " + ((PC)ch).AggressiveLevel + ".\r\n";
            }
            ch.SendText(buf);
            return;
        }
Exemple #5
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 #6
0
        /// <summary>
        /// Creates a character based on an object. Used for animate-object-type spells.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public CharData CreateCharacterFromObject( ref Object obj )
        {
            int count;

            MobTemplate mobTemplate = Database.GetMobTemplate( StaticMobs.MOB_NUMBER_OBJECT );
            if( !mobTemplate )
            {
                Log.Error( "CreateCharacterFromObject: null object template.", 0 );
                return null;
            }

            CharData mob = new CharData();

            mob.MobileTemplate = mobTemplate;
            mob.Name = obj._name;
            mob.ShortDescription = obj._shortDescription;
            mob.FullDescription = obj._fullDescription;
            mob.Description = obj._fullDescription;
            mob.CharacterClass = mobTemplate.CharacterClass;
            mob.Level = Math.Max( obj._level, 1 );
            mob.ActionFlags = mobTemplate.ActionFlags;
            mob.CurrentPosition = mobTemplate.DefaultPosition;
            for( count = 0; count < Limits.NUM_AFFECT_VECTORS; ++count )
            {
                mob.AffectedBy[ count ] = mobTemplate.AffectedBy[ count ];
            }
            mob.Alignment = mobTemplate.Alignment;
            mob.Gender = mobTemplate.Gender;
            mob.SetPermRace( mobTemplate.Race );
            mob.CurrentSize = Race.RaceList[ mob.GetRace() ].DefaultSize;
            if (mob.HasActionBit(MobTemplate.ACT_SIZEMINUS))
                mob.CurrentSize--;
            if (mob.HasActionBit(MobTemplate.ACT_SIZEPLUS))
                mob.CurrentSize++;

            mob.CastingSpell = 0;
            mob.CastingTime = 0;
            mob.PermStrength = 55;
            mob.PermIntelligence = 55;
            mob.PermWisdom = 55;
            mob.PermDexterity = 55;
            mob.PermConstitution = 55;
            mob.PermAgility = 55;
            mob.PermCharisma = 55;
            mob.PermPower = 55;
            mob.PermLuck = 55;
            mob.ModifiedStrength = 0;
            mob.ModifiedIntelligence = 0;
            mob.ModifiedWisdom = 0;
            mob.ModifiedDexterity = 0;
            mob.ModifiedConstitution = 0;
            mob.ModifiedAgility = 0;
            mob.ModifiedCharisma = 0;
            mob.ModifiedPower = 0;
            mob.ModifiedLuck = 0;
            mob.Resistant = mobTemplate.Resistant;
            mob.Immune = mobTemplate.Immune;
            mob.Susceptible = mobTemplate.Susceptible;
            mob.Vulnerable = mobTemplate.Vulnerable;
            mob.SetCoins( 0, 0, 0, 0 );
            mob.ArmorPoints = MUDMath.Interpolate( mob.Level, 100, -100 );

            // * MOB HITPOINTS *
            //
            // Was level d 8, upped it to level d 13
            // considering mobs *still* won't have as many hitpoints as some players until
            // at least lvl 10, this shouldn't be too big an upgrade.
            //
            // Mob hitpoints are not based on constitution *unless* they have a
            // constitution modifier from an item, spell, or other affect

            mob.MaxHitpoints = mob.Level * 100;
            mob.Hitpoints = mob.GetMaxHit();

            /*
            * Insert in list.
            */
            Database.CharList.Add( mob );
            // Increment in-game count of mob.
            mobTemplate.NumActive++;
            mob.AddToRoom( obj._inRoom );
            return mob;
        }
        /// <summary>
        /// Builds condition meter of style #1 for a player.
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        static string ConditionMeter( CharData ch )
        {
            int percent;

            if( ch.GetMaxHit() > 0 )
                percent = ( 100 * ch.Hitpoints ) / ch.GetMaxHit();
            else
                percent = -1;

            if( percent >= 100 )
                return "&+L(&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&+L)&n";
            if( percent >= 90 )
                return "&+L(&+C-&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&+R=&+L)&n";
            if( percent >= 79 )
                return "&+L(&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&+R=&n&+r-&+L)&n";
            if( percent >= 69 )
                return "&+L(&+C-&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&+R=&n&+r-&+R=&+L)&n";
            if( percent >= 58 )
                return "&+L(&n&+c=&+C-&n&+c=&+C-&n&+c=&+C-&+R=&n&+r-&+R=&n&+r-&+L)&n";
            if( percent >= 48 )
                return "&+L(&+C-&n&+c=&+C-&n&+c=&+C-&+R=&n&+r-&+R=&n&+r-&+R=&+L)&n";
            if( percent >= 37 )
                return "&+L(&n&+c=&+C-&n&+c=&+C-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+L)&n";
            if( percent >= 27 )
                return "&+L(&+C-&n&+c=&+C-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+R=&+L)&n";
            if( percent >= 16 )
                return "&+L(&n&+c=&+C-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+L)&n";
            if( percent >= 6 )
                return "&+L(&+C-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+R=&+L)&n";
            return "&+L(&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+R=&n&+r-&+L)&n";
        }
Exemple #8
0
        public static void Wimpy(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int wimpy;

            if (str.Length == 0)
            {
                wimpy = ch.Wimpy;
            }
            else
            {
                Int32.TryParse(str[0], out wimpy);
            }

            if (wimpy < 0)
            {
                ch.SendText("&nYour courage exceeds your wisdom.\r\n");
                return;
            }

            if (wimpy > ch.GetMaxHit())
            {
                ch.SendText("&nSuch cowardice ill becomes you.\r\n");
                return;
            }

            ch.Wimpy = wimpy;
            string text = String.Format("&nWimpy set to {0} hit points.\r\n", wimpy);
            ch.SendText(text);
            return;
        }
Exemple #9
0
        /// <summary>
        /// Inflicts damage from a spell, based on the weapon damage() function, but customized for spells.
        /// 
        /// Needs to be cleaned up because it's just too big (600+ lines).
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="victim"></param>
        /// <param name="dam"></param>
        /// <param name="spell"></param>
        /// <param name="damType"></param>
        /// <returns></returns>
        public static bool InflictSpellDamage( CharData ch, CharData victim, int dam, Spell spell, AttackType.DamageType damType )
        {
            if( ch == null || victim == null || victim.CurrentPosition == Position.dead )
                return true;

            // Remove memorization and meditation bits.
            // And invis.
            ch.BreakInvisibility();
            victim.BreakMeditate();
            victim.BreakMemorization();

            if( CheckShrug( ch, victim ) )
                return false;

            if( victim.CurrentPosition == Position.sleeping
                    && !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                    && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                    && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                    && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
            {
                SocketConnection.Act( "$n&n has a rude awakening!", victim, null, null, SocketConnection.MessageTarget.room );
                victim.CurrentPosition = Position.resting;
                if( ch.InRoom == victim.InRoom && ch.FlightLevel == victim.FlightLevel )
                    SetFighting( victim, ch );
            }

            // Check for globe spells.  See also FinishSpell under TargetType.singleCharacterOffensive
            // This check here is just to prevent area effect spells from
            // doing damage if too low level.  The check for direct spells is in
            // Magic.cs
            if (victim.IsAffected( Affect.AFFECT_MAJOR_GLOBE)
                    && (spell.SpellCircle[(int)ch.CharacterClass.ClassNumber] <= 6
                         || spell.Name == "fireshield"
                         || spell.Name == "shockshield"
                         || spell.Name == "soulshield"
                         || spell.Name == "coldshield" ) )
            {
                SocketConnection.Act( "&+RThe globe around $N&+R's body bears the brunt of your assault!&n", ch, null, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "&+RYour globe deflects $n&+R's attack!&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                SocketConnection.Act( "&+R$N&+R's globe deflects $n&+R's attack!&n", ch, null, victim, SocketConnection.MessageTarget.room_vict );
                return false;
            }
            if (victim.IsAffected( Affect.AFFECT_GREATER_SPIRIT_WARD) && spell.SpellCircle[(int)ch.CharacterClass.ClassNumber] <= 5)
            {
                SocketConnection.Act( "&+WThe aura around $N&+W's body bears the brunt of your assault!&n", ch, null, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "&+WYour globe absorbs $n&+W's attack!&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                SocketConnection.Act( "&+W$N&+W's aura absorbs $n&+W's attack!&n", ch, null, victim, SocketConnection.MessageTarget.room_vict );
                return false;
            }
            if (victim.IsAffected( Affect.AFFECT_MINOR_GLOBE) && spell.SpellCircle[(int)ch.CharacterClass.ClassNumber] <= 4)
            {
                SocketConnection.Act( "&+RThe globe around $N&+R's body bears the brunt of your assault!&n", ch, null, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "&+RYour globe deflects $n&+R's attack!&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                SocketConnection.Act( "&+R$N&+R's globe deflects $n&+R's attack!&n", ch, null, victim, SocketConnection.MessageTarget.room_vict );
                return false;
            }
            if (victim.IsAffected( Affect.AFFECT_SPIRIT_WARD) && spell.SpellCircle[(int)ch.CharacterClass.ClassNumber] <= 3)
            {
                SocketConnection.Act( "&+WThe aura around $N&+W's body bears the brunt of your assault!&n", ch, null, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "&+WYour globe absorbs $n&+W's attack!&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                SocketConnection.Act( "&+W$N&+W's aura absorbs $n&+W's attack!&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                return false;
            }

            /*
            * Stop up any residual loopholes.
            */
            // 1275 is average damage from Akiaurn's Power Word
            // I changed this to reflect that.
            if( ( dam > 1275 ) && ch.Level < Limits.LEVEL_AVATAR && ch.GetRace() != Race.RACE_DRAGON )
            {
                string buf3;

                if( ch.IsNPC() && ch.Socket )
                    buf3 = String.Format(
                              "Spell_Damage: {0} from {1} by {2}: > 1275 points with {3} spell!",
                              dam, ch.Name, ch.Socket.Original.Name, spell.Name );
                else
                    buf3 = String.Format(
                              "Spell_Damage: {0} from {1}: > 1275 points with {2} spell!",
                              dam, ch.IsNPC() ? ch.ShortDescription : ch.Name, spell.Name );

                Log.Error( buf3, 0 );
                dam = 1275;
            }

            if (victim.IsAffected( Affect.AFFECT_MINOR_PARA)
                    && !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                    && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                    && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                    && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
            {
                SocketConnection.Act( "$n&n disrupts the magic preventing $N&n from moving.", ch, null, victim, SocketConnection.MessageTarget.room_vict );
                SocketConnection.Act( "You disrupt the magic preventing $N&n from moving.", ch, null, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "&+YYou can move again.&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                victim.RemoveAffect( Affect.AFFECT_MINOR_PARA );
                victim.AffectStrip( Affect.AffectType.spell, "earthen grasp" );
                victim.AffectStrip( Affect.AffectType.spell, "greater earthen grasp");
            }

            bool immune = false;
            if( victim != ch )
            {
                /*
                * Certain attacks are forbidden.
                * Most other attacks are returned.
                */
                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 true;
                Crime.CheckAttemptedMurder( ch, victim );

                if( victim.CurrentPosition > Position.stunned
                        && !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                        && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                        && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                        && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
                {
                    // Offensive spells engage victim if not fighting, and
                    //   caster only if neither are fighting.
                    if( !victim.Fighting && victim.InRoom == ch.InRoom
                            && victim.FlightLevel == ch.FlightLevel )
                    {
                        SetFighting( victim, ch );
                        if( !ch.Fighting )
                            SetFighting( ch, victim );
                        // Can't have prone people automaticaly stand.
                        if( victim.CurrentPosition == Position.standing )
                            victim.CurrentPosition = Position.fighting;
                    }
                    /*
                    * If NPC victim is following, ch might attack victim's master.
                    * No charm check here because charm would be dispelled from
                    * tanking mobile when combat ensues thus ensuring PC charmer is
                    * not harmed.
                    * Check for is_same_group wont work as following mobile is not
                    * always grouped with PC charmer
                    */
                    if( ch.IsNPC()
                            && victim.IsNPC()
                            && victim.Master
                            && victim.Master.InRoom == ch.InRoom
                            && MUDMath.NumberBits( 2 ) == 0 )
                    {
                        StopFighting( ch, false );
                        SetFighting( ch, victim.Master );
                        return false;
                    }
                }

                /*
                * More charm stuff.
                */
                if( victim.Master == ch
                        && !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                        && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                        && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                        && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
                    StopFighting( victim, true );

                /*
                * Hunting stuff...
                */
                if( dam != 0 && victim.IsNPC()
                        && !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                        && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                        && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                        && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
                {
                    StartGrudge( victim, ch, false );
                }

                /*
                * Damage modifiers.
                */
                if (victim.IsAffected( Affect.AFFECT_SANCTUARY))
                    dam /= 2;

                if ((victim.IsAffected( Affect.AFFECT_PROTECT_EVIL)) && ch.IsEvil())
                    dam -= dam / 8;
                else if ((victim.IsAffected( Affect.AFFECT_PROTECT_GOOD)) && ch.IsGood())
                    dam -= dam / 8;

                if( dam < 0 )
                    dam = 0;
            }

            switch( victim.CheckRIS( damType ) )
            {
                case Race.ResistanceType.resistant:
                    dam -= dam / 3;
                    break;
                case Race.ResistanceType.immune:
                    immune = true;
                    dam = 0;
                    break;
                case Race.ResistanceType.susceptible:
                    dam += dam / 2;
                    break;
                case Race.ResistanceType.vulnerable:
                    dam *= 2;
                    break;
            }

            if( ( damType == AttackType.DamageType.wind || damType == AttackType.DamageType.gas || damType == AttackType.DamageType.asphyxiation )
                    && victim.IsAffected( Affect.AFFECT_DENY_AIR))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    victim.SendText( "&+CYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }
            if (damType == AttackType.DamageType.fire && victim.IsAffected( Affect.AFFECT_DENY_FIRE))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    victim.SendText( "&+rYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }
            if( ( damType == AttackType.DamageType.earth || damType == AttackType.DamageType.crushing )
                    && victim.IsAffected(Affect.AFFECT_DENY_EARTH))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    victim.SendText( "&+yYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }
            if( ( damType == AttackType.DamageType.water || damType == AttackType.DamageType.acid || damType == AttackType.DamageType.drowning )
                    && victim.IsAffected(Affect.AFFECT_DENY_WATER))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    victim.SendText( "&+bYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }

            // Check for protection spells that give 25% damage reduction - Xangis
            if (damType == AttackType.DamageType.fire && victim.IsAffected( Affect.AFFECT_PROTECT_FIRE))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.cold && victim.IsAffected( Affect.AFFECT_PROTECT_COLD))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.acid && victim.IsAffected( Affect.AFFECT_PROTECT_ACID))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.gas && victim.IsAffected( Affect.AFFECT_PROTECT_GAS))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.electricity && victim.IsAffected( Affect.AFFECT_PROTECT_LIGHTNING))
                dam = ( dam * 3 ) / 4;

            /*
            * We moved DamageMessage out of the victim != ch if above
            * so self damage would show.  Other valid type_undefined
            * damage is ok to avoid like mortally wounded damage
            */
            if( spell != Spell.SpellList["reserved"]
                    && !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                    && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                    && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                    && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
                SendSpellDamageMessage( ch, victim, dam, spell, immune );

            /*  PC to PC damage quartered.
            *  NPC to PC damage divided by 3.
            */
            if( dam > 0 && !victim.IsNPC() && victim != ch )
            {
                if( !ch.IsNPC() )
                    dam /= 4;
                else
                    dam /= 3;
            }

            /*
            * Hurt the victim.
            * Inform the victim of his new state.
            */
            if( !( victim.GetRace() == Race.RACE_FIRE_ELE && damType == AttackType.DamageType.fire )
                    && !( victim.GetRace() == Race.RACE_WATER_ELE && damType == AttackType.DamageType.water )
                    && !( victim.GetRace() == Race.RACE_EARTH_ELE && damType == AttackType.DamageType.earth )
                    && !( victim.GetRace() == Race.RACE_AIR_ELE && damType == AttackType.DamageType.wind ) )
            {
                /* Added damage exp! */
                // chance added because people level faster and faster as they get higher level...
                // you can now only get damage exp on mobs that con easy or better
                // and there's only a 25% chance per hit of you evern being eligible for damage exp.
                if( MUDMath.NumberPercent() < 25 && victim.Level >= ( ch.Level - 3 ) )
                    ch.GainExperience( Math.Max( 1, dam / 20 ) );
                victim.Hitpoints -= dam;
            }
            else
            {
                string attack;

                if( spell != null && spell != Spell.SpellList["none"] )
                    attack = spell.Name;
                else
                    attack = "it";

                SocketConnection.Act( "$N&n absorbs your $t!", ch, attack, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "You absorb $n&n's $t!", ch, attack, victim, SocketConnection.MessageTarget.victim );
                SocketConnection.Act( "$N&n absorbs $n&n's $t", ch, attack, victim, SocketConnection.MessageTarget.room_vict );
                if( ch.IsImmortal() )
                {
                    string buf4 = String.Format( "You healed {0} damage.",
                                                 victim.GetMaxHit() >= dam + victim.Hitpoints ? dam : victim.GetMaxHit() - victim.Hitpoints );
                    ch.SendText( buf4 );
                }

                victim.Hitpoints = Math.Min( victim.GetMaxHit(), victim.Hitpoints + dam );

                return false;
            }

            if( !victim.IsNPC()
                    && victim.Level >= Limits.LEVEL_AVATAR
                    && victim.Hitpoints < 1 )
                victim.Hitpoints = 1;

            if (victim.IsAffected(Affect.AFFECT_BERZERK)
                    && victim.CurrentPosition <= Position.stunned )
                victim.RemoveAffect(Affect.AFFECT_BERZERK);

            victim.UpdatePosition();

            switch( victim.CurrentPosition )
            {
                case Position.mortally_wounded:
                    victim.SendText(
                        "&+LYou are &+Rmo&n&+rr&+Rt&n&+ral&+Rl&n&+ry&+L wounded, and will die soon, if not aided.&n\r\n" );
                    SocketConnection.Act( "$n&+L is &+Rmo&n&+rr&+Rt&n&+ral&+Rl&n&+ry&+L wounded, and will die soon, if not aided.&n",
                         victim, null, null, SocketConnection.MessageTarget.room, true );
                    StopNotVicious( victim );
                    break;

                case Position.incapacitated:
                    victim.SendText(
                        "&+LYou are incapacitated and will slowly &n&+rbl&+Re&n&+re&+Rd&+L to death, if not aided.\r\n" );
                    SocketConnection.Act( "$n&+L is incapacitated and will slowly &n&+rbl&+Re&n&+re&+Rd&+L to death, if not aided.&n",
                         victim, null, null, SocketConnection.MessageTarget.room, true );
                    StopNotVicious( victim );
                    break;

                case Position.stunned:
                    victim.SendText( "&+LYou are stunned, but will probably recover.&n\r\n" );
                    SocketConnection.Act( "$n&+L is stunned, but will probably recover.&n",
                         victim, null, null, SocketConnection.MessageTarget.room, true );
                    break;

                case Position.dead:
                    SocketConnection.Act( spell.MessageKill, ch, null, victim, SocketConnection.MessageTarget.room_vict );
                    SocketConnection.Act( spell.MessageKill, ch, null, victim, SocketConnection.MessageTarget.character );
                    if( victim == ch )
                    {
                        victim.SendText( "&+LYou have been &+Rsl&n&+ra&+Ri&n&+rn&+L!&n\r\n\r\n" );
                    }
                    else
                    {
                        string buf = String.Format( "&+LYou have been &+Rsl&n&+ra&+Ri&n&+rn&+L by&n {0}&+L!&n\r\n\r\n",
                                                    ch.ShowNameTo( victim, false ) );
                        victim.SendText( buf );
                    }
                    StopFighting( victim, true );
                    SocketConnection.Act( "$n&+L is &n&+rdead&+L!&n", victim, null, null, SocketConnection.MessageTarget.room, true );
                    break;

                default:
                    if( dam > victim.GetMaxHit() / 5 )
                        victim.SendText( "That really did &+RHURT&n!\r\n" );
                    if( victim.Hitpoints < victim.GetMaxHit() / 10 )
                        victim.SendText( "You sure are &n&+rBL&+RE&n&+rE&+RDI&n&+rN&+RG&n!\r\n" );
                    break;
            }

            /*
            * Sleep spells and extremely wounded folks.
            */
            if( !victim.IsAwake() )      /* lets make NPC's not slaughter PC's */
            {
                if( victim.Fighting
                        && victim.Fighting.Hunting
                        && victim.Fighting.Hunting.Who == victim )
                    StopHunting( victim.Fighting );
                if( victim.Fighting
                        && !victim.IsNPC()
                        && ch.IsNPC() )
                    StopFighting( victim, true );
                else
                    StopFighting( victim, false );
            }

            /*
            * Payoff for killing things.
            */
            if( victim.CurrentPosition == Position.dead )
            {
                StopFighting( ch, false );

                if( !victim.HasActionBit(MobTemplate.ACT_NOEXP ) || !victim.IsNPC() )
                    GroupExperienceGain( ch, victim );

                if( !victim.IsNPC() )
                {
                    if( ch.IsNPC() )
                    {
                        ( (PC)victim ).MobDeaths++;
                        if( victim.IsGuild() )
                        {
                            ( (PC)victim ).GuildMembership.MonsterDeaths++;
                            ( (PC)victim ).GuildMembership.Score += CalculateDeathScore( ch, victim );
                        }
                        ( (PC)victim ).Score += CalculateDeathScore( ch, victim );
                    }
                    else
                    {
                        ( (PC)ch ).PlayerKills++;
                        ( (PC)victim ).PlayerDeaths++;

                        ( (PC)victim ).Score += CalculateDeathScore( ch, victim );
                        ( (PC)ch ).Score += CalculateKillScore( ch, victim );

                        if( ch.IsGuild()
                                && victim.IsGuild()
                                && ( (PC)ch ).GuildMembership != ( (PC)victim ).GuildMembership )
                        {
                            ( (PC)ch ).GuildMembership.PlayerKills++;
                            ( (PC)victim ).GuildMembership.PlayerDeaths++;
                            ( (PC)ch ).GuildMembership.Score += CalculateKillScore( ch, victim );
                            ( (PC)victim ).GuildMembership.Score += CalculateDeathScore( ch, victim );
                        }
                    }

                    string logBuf = String.Format( "{0}&n killed by {1}&n at {2}",
                              victim.Name,
                              ( ch.IsNPC() ? ch.ShortDescription : ch.Name ),
                              victim.InRoom.IndexNumber );
                    Log.Trace( logBuf );
                    ImmortalChat.SendImmortalChat( ch, ImmortalChat.IMMTALK_DEATHS, Limits.LEVEL_AVATAR, logBuf );

                    /*
                    * Dying penalty:
                    * 1/2 way back to previous 2 levels.
                    */
                    // Newbies do not lose exp from death.
                    if( ch.Level > 5 )
                        victim.GainExperience( ( 0 - ( ( ( 50 + victim.Level ) * ExperienceTable.Table[ victim.Level ].LevelExperience ) / 400 ) ) );
                    if( victim.Level < 2 && victim.ExperiencePoints < 1 )
                        victim.ExperiencePoints = 1;
                }
                else
                {
                    if( !ch.IsNPC() )
                    {
                        ( (PC)ch ).MobKills++;
                        if( ch.IsGuild() )
                        {
                            ( (PC)ch ).GuildMembership.MonsterKills++;
                            ( (PC)ch ).GuildMembership.Score += CalculateKillScore( ch, victim );
                        }
                        ( (PC)ch ).Score += CalculateKillScore( ch, victim );
                    }
                }

                KillingBlow( ch, victim );

                // Keep in mind after this point the character is not in the
                // CharList, not in any room, and is at the menu.  Don't do
                // anything that would cause a segmentation fault.

                if( ch.IsGuild()
                        && victim.IsGuild()
                        && ( (PC)ch ).GuildMembership != ( (PC)victim ).GuildMembership )
                {
                    ( (PC)ch ).GuildMembership.Score += 20;
                }

                return true;
            }

            if( victim == ch )
            {
                return false;
            }

            /*
            * Wimp out?
            */
            if( victim.IsNPC() && dam > 0 )
            {
                if( ( victim.HasActionBit(MobTemplate.ACT_WIMPY ) && MUDMath.NumberBits( 1 ) == 0
                        && victim.Hitpoints < victim.GetMaxHit() / 5 )
                        || (victim.IsAffected(Affect.AFFECT_CHARM) && victim.Master
                             && victim.Master.InRoom != victim.InRoom ) )
                {
                    StartFearing( victim, ch );
                    StopHunting( victim );
                    CommandType.Interpret(victim, "flee");
                }
            }

            if( !victim.IsNPC() && victim.Hitpoints > 0 && victim.Hitpoints <= victim.Wimpy )
            {
                CommandType.Interpret(victim, "flee");
            }

            return false;
        }
Exemple #10
0
        /// <summary>
        /// Create an instance of a mobile from the provided template.
        /// </summary>
        /// <param name="mobTemplate"></param>
        /// <returns></returns>
        public static CharData CreateMobile( MobTemplate mobTemplate )
        {
            int count;

            if( !mobTemplate )
            {
                Log.Error("CreateMobile: null MobTemplate.", 0);
                throw new NullReferenceException();
            }

            CharData mob = new CharData();

            mob.MobileTemplate = mobTemplate;
            mob.Followers = null;
            mob.Name = mobTemplate.PlayerName;
            mob.ShortDescription = mobTemplate.ShortDescription;
            mob.FullDescription = mobTemplate.FullDescription;
            mob.Description = mobTemplate.Description;
            mob.SpecialFunction = mobTemplate.SpecFun;
            mob.SpecialFunctionNames = mobTemplate.SpecFunNames;
            mob.CharacterClass = mobTemplate.CharacterClass;
            mob.Level = MUDMath.FuzzyNumber( mobTemplate.Level );
            mob.ActionFlags = mobTemplate.ActionFlags;
            mob.CurrentPosition = mobTemplate.DefaultPosition;
            mob.ChatterBotName = mobTemplate.ChatterBotName;
            // TODO: Look up the chatter bot name and load a runtime bot into the variable.
            mob.ChatBot = null;
            for( count = 0; count < Limits.NUM_AFFECT_VECTORS; ++count )
            {
                mob.AffectedBy[ count ] = mobTemplate.AffectedBy[ count ];
            }
            mob.Alignment = mobTemplate.Alignment;
            mob.Gender = mobTemplate.Gender;
            mob.SetPermRace( mobTemplate.Race );
            mob.CurrentSize = Race.RaceList[ mob.GetRace() ].DefaultSize;
            if (mob.HasActionBit(MobTemplate.ACT_SIZEMINUS))
                mob.CurrentSize--;
            if (mob.HasActionBit(MobTemplate.ACT_SIZEPLUS))
                mob.CurrentSize++;

            mob.CastingSpell = 0;
            mob.CastingTime = 0;
            mob.PermStrength = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermIntelligence = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermWisdom = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermDexterity = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermConstitution = MUDMath.Dice( 2, 46 ) + 7;
            mob.PermAgility = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermCharisma = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermPower = MUDMath.Dice( 2, 46 ) + 8;
            mob.PermLuck = MUDMath.Dice( 2, 46 ) + 8;
            mob.ModifiedStrength = 0;
            mob.ModifiedIntelligence = 0;
            mob.ModifiedWisdom = 0;
            mob.ModifiedDexterity = 0;
            mob.ModifiedConstitution = 0;
            mob.ModifiedAgility = 0;
            mob.ModifiedCharisma = 0;
            mob.ModifiedPower = 0;
            mob.ModifiedLuck = 0;
            mob.Resistant = mobTemplate.Resistant;
            mob.Immune = mobTemplate.Immune;
            mob.Susceptible = mobTemplate.Susceptible;
            mob.Vulnerable = mobTemplate.Vulnerable;
            mob.MaxMana = mob.Level * 10;
            if( Race.RaceList[mobTemplate.Race].Coins )
            {
                int level = mobTemplate.Level;
                mob.ReceiveCopper( MUDMath.Dice( 12, level ) / 32 );
                mob.ReceiveSilver( MUDMath.Dice( 9, level ) / 32 );
                mob.ReceiveGold( MUDMath.Dice( 5, level ) / 32 );
                mob.ReceivePlatinum( MUDMath.Dice( 2, level ) / 32 );
            }
            else
            {
                mob.SetCoins( 0, 0, 0, 0 );
            }
            mob.ArmorPoints = MUDMath.Interpolate( mob.Level, 100, -100 );

            // * MOB HITPOINTS *
            //
            // Was level d 8, upped it to level d 13
            // considering mobs *still* won't have as many hitpoints as some players until
            // at least level 10, this shouldn't be too big an upgrade.
            //
            // Mob hitpoints are not based on constitution *unless* they have a
            // constitution modifier from an item, spell, or other affect

            // In light of recent player dissatisfaction with the
            // mob hitpoints, I'm implementing a log curve, using
            //  hp = exp( 2.15135 + level*0.151231)
            // This will will result in the following hp matrix:
            //     Level    Hitpoints
            //      20        175
            //      30        803
            //      40        3643
            //      50        16528
            //      55        35207
            //      60        75000
            mob.MaxHitpoints = MUDMath.Dice( mob.Level, 13 ) + 1;
            // Mob hps are non-linear above level 10.
            if( mob.Level > 20 )
            {
                int upper = (int)Math.Exp( 1.85 + mob.Level * 0.151231 );
                int lower = (int)Math.Exp( 1.80 + mob.Level * 0.151231 );
                mob.MaxHitpoints += MUDMath.NumberRange( lower, upper );
            }
            else if (mob.Level > 10)
            {
                mob.MaxHitpoints += MUDMath.NumberRange(mob.Level * 2, ((mob.Level - 8) ^ 2 * mob.Level) / 2);
            }

            // Demons/devils/dragons gain an extra 30 hitpoints per level (+1500 at lvl 50).
            if (mob.GetRace() == Race.RACE_DEMON || mob.GetRace() == Race.RACE_DEVIL || mob.GetRace() == Race.RACE_DRAGON)
            {
                mob.MaxHitpoints += (mob.Level * 30);
            }

            mob.Hitpoints = mob.GetMaxHit();

            // Horses get more moves, necessary for mounts.
            if(Race.RaceList[ mob.GetRace() ].Name.Equals( "Horse", StringComparison.CurrentCultureIgnoreCase ))
            {
                mob.MaxMoves = 290 + MUDMath.Dice( 4, 5 );
                mob.CurrentMoves = mob.MaxMoves;
            }
            mob.LoadRoomIndexNumber = 0;

            // Insert in list.
            CharList.Add( mob );
            // Increment count of in-game instances of mob.
            mobTemplate.NumActive++;
            return mob;
        }
Exemple #11
0
        /// <summary>
        /// Inflict damage from a single hit.  This could use some cleanup since it's way too unwieldy at more than 600 lines.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="victim"></param>
        /// <param name="dam"></param>
        /// <param name="skill"></param>
        /// <param name="weapon"></param>
        /// <param name="damType"></param>
        /// <returns></returns>
        public static bool InflictDamage(CharData ch, CharData victim, int dam, string skill, ObjTemplate.WearLocation weapon, AttackType.DamageType damType)
        {
            if (ch == null || victim == null)
            {
                return false;
            }

            Object obj;
            bool critical = false;

            if( victim.CurrentPosition == Position.dead || victim.Hitpoints < -10 )
            {
                return true;
            }

            /*
            * Stop up any residual loopholes.
            */
            if( ( dam > 1276 ) && ch.Level < Limits.LEVEL_AVATAR )
            {
                string text;

                if (ch.IsNPC() && ch.Socket)
                {
                    text = String.Format("Damage: {0} from {1} by {2}: > 1276 points with {3} damage type!",
                              dam, ch.Name, ch.Socket.Original.Name, skill);
                }
                else
                {
                    text = String.Format("Damage: {0} from {1}: > 1276 points with {2} damage type!",
                              dam, ch.IsNPC() ? ch.ShortDescription : ch.Name, skill);
                }
                Log.Error( text, 0 );
                dam = 1276;
            }

            // Remove memorization and meditation bits - Xangis
            victim.BreakMeditate();
            victim.BreakMemorization();
            if (victim.IsAffected( Affect.AFFECT_MINOR_PARA))
            {
                SocketConnection.Act( "$n&n disrupts the magic preventing $N&n from moving.", ch, null, victim, SocketConnection.MessageTarget.room_vict );
                SocketConnection.Act( "You disrupt the magic preventing $N&n from moving.", ch, null, victim, SocketConnection.MessageTarget.character );
                SocketConnection.Act( "&+YYou can move again.&n", ch, null, victim, SocketConnection.MessageTarget.victim );
                victim.RemoveAffect( Affect.AFFECT_MINOR_PARA );
            }

            bool immune = false;
            if( victim != ch )
            {
                /*
                * Certain attacks are forbidden.
                * Most other attacks are returned.
                */
                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 == null )
                    return true;
                Crime.CheckAttemptedMurder( ch, victim );
                if( victim.CurrentPosition > Position.stunned )
                {
                    if( !victim.Fighting )
                        SetFighting( victim, ch );
                    // Can't have prone people automatically stand
                    if( victim.CurrentPosition == Position.standing )
                        victim.CurrentPosition = Position.fighting;

                    if( !ch.Fighting )
                        SetFighting( ch, victim );

                    /*
                    * If NPC victim is following, ch might attack victim's master.
                    * No charm check here because charm would be dispelled from
                    * tanking mobile when combat ensues thus ensuring PC charmer is
                    * not harmed.
                    * Check for IsSameGroup wont work as following mobile is not
                    * always grouped with PC charmer
                    *
                    * Added a check for whether ch has switch skill.  If not,
                    * much lower chancing of retargetting
                    */
                    if( ch.IsNPC()
                            && victim.IsNPC()
                            && victim.Master
                            && victim.Master.InRoom == ch.InRoom
                            && MUDMath.NumberBits( 2 ) == 0 )
                    {
                        StartGrudge( ch, victim.Master, false );
                    }
                }

                /*
                * More charm stuff.
                */
                if( victim.Master == ch )
                {
                    StopFighting( victim, true );
                }

                ch.BreakInvisibility();

                /*
                * Hunting stuff...
                */
                if( dam != 0 && victim.IsNPC() )
                {
                    /* StartGrudge is combined StartHating and StartHunting */
                    StartGrudge( victim, ch, false );
                }

                /*
                * Damage modifiers.
                */

                // Critical hits for double damage
                // Average of 5% for those that have average luck
                // Gnomes could concievably have 10%
                if( MUDMath.NumberPercent() < ( 2 + ( ch.GetCurrLuck() / 18 ) ) && dam > 0 )
                {
                    ch.SendText( "&+WYou score a CRITICAL HIT!&n\r\n" );
                    dam *= 2;
                    critical = true;
                }

                if( victim.IsAffected( Affect.AFFECT_SANCTUARY ) )
                    dam /= 2;

                if( victim.IsAffected( Affect.AFFECT_PROTECT_EVIL ) && ch.IsEvil() )
                    dam -= dam / 8;
                else if( victim.IsAffected( Affect.AFFECT_PROTECT_GOOD ) && ch.IsGood() )
                    dam -= dam / 8;

                // Check stoneskin.  People not affected by a stoneskin affect
                // cannot lose their stoneskin for any reason.  This should mean
                // that mobs will keep their stoneskin and players should always
                // have a chance to lose it, since no player should ever be
                // setbit stoneskin.
                //
                // The bool value of found is used so that we can have them
                // take full damage when their stoneskin shatters, but get the
                // damage reduction if they are either a mob or their stoneskin
                // wears off that round.
                //
                /* Yeah, yeah.. so maybe backstabs shouldn't be aff'd. */
                // Actually they should be affected, but they should have a much
                // higher chance of getting through (say 30-70%).
                //
                // Critical hits will now go through stoneskin
                // automatically
                if (!critical && victim.IsAffected( Affect.AFFECT_STONESKIN) &&
                        ( skill != "backstab" || MUDMath.NumberPercent() < ( 25 + ch.Level ) ) )
                {
                    bool found = false;
                    for (int i = (victim.Affected.Count - 1); i >= 0; i--)
                    {
                        if( victim.Affected[i].HasBitvector( Affect.AFFECT_STONESKIN ) )
                        {
                            // Small chance of shattering the stoneskin on a good hit.
                            // Reduced chance by about 20%
                            if( dam >= 25 && MUDMath.NumberPercent() <= ( dam / 12 ) )
                            {
                                victim.SendText( "&+LYour stoneskin is shattered by the massive blow!&n\r\n" );
                                SocketConnection.Act( "$n&n's massive blow shatters $N&n's stoneskin!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim );
                                SocketConnection.Act( "Your massive blow shatters $N&n's stoneskin!", ch, null, victim, SocketConnection.MessageTarget.character );
                                victim.RemoveAffect(victim.Affected[i]);
                                found = true;
                            }
                            else if( dam > 0 ) // Added check for actual damage
                            {
                                for( int j = 0; j < victim.Affected[i].Modifiers.Count; j++ )
                                {
                                    victim.Affected[i].Modifiers[j].Amount--;
                                    if (victim.Affected[i].Modifiers[j].Amount < 1)
                                    {
                                        victim.RemoveAffect(victim.Affected[i]);
                                        victim.SendText("&+LYou feel your skin soften and return to normal.&n\r\n");
                                    }
                                    dam /= 15;
                                    found = true;
                                }
                            }
                        }
                    }
                    // This means they're Affect.AFFECT_STONESKIN as an innate/permenant.
                    // We will still allow it to shatter, but it will refresh itself
                    // upon a mob update.  Because of this, we make it easier to shatter.
                    // No damage reduction when it shatters.
                    if( !found )
                    {
                        if( dam >= 8 && MUDMath.NumberPercent() <= ( dam / 8 ) )
                        {
                            victim.SendText( "&+LYour stoneskin is shattered by the massive blow!&n\r\n" );
                            SocketConnection.Act( "$n&n's massive blow shatters $N&n's stoneskin!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim );
                            SocketConnection.Act( "Your massive blow shatters $N&n's stoneskin!", ch, null, victim, SocketConnection.MessageTarget.character );
                            victim.RemoveAffect( Affect.AFFECT_STONESKIN );
                        }
                        else
                        {
                            dam = dam / 15 != 0 ? dam / 15 : 1;
                        }
                    }

                }

                if( dam < 0 )
                    dam = 0;

                /*
                * Check for disarm, trip, parry, dodge and shield block.
                */
                if (skill != "barehanded fighting" || skill == "kick")
                {
                    // Trip and disarm removed because those should be handled
                    // by each individual mob's special function.
                    if( ch.IsNPC()
                            && ch.HasInnate( Race.RACE_WEAPON_WIELD )
                            && MUDMath.NumberPercent() < Math.Min( 25, Math.Max( 10, ch.Level ) )
                            && !victim.IsNPC() )
                        UseMagicalItem( ch );
                }
            }

            switch( victim.CheckRIS( damType ) )
            {
                case Race.ResistanceType.resistant:
                    dam -= dam / 3;
                    break;
                case Race.ResistanceType.immune:
                    immune = true;
                    dam = 0;
                    break;
                case Race.ResistanceType.susceptible:
                    dam += dam / 2;
                    break;
                case Race.ResistanceType.vulnerable:
                    dam *= 2;
                    break;
                default:
                    break;
            }

            if( ( damType == AttackType.DamageType.wind || damType == AttackType.DamageType.gas || damType == AttackType.DamageType.asphyxiation )
                    && victim.IsAffected(Affect.AFFECT_DENY_AIR))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    ch.SendText( "&+CYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }
            if (damType == AttackType.DamageType.fire && victim.IsAffected( Affect.AFFECT_DENY_FIRE))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    ch.SendText( "&+rYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }
            if( ( damType == AttackType.DamageType.earth || damType == AttackType.DamageType.crushing )
                    && victim.IsAffected( Affect.AFFECT_DENY_EARTH))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    ch.SendText( "&+yYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }
            if( ( damType == AttackType.DamageType.water || damType == AttackType.DamageType.acid || damType == AttackType.DamageType.drowning )
                    && victim.IsAffected( Affect.AFFECT_DENY_WATER))
            {
                if( MUDMath.NumberPercent() < 50 )
                {
                    ch.SendText( "&+bYou deny the damage.&n\r\n" );
                    immune = true;
                    dam = 0;
                }
                else
                    dam -= dam / 5;
            }

            // Check for protection spells that give 25% damage reduction - Xangis
            if (damType == AttackType.DamageType.fire && victim.IsAffected( Affect.AFFECT_PROTECT_FIRE))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.cold && victim.IsAffected( Affect.AFFECT_PROTECT_COLD))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.acid && victim.IsAffected( Affect.AFFECT_PROTECT_ACID))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.gas && victim.IsAffected( Affect.AFFECT_PROTECT_GAS))
                dam = ( dam * 3 ) / 4;
            else if (damType == AttackType.DamageType.electricity && victim.IsAffected( Affect.AFFECT_PROTECT_LIGHTNING))
                dam = ( dam * 3 ) / 4;

            // Barkskin protects from 8% of slash and 12% of pierce damage.
            if (victim.IsAffected( Affect.AFFECT_BARKSKIN))
            {
                if (skill == "1h slashing" || skill == "2h slashing")
                    dam = dam * 11 / 12;
                else if (skill == "1h piercing" || skill == "2h piercing")
                    dam = dam * 7 / 8;
            }

            // Check for vampiric touch for anti-paladins and vampires
            if( weapon == ObjTemplate.WearLocation.hand_one || weapon == ObjTemplate.WearLocation.hand_two || weapon == ObjTemplate.WearLocation.hand_three || weapon == ObjTemplate.WearLocation.hand_four )
            {
                if( ( ( ch.IsClass(CharClass.Names.antipaladin) || ch.GetRace() == Race.RACE_VAMPIRE )
                        && skill == "barehanded fighting" && !Object.GetEquipmentOnCharacter(ch, weapon)) || (ch.IsAffected( Affect.AFFECT_VAMP_TOUCH)
                             && ( !( obj = Object.GetEquipmentOnCharacter( ch, weapon ) ) || obj.HasAffect( Affect.AFFECT_VAMP_TOUCH ) ) ) )
                {
                    ch.Hitpoints += dam / 3;
                    if( ch.Hitpoints > ( ch.GetMaxHit() + 50 + ch.Level * 5 ) )
                    {
                        ch.Hitpoints = ch.GetMaxHit() + 50 + ch.Level * 5;
                    }
                }
            }

            /* PC to PC damage quartered.
            *  NPC to PC damage divided by 3.
            */
            if( dam > 0 && !victim.IsNPC() && victim != ch )
            {
                if( !ch.IsNPC() )
                    dam /= 4;
                else
                    dam /= 3;
            }

            /*
            * Just a check for anything that is excessive damage
            * Send a log message, keeping the imms on their toes
            * Changed this from 300 to 250 'cause hitters get more than one
            *  attack/round and w/haste that's 1000 possible in the time one fist
            *  goes off.  That's more than the fist might do and it has to be
            *  memmed.
            */
            if (dam > 250 && skill != "backstab" )
            {
                string buf4;
                if (!string.IsNullOrEmpty(skill))
                {
                    buf4 = String.Format("Excessive damage: {0} attacking {1} for {2}, skill = {3}({4}).",
                              ch.Name, victim.Name, dam, Skill.SkillList[skill].DamageText, skill);
                }
                else
                {
                    buf4 = String.Format("Excessive damage: {0} attacking {1} for {2}, unknown damage type.",
                              ch.Name, victim.Name, dam);
                }
                Log.Trace( buf4 );
            }

            /*
            * We moved DamageMessage out of the victim != ch if above
            * so self damage would show.  Other valid type_undefined
            * damage is ok to avoid like mortally wounded damage
            */
            if (!String.IsNullOrEmpty(skill))
            {
                SendDamageMessage(ch, victim, dam, skill, weapon, immune);
            }

            victim.Hitpoints -= dam;

            /* Check for HOLY_SACRFICE and BATTLE_ECSTASY */
            if( dam > 0 && victim != ch )
            {
                CharData groupChar;
                if (victim.IsAffected( Affect.AFFECT_HOLY_SACRIFICE) && victim.GroupLeader)
                {
                    for( groupChar = victim.GroupLeader; groupChar; groupChar = groupChar.NextInGroup )
                    {
                        if( groupChar == victim || groupChar.InRoom != ch.InRoom )
                            continue;
                        groupChar.Hitpoints += dam / 5;
                        if (groupChar.Hitpoints > groupChar.GetMaxHit() + 50 + groupChar.Level * 5)
                        {
                            groupChar.Hitpoints = groupChar.GetMaxHit() + 50 + groupChar.Level * 5;
                        }
                    } //end for loop
                } //end if holy sac
                if( ch.GroupLeader != null )
                {
                    for( groupChar = ch.GroupLeader; groupChar != null; groupChar = groupChar.NextInGroup )
                    {
                        if( groupChar == victim || groupChar.InRoom != ch.InRoom )
                            continue;
                        if( groupChar.IsAffected( Affect.AFFECT_BATTLE_ECSTASY ) )
                        {
                            groupChar.Hitpoints += dam / 20;
                            if( groupChar.Hitpoints > groupChar.GetMaxHit() + 50 + groupChar.Level * 5 )
                                groupChar.Hitpoints = groupChar.GetMaxHit() + 50 + groupChar.Level * 5;
                        } // end if battle ecstasy
                    } //end for loop
                } //end if grouped
            } //end if

            // Make sure if they got an instant kill roll that the victim dies.
            if (skill == "instant kill")
            {
                if( victim.GetRace() != Race.RACE_DEVIL
                        && victim.GetRace() != Race.RACE_DEMON
                        && victim.GetRace() != Race.RACE_GOD )
                    victim.Hitpoints = -20;
            }

            /* Added damage exp! */
            // chance added because people level faster and faster as they get higher level...
            // to be worked out when exp is redone.
            // you can now only get damage exp on mobs that con easy or better
            // and there's only a 25% chance per hit of you evern being eligible for damage exp.
            if( MUDMath.NumberPercent() < 25 && victim.Level >= ( ch.Level - 3 ) )
                ch.GainExperience( Math.Max( 1, dam / 20 ) );

            if( !victim.IsNPC()
                    && victim.Level >= Limits.LEVEL_AVATAR
                    && victim.Hitpoints < 1 )
                victim.Hitpoints = 1;

            /*
            * Magic shields that retaliate
            *
            * Apparently two people with the same sort of shield do not
            * take damage from each other
            */
            if( ( dam > 1 ) && victim != ch )
            {
                if( victim.IsAffected( Affect.AFFECT_FIRESHIELD )
                        && !ch.IsAffected( Affect.AFFECT_FIRESHIELD ) )
                    InflictSpellDamage( victim, ch, dam / 2, "fireshield", AttackType.DamageType.fire );

                if (victim.IsAffected( Affect.AFFECT_COLDSHIELD)
                        && !ch.IsAffected(Affect.AFFECT_COLDSHIELD))
                    InflictSpellDamage( victim, ch, dam / 2, "coldshield", AttackType.DamageType.cold );

                if (victim.IsAffected(Affect.AFFECT_SHOCK_SHIELD)
                        && !ch.IsAffected(Affect.AFFECT_SHOCK_SHIELD))
                    InflictSpellDamage( victim, ch, dam / 2, "shockshield", AttackType.DamageType.electricity );

                /* Soulshield is a complex one.  If the attacker and victim are of
                * opposite alignment, the shield retaliates with 1/2 damage just like
                * any other shield.  If the victim is neutral and the attacker is
                * not, the shield retaliates with 1/4 damage.  If the victim is good
                * or evil and the attacker is neutral, the shield retaliates with
                * 1/8 damage.  If the attacker and victim are of same alignment,
                * the shield does nothing.
                */
                if (victim.IsAffected(Affect.AFFECT_SOULSHIELD)
                        && !ch.IsAffected(Affect.AFFECT_SOULSHIELD))
                {
                    if( victim.IsEvil() && ch.IsGood() )
                        InflictSpellDamage(victim, ch, dam / 2, "soulshield", AttackType.DamageType.harm);
                    else if( victim.IsGood() && ch.IsEvil() )
                        InflictSpellDamage(victim, ch, dam / 2, "soulshield", AttackType.DamageType.harm);
                    else if( victim.IsNeutral() && ( ch.IsEvil() || ch.IsGood() ) )
                        InflictSpellDamage(victim, ch, dam / 4, "soulshield", AttackType.DamageType.harm);
                    else if( victim.IsGood() && ch.IsNeutral() )
                        InflictSpellDamage(victim, ch, dam / 8, "soulshield", AttackType.DamageType.harm);
                    else if( victim.IsEvil() && ch.IsNeutral() )
                        InflictSpellDamage(victim, ch, dam / 8, "soulshield", AttackType.DamageType.harm);
                }
            }

            if (victim.IsAffected( Affect.AFFECT_BERZERK ) && victim.CurrentPosition <= Position.stunned )
                victim.RemoveAffect(Affect.AFFECT_BERZERK);

            if (dam > 0 && skill != "barehanded fighting"
                    && IsWieldingPoisoned( ch, weapon )
                    && !Magic.SpellSavingThrow( ch.Level, victim, AttackType.DamageType.poison ) )
            {
                InflictPoison( "poison_weapon", ch.Level, IsWieldingPoisoned( ch, weapon ), ch, victim );
                SocketConnection.Act( "$n&n suffers from the &+Gpoison&n inflicted upon $m.", victim, null, null, SocketConnection.MessageTarget.room, true );
                Object.StripAffect( Object.GetEquipmentOnCharacter( ch, weapon ), Affect.AffectType.skill, "poison weapon" );
            }

            victim.UpdatePosition();

            switch( victim.CurrentPosition )
            {
                case Position.mortally_wounded:
                    victim.SendText(
                        "&+LYou are &+Rmo&n&+rr&+Rt&n&+ral&+Rl&n&+ry&+L wounded, and will die soon, if not aided.&n\r\n" );
                    SocketConnection.Act( "$n&+L is &+Rmo&n&+rr&+Rt&n&+ral&+Rl&n&+ry&+L wounded, and will die soon, if not aided.&n",
                         victim, null, null, SocketConnection.MessageTarget.room, true );
                    StopNotVicious( victim );
                    break;

                case Position.incapacitated:
                    victim.SendText(
                        "&+LYou are incapacitated and will &n&+rbl&+Re&n&+re&+Rd&+L to death, if not aided.&n\r\n" );
                    SocketConnection.Act( "$n&+L is incapacitated and will slowly &n&+rbl&+Re&n&+re&+Rd&+L to death, if not aided.&n",
                         victim, null, null, SocketConnection.MessageTarget.room, true );
                    StopNotVicious( victim );
                    break;

                case Position.stunned:
                    victim.SendText( "&+LYou are stunned, but will probably recover.&n\r\n" );
                    SocketConnection.Act( "$n&+L is stunned, but will probably recover.&n",
                         victim, null, null, SocketConnection.MessageTarget.room, true );
                    break;

                case Position.dead:
                    if( victim == ch )
                    {
                        victim.SendText( "&+LYou have been &+Rsl&n&+ra&+Ri&n&+rn&+L!&n\r\n\r\n" );
                    }
                    else
                    {
                        string buf = String.Format( "&+LYou have been &+Rsl&n&+ra&+Ri&n&+rn&+L by&n {0}&+L!&n\r\n\r\n",
                                                    ch.ShowNameTo( victim, false ) );
                        victim.SendText( buf );
                    }
                    /* Added this to stop a bug. */
                    Combat.StopFighting( victim, true );
                    SocketConnection.Act( "$n&+L is &n&+rdead&+L!&n", victim, null, null, SocketConnection.MessageTarget.room, true );
                    break;

                default:
                    if( dam > victim.GetMaxHit() / 5 )
                        victim.SendText( "That really did &+RHURT&n!\r\n" );
                    if( victim.Hitpoints < victim.GetMaxHit() / 10 )
                        victim.SendText( "You sure are &n&+rBL&+RE&n&+rE&+RDI&n&+rN&+RG&n!\r\n" );
                    break;
            }

            // Check for weapon procs
            if( ( obj = Object.GetEquipmentOnCharacter( ch, weapon ) ) && Position.dead != victim.CurrentPosition )
            {
                if( obj.SpecFun.Count > 0 )
                    obj.CheckSpecialFunction(true);
            }

            /*
            * Sleep spells and extremely wounded folks.
            */
            if( !victim.IsAwake() )      /* lets make NPC's not slaughter PC's */
            {
                if( victim.Fighting
                        && victim.Fighting.Hunting
                        && victim.Fighting.Hunting.Who == victim )
                    StopHunting( victim.Fighting );
                if( victim.Fighting
                        && !victim.IsNPC()
                        && ch.IsNPC() )
                    StopFighting( victim, true );
                else
                    StopFighting( victim, false );
            }

            /*
            * Payoff for killing things.
            */
            if( victim.CurrentPosition == Position.dead )
            {
                // Done in attempt to squelch the combat continuation bug
                StopFighting( victim, true );

                if( !victim.HasActionBit(MobTemplate.ACT_NOEXP ) || !victim.IsNPC() )
                    GroupExperienceGain( ch, victim );

                if( ch.IsNPC() )
                {
                    if( ch.Hunting )
                    {
                        if( ch.Hunting.Who == victim )
                            StopHunting( ch );
                    }
                    if( ch.IsHating(victim) )
                    {
                        ch.StopHating( victim );
                    }
                }

                if( !victim.IsNPC() )
                {
                    if( ch.IsNPC() )
                    {
                        ( (PC)victim ).MobDeaths++;
                        if( victim.IsGuild() )
                        {
                            ( (PC)victim ).GuildMembership.MonsterDeaths++;
                            ( (PC)victim ).GuildMembership.Score += CalculateDeathScore( ch, victim );
                        }
                        ( (PC)victim ).Score += CalculateDeathScore( ch, victim );

                    }
                    else
                    {
                        ( (PC)ch ).PlayerKills++;
                        ( (PC)victim ).PlayerDeaths++;

                        ( (PC)victim ).Score += CalculateDeathScore( ch, victim );
                        ( (PC)ch ).Score += CalculateKillScore( ch, victim );

                        if( ch.IsGuild()
                                && victim.IsGuild()
                                && ( (PC)ch ).GuildMembership != ( (PC)victim ).GuildMembership )
                        {
                            ( (PC)ch ).GuildMembership.PlayerKills++;
                            ( (PC)victim ).GuildMembership.PlayerDeaths++;
                            ( (PC)ch ).GuildMembership.Score += CalculateKillScore( ch, victim );
                            ( (PC)victim ).GuildMembership.Score += CalculateDeathScore( ch, victim );
                        }
                    }

                    string logBuf = String.Format( "{0}&n killed by {1}&n at {2}",
                              victim.Name, ( ch.IsNPC() ? ch.ShortDescription : ch.Name ),
                              victim.InRoom.IndexNumber );
                    Log.Trace( logBuf );
                    ImmortalChat.SendImmortalChat( ch, ImmortalChat.IMMTALK_DEATHS, Limits.LEVEL_AVATAR, logBuf );

                    /*
                    * Dying penalty:
                    *
                    * At level 1 you lose 12.5% of a level.
                    * At level 50 you lose 25% of a level.
                    */
                    // Made it so people level 5 and under lose no exp from death.
                    if( ch.Level > 5 )
                        victim.GainExperience( ( 0 - ( ( ( 50 + victim.Level ) * ExperienceTable.Table[ victim.Level ].LevelExperience ) / 400 ) ) );
                    if( victim.Level < 2 && victim.ExperiencePoints < 1 )
                        victim.ExperiencePoints = 1;

                }
                else
                {
                    if( !ch.IsNPC() )
                    {
                        ( (PC)ch ).MobKills++;
                        if( ch.IsGuild() )
                        {
                            ( (PC)ch ).GuildMembership.MonsterKills++;
                            ( (PC)ch ).GuildMembership.Score += CalculateKillScore( ch, victim );
                        }
                        ( (PC)ch ).Score += CalculateKillScore( ch, victim );
                    }
                }
                KillingBlow( ch, victim );

                return true;
            }

            if( victim == ch )
            {
                return false;
            }

            /*
            * Wimp out?
            */
            if( victim.IsNPC() && dam > 0 )
            {
                if( ( victim.HasActionBit(MobTemplate.ACT_WIMPY ) && MUDMath.NumberBits( 1 ) == 0
                        && victim.Hitpoints < victim.GetMaxHit() / 5 )
                        || (victim.IsAffected( Affect.AFFECT_CHARM) && victim.Master
                             && victim.Master.InRoom != victim.InRoom ) )
                {
                    StartFearing( victim, ch );
                    StopHunting( victim );
                    CommandType.Interpret(victim, "flee");
                }
            }

            if( !victim.IsNPC() && victim.Hitpoints > 0 && victim.Hitpoints <= victim.Wimpy )
            {
                CommandType.Interpret(victim, "flee");
            }

            return false;
        }
Exemple #12
0
        public void Restore(CharData victim)
        {
            if (victim == null) return;

            if (victim.Hitpoints < victim.GetMaxHit())
                victim.Hitpoints = victim.GetMaxHit();
            victim.CurrentMana = victim.MaxMana;
            victim.CurrentMoves = victim.MaxMoves;
            if (!victim.IsNPC())
            {
                ((PC)victim).Hunger = 48;
                ((PC)victim).Thirst = 48;
                ((PC)victim).Drunk = 0;
                victim.PurgeInnateTimers();
            }
            if (victim.IsAffected(Affect.AFFECT_BLIND))
                victim.RemoveBlindness();
            if (victim.IsAffected(Affect.AFFECT_POISON))
                victim.RemovePoison();
            victim.UpdatePosition();
            SocketConnection.Act("$n has restored you.", this, null, victim, SocketConnection.MessageTarget.victim);
            return;
        }
Exemple #13
0
        /// <summary>
        /// Regeneration and natural healing.
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        public static int HitGain( CharData ch )
        {
            int gain;
            int percent = 0;

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

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

            gain = 1;
            percent = 100;

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

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

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

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

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

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

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

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

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

            return Math.Min( gain, ch.GetMaxHit() - ch.Hitpoints );
        }
Exemple #14
0
        public static void ScribeScroll(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object scroll;
            Spell spell;

            if (String.IsNullOrEmpty(str[0]))
            {
                ch.SendText("Scribe what spell?\r\n");
                return;
            }

            if (!(scroll = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one)))
            {
                ch.SendText("You hold nothing in your hand.\r\n");
                return;
            }

            if (scroll.ItemType != ObjTemplate.ObjectType.scroll)
            {
                ch.SendText("You are not holding a &+Wparchment&n.\r\n");
                return;
            }

            if ((spell = StringLookup.SpellLookup(str[0])) == null)
            {
                ch.SendText("You don't know any spells by that _name.\r\n");
                return;
            }

            SocketConnection.Act("$n begins writing a &+Wscroll&n.", ch, scroll, null, SocketConnection.MessageTarget.room);
            ch.WaitState(Skill.SkillList["Scribe"].Delay);

            ch.PracticeSkill("Scribe");

            if (!ch.IsNPC()
                    && (MUDMath.NumberPercent() > ((PC)ch).SkillAptitude["brew"] ||
                         MUDMath.NumberPercent() > ((ch.GetCurrInt() - 13) * 5 +
                                               (ch.GetCurrWis() - 13) * 3)))
            {
                SocketConnection.Act("$p&n bursts in &n&+rflames&n!", ch, scroll, null, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$p&n bursts in &+Rflames&n!", ch, scroll, null, SocketConnection.MessageTarget.room);
                scroll.RemoveFromWorld();
                Combat.InflictDamage(ch, ch, ch.GetMaxHit(), "Scribe", ObjTemplate.WearLocation.none, AttackType.DamageType.fire);
                return;
            }

            scroll.Level = ch.Level * 2 / 3;
            scroll.Values[0] = ch.Level / 3;
            ch.ImprintSpell(spell, ch.Level, scroll);
            return;
        }
Exemple #15
0
        /// <summary>
        /// Builds a condition meter of style #2 for a player.
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        static string ConditionMeter2( CharData ch )
        {
            if (ch == null) return String.Empty;
            int percent;

            if( ch.GetMaxHit() > 0 )
                percent = ( 100 * ch.Hitpoints ) / ch.GetMaxHit();
            else
                percent = -1;

            if( percent >= 100 )
                return "&+L(&+r+++&+y++&+Y++&n&+g+++&+L)&n";
            if( percent >= 90 )
                return "&+L(&+r+++&+y++&+Y++&n&+g++&+L-&+L)&n";
            if( percent >= 79 )
                return "&+L(&+r+++&+y++&+Y++&n&+g+&+L--&+L)&n";
            if( percent >= 69 )
                return "&+L(&+r+++&+y++&+Y++&+L---&+L)&n";
            if( percent >= 58 )
                return "&+L(&+r+++&+y++&+Y+&+L----&+L)&n";
            if( percent >= 48 )
                return "&+L(&+r+++&+y++&+L-----&+L)&n";
            if( percent >= 37 )
                return "&+L(&+r+++&+y+&+L------&+L)&n";
            if( percent >= 27 )
                return "&+L(&+r+++&+L-------&+L)&n";
            if( percent >= 16 )
                return "&+L(&+r++&+L--------&+L)&n";
            if( percent >= 6 )
                return "&+L(&+r+&+L---------&+L)&n";
            return "&+L(&+L----------&+L)&n";
        }
Exemple #16
0
        public static void Brew(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object potion;
            Spell spell;

            if (str.Length == 0)
            {
                ch.SendText("Which spell do you want to brew into a &+Lpotion&n?\r\n");
                return;
            }

            if (!(potion = Object.GetEquipmentOnCharacter(ch, ObjTemplate.WearLocation.hand_one)))
            {
                ch.SendText("You hold nothing in your hand.\r\n");
                return;
            }

            if (potion.ItemType != ObjTemplate.ObjectType.potion)
            {
                ch.SendText("You are not holding a vial.\r\n");
                return;
            }

            if ((spell = StringLookup.SpellLookup(str[0])) == null)
            {
                ch.SendText("You don't know any spells by that _name.\r\n");
                return;
            }

            if (spell.ValidTargets != TargetType.singleCharacterDefensive
                    && spell.ValidTargets != TargetType.self)
            {
                ch.SendText("You cannot brew that spell.\r\n");
                return;
            }

            SocketConnection.Act("$n begins preparing a &+Lpotion&n.", ch, potion, null, SocketConnection.MessageTarget.room);
            ch.WaitState(Skill.SkillList["brew"].Delay);

            ch.PracticeSkill("brew");

            if (!ch.IsNPC() && (MUDMath.NumberPercent() > ((PC)ch).SkillAptitude["brew"] ||
                MUDMath.NumberPercent() > ((ch.GetCurrInt() - 13) * 5 + (ch.GetCurrWis() - 13) * 3)))
            {
                SocketConnection.Act("$p&n explodes violently!", ch, potion, null, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$p&n explodes violently!", ch, potion, null, SocketConnection.MessageTarget.room);
                potion.RemoveFromWorld();
                Combat.InflictDamage(ch, ch, ch.GetMaxHit() / 16, "brew", ObjTemplate.WearLocation.none, AttackType.DamageType.energy);
                return;
            }

            potion.Level = ch.Level / 2;
            potion.Values[0] = ch.Level / 4;
            ch.ImprintSpell(spell, ch.Level, potion);
            return;
        }
Exemple #17
0
        /// <summary>
        /// Builds a condition string of style #2 for a player.
        /// </summary>
        /// <param name="ch"></param>
        /// <returns></returns>
        static string ConditionString2( CharData ch )
        {
            int percent;

            if( ch.GetMaxHit() > 0 )
                percent = ( 100 * ch.Hitpoints ) / ch.GetMaxHit();
            else
                percent = -1;

            if( percent >= 100 )
                return "&+CExcellent&n";
            if( percent >= 90 )
                return "&+LBarely &n&+cScratched&n";
            if( percent >= 79 )
                return "&+CBa&n&+ct&+Ct&n&+cer&+Ce&n&+cd&+L and &n&+mBr&+Mu&n&+mi&+Mse&n&+md&n";
            if( percent >= 69 )
                return "&+LLightly &+MWo&n&+mu&+Mn&n&+mde&+Md&n";
            if( percent >= 58 )
                return "&+LModerately &+MWo&+Ru&+Mn&+Rde&+Md&n";
            if( percent >= 48 )
                return "&+LSeverely &n&+rWo&n&+mu&+rn&+mde&n&+rd&n";
            if( percent >= 37 )
                return "&n&+rBl&+Re&n&+re&+Rdi&n&+rn&+Rg&+L Freely&n";
            if( percent >= 27 )
                return "&+LBathed in &n&+rBl&+Ro&n&+ro&+Rd&n";
            if( percent >= 16 )
                return "&+LLeaking&n&+r Guts&n";
            if( percent >= 6 )
                return "&+RWr&n&+ri&+Rt&n&+rhi&+Rn&n&+rg&+L in &n&+rA&+Rgo&n&+rn&+Ry&n";
            return "&+LAt &n&+wDeath&+L's Door&n";
        }
Exemple #18
0
        /// <summary>
        /// Knock a door from its hinges with brute force.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void DoorBash(CharData ch, string[] str)
        {
            if( ch == null ) return;
            Exit.Direction door;
            Room toRoom;

            if (ch.IsNPC() || (!ch.HasSkill("doorbash") && !ch.HasInnate(Race.RACE_DOORBASH)))
            {
                ch.SendText("You don't feel massive enough!\r\n");
                return;
            }

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

            if (ch.Fighting)
            {
                ch.SendText("You can't break off your fight.\r\n");
                return;
            }

            if ((door = Movement.FindDoor(ch, str[0])) >= 0)
            {
                Exit reverseExit;
                int chance;

                Exit exit = ch.InRoom.GetExit(door);
                if (!exit.HasFlag(Exit.ExitFlag.closed))
                {
                    ch.SendText("Calm down. It is already open.\r\n");
                    return;
                }

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

                if (ch.IsNPC())
                {
                    chance = 0;
                }
                else if (!ch.HasSkill("doorbash"))
                {
                    chance = 20;
                }
                else
                {
                    chance = ((PC)ch).SkillAptitude["doorbash"] / 2;
                }

                if (exit.HasFlag(Exit.ExitFlag.locked))
                {
                    chance /= 2;
                }

                if (exit.HasFlag(Exit.ExitFlag.bashproof) && !ch.IsImmortal())
                {
                    SocketConnection.Act("WHAAAAM!!!  You bash against the $d, but it doesn't budge.",
                         ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("WHAAAAM!!!  $n&n bashes against the $d, but it holds strong.",
                         ch, null, exit.Keyword, SocketConnection.MessageTarget.room);
                    Combat.InflictDamage(ch, ch, (ch.GetMaxHit() / 20), "doorbash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                    if (exit.HasFlag(Exit.ExitFlag.spiked))
                    {
                        SocketConnection.Act("You are impaled by spikes protruding from the $d!",
                            ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$n&n is impaled by spikes protruding from the $d!",
                            ch, null, exit.Keyword, SocketConnection.MessageTarget.room);
                        Combat.InflictDamage(ch, ch, (ch.GetMaxHit() / 5), "doorbash", ObjTemplate.WearLocation.none, AttackType.DamageType.pierce);
                    }
                    return;
                }

                if (exit.HasFlag(Exit.ExitFlag.spiked))
                {
                    SocketConnection.Act("You are impaled by spikes protruding from the $d!",
                        ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n is impaled by spikes protruding from the $d!",
                        ch, null, exit.Keyword, SocketConnection.MessageTarget.room);
                    Combat.InflictDamage(ch, ch, (ch.GetMaxHit() / 5), "doorbash", ObjTemplate.WearLocation.none, AttackType.DamageType.pierce);
                }

                if ((ch.GetCurrStr() >= 20) && MUDMath.NumberPercent() < (chance + 4 * (ch.GetCurrStr() - 20)))
                {
                    /* Success */

                    exit.RemoveFlag(Exit.ExitFlag.closed);
                    if (exit.HasFlag(Exit.ExitFlag.locked))
                    {
                        exit.RemoveFlag(Exit.ExitFlag.locked);
                    }

                    exit.AddFlag(Exit.ExitFlag.bashed);

                    SocketConnection.Act("Crash!  You bashed open the $d!",
                         ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n bashes open the $d!",
                         ch, null, exit.Keyword, SocketConnection.MessageTarget.room);

                    Combat.InflictDamage(ch, ch, (ch.GetMaxHit() / 30), "doorbash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);

                    /* Bash through the other side */
                    if ((toRoom = Room.GetRoom(exit.IndexNumber)) && (reverseExit = toRoom.GetExit(Exit.ReverseDirection(door)))
                        && reverseExit.TargetRoom == ch.InRoom)
                    {
                        reverseExit.RemoveFlag(Exit.ExitFlag.closed);
                        if (reverseExit.HasFlag(Exit.ExitFlag.locked))
                        {
                            reverseExit.RemoveFlag(Exit.ExitFlag.locked);
                        }

                        reverseExit.AddFlag(Exit.ExitFlag.bashed);

                        foreach (CharData irch in toRoom.People)
                        {
                            SocketConnection.Act("The $d crashes open!",
                                 irch, null, reverseExit.Keyword, SocketConnection.MessageTarget.character);
                        }

                        // Have any aggro mobs on the other side come after the player.
                        foreach (CharData charData in toRoom.People)
                        {
                            if (charData != ch && (charData.IsNPC() && !charData.IsAffected( Affect.AFFECT_CHARM))
                                && charData.IsAggressive(ch) && charData.IsAwake() && CharData.CanSee(charData, ch)
                                && !charData.Fighting)
                            {
                                Combat.StartHating(charData, ch);
                                Combat.StartHunting(charData, ch);
                            }
                        }

                    }
                }
                else
                {
                    /* Failure */
                    SocketConnection.Act("OW!  You bash against the $d, but it doesn't budge.",
                         ch, null, exit.Keyword, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("$n&n bashes against the $d, but it holds strong.",
                         ch, null, exit.Keyword, SocketConnection.MessageTarget.room);
                    Combat.InflictDamage(ch, ch, (ch.GetMaxHit() / 10), "doorbash", ObjTemplate.WearLocation.none, AttackType.DamageType.bludgeon);
                }
            }

            /*
            * Check for "guards"... anyone bashing a door is considered as
            * a potential aggressor, and there's a 25% chance that mobs
            * will do unto before being done unto.
            * But first...let's make sure ch ain't dead?  That'd be a pain.
            */

            if (ch.Hitpoints <= 1)
                return;

            ch.PracticeSkill("doorbash");

            foreach (CharData guardChar in ch.InRoom.People)
            {
                if (guardChar != ch && guardChar.HasActionBit(MobTemplate.ACT_PROTECTOR) && (guardChar.IsNPC() &&
                    !guardChar.IsAffected( Affect.AFFECT_CHARM)) && guardChar.IsAwake() && CharData.CanSee(guardChar, ch) &&
                    !guardChar.Fighting && MUDMath.NumberBits(2) == 0)
                {
                    SocketConnection.Act("$n&n is very unhappy about you trying to destroy the door.", guardChar, null, ch, SocketConnection.MessageTarget.victim);
                    guardChar.AttackCharacter(ch);
                }
            }
            return;
        }
Exemple #19
0
 /// <summary>
 /// Shows the graphical client-friendly version of the prompt.
 /// </summary>
 private void ShowEnhancedPrompt(CharData ch)
 {
     StringBuilder output = new StringBuilder();
     output.Append("<prompt>");
     // H = Hits.
     output.Append("H:");
     output.Append(ch.Hitpoints);
     // I = Max Hits.
     output.Append(" I:");
     output.Append(ch.GetMaxHit());
     // M = Moves.
     output.Append(" M:");
     output.Append(ch.CurrentMoves);
     // N = Max Moves.
     output.Append(" N:");
     output.Append(ch.MaxMoves);
     // A = Mana.
     output.Append(" A:");
     output.Append(ch.CurrentMana);
     // B = Max Mana
     output.Append(" B:");
     output.Append(ch.MaxMana);
     // P = Player Name.
     output.Append(" P:");
     output.Append((ch.ShowNameTo(ch, true)).Replace(' ', '_'));
     // Q = Player Condition.
     output.Append(" Q:");
     output.Append((ch.Hitpoints * 100) / ch.MaxHitpoints);
     output.Append(" R:");
     output.Append(Position.PositionString(ch.CurrentPosition));
     // T = Tank Name.
     output.Append(" T:");
     if (ch.Fighting && ch.Fighting.Fighting)
     {
         output.Append((ch.Fighting.Fighting.ShowNameTo(ch, true)).Replace(' ', '_'));
         // U = Enemy Condition.
         output.Append(" U:");
         output.Append((ch.Fighting.Fighting.Hitpoints * 100) / ch.Fighting.Fighting.GetMaxHit());
         output.Append(" V:");
         output.Append(Position.PositionString(ch.Fighting.Fighting.CurrentPosition));
     }
     else
     {
         output.Append("0 U:0 V:0");
     }
     // E = Enemy Name.
     output.Append(" E:");
     if (ch.Fighting)
     {
         output.Append((ch.Fighting.ShowNameTo(ch, true)).Replace(' ', '_'));
         // F = Enemy Condition.
         output.Append(" F:");
         output.Append((ch.Fighting.Hitpoints * 100) / ch.Fighting.GetMaxHit());
         output.Append(" G:");
         output.Append(Position.PositionString(ch.Fighting.CurrentPosition));
         output.Append(" ");
     }
     else
     {
         output.Append("0 F:0 G:0");
     }
     output.Append("</prompt>");
     ch.SendText(output.ToString());
 }
Exemple #20
0
        /// <summary>
        /// A basic bandage self command, usable once per day.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void FirstAid(CharData ch, string[] str)
        {
            if( ch == null ) return;

            if (ch.IsNPC())
                return;

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

            if (((PC)ch).FirstaidTimer > 0)
            {
                ch.SendText("You can only first aid once per day.\r\n");
                return;
            }

            if (ch.Hitpoints < ch.GetMaxHit())
            {
                ch.Hitpoints += MUDMath.Dice(3, (ch.Level / 2)) + 1;
                if (((PC)ch).SkillAptitude["bandage"] > 9)
                {
                    ch.Hitpoints += ((PC)ch).SkillAptitude["bandage"] / 8;
                    ch.PracticeSkill("bandage");
                }
                if (ch.Hitpoints > ch.GetMaxHit())
                {
                    ch.Hitpoints = ch.GetMaxHit();
                }
            }

            ((PC)ch).FirstaidTimer = 24;

            ch.SendText("You attempt to render first aid unto yourself.\r\n");

            return;
        }
Exemple #21
0
        /// <summary>
        /// Show a character to another character.
        /// </summary>
        /// <param name="victim"></param>
        /// <param name="ch"></param>
        public static void ShowCharacterToCharacterFull(CharData victim, CharData ch)
        {
            Object obj;
            string text = String.Empty;
            int percent;

            if (CharData.CanSee(victim, ch))
            {
                SocketConnection.Act("$n&n looks at you.", ch, null, victim, SocketConnection.MessageTarget.victim);
                if (victim != ch)
                {
                    SocketConnection.Act("$n&n looks at $N&n.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                }
                else
                {
                    SocketConnection.Act("$n&n looks at $mself.", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                }
            }

            if (victim.Riding != null)
            {
                text += String.Format("&nMounted on {0}, ", victim.Riding.ShowNameTo(ch, false));
            }
            else if (victim.Rider != null)
            {
                text += String.Format("&nRidden by {0}, ", victim.Rider.ShowNameTo(ch, false));
            }

            if (!victim.IsNPC() && victim.IsGuild())
            {
                text += String.Format("&n{0} of {1}.\r\n", ((PC)victim).GuildRank.ToString().ToUpper(),
                          ((PC)victim).GuildMembership.Name);
            }

            SocketConnection.Act(text, ch, null, victim, SocketConnection.MessageTarget.character);

            if (!String.IsNullOrEmpty(victim.Description))
            {
                ch.SendText(victim.Description);
            }
            else
            {
                SocketConnection.Act("&nYou see nothing special about $M.", ch, null, victim, SocketConnection.MessageTarget.character);
            }

            if (victim.GetMaxHit() > 0)
            {
                percent = (100 * victim.Hitpoints) / victim.GetMaxHit();
            }
            else
            {
                percent = -1;
            }

            text = victim.ShowNameTo(ch, true);

            if (percent >= 100)
                text += " &nis in perfect &n&+ghealth&n.  ";
            else if (percent >= 90)
                text += " &nis slightly &n&+yscratched&n.  ";
            else if (percent >= 80)
                text += " &nhas a &+yfew bruises&n.  ";
            else if (percent >= 70)
                text += " &nhas &+Ysome cuts&n.  ";
            else if (percent >= 60)
                text += " &nhas &+Mseveral wounds&n.  ";
            else if (percent >= 50)
                text += " &nhas &+mmany nasty wounds&n.  ";
            else if (percent >= 40)
                text += " &nis &+Rbleeding freely&n.  ";
            else if (percent >= 30)
                text += " &nis &+Rcovered in blood&n.  ";
            else if (percent >= 20)
                text += " &nis &+rleaking guts&n.  ";
            else if (percent >= 10)
                text += " &nis &+ralmost dead&n.  ";
            else
                text += " &nis &+rDYING&n.  ";

            ch.SendText(text);

            // Show size on look at someone.
            text = MUDString.CapitalizeANSIString(String.Format("{0}&n is a {1} of {2} size.\r\n", victim.GetSexPronoun(),
                Race.RaceList[victim.GetRace()].ColorName, Race.SizeString(victim.CurrentSize)));
            ch.SendText(text);

            ShowAffectLines(ch, victim);

            bool found = false;
            foreach (ObjTemplate.WearLocation location in ObjTemplate.TopDownEquipment)
            {
                obj = Object.GetEquipmentOnCharacter(victim, location);
                if (obj && CharData.CanSeeObj(ch, obj))
                {
                    if (!found)
                    {
                        ch.SendText("\r\n");
                        SocketConnection.Act("&n$E is using:", ch, null, victim, SocketConnection.MessageTarget.character);
                        found = true;
                    }
                    if (obj.ItemType == ObjTemplate.ObjectType.weapon
                            && (location == ObjTemplate.WearLocation.hand_one
                                 || location == ObjTemplate.WearLocation.hand_three
                                 || location == ObjTemplate.WearLocation.hand_four
                                 || location == ObjTemplate.WearLocation.hand_two)
                            && obj.HasWearFlag(ObjTemplate.WEARABLE_WIELD))
                    {
                        if (obj.HasFlag(ObjTemplate.ITEM_TWOHANDED)
                                && !ch.HasInnate(Race.RACE_EXTRA_STRONG_WIELD))
                        {
                            ch.SendText("&+y(wielding twohanded)  &n");
                        }
                        else
                        {
                            ch.SendText("&+y(wielding)            &n");
                        }
                    }
                    else
                    {
                        if (obj.ItemType == ObjTemplate.ObjectType.shield
                                && (location == ObjTemplate.WearLocation.hand_one
                                     || location == ObjTemplate.WearLocation.hand_three
                                     || location == ObjTemplate.WearLocation.hand_four
                                     || location == ObjTemplate.WearLocation.hand_two)
                                && obj.HasWearFlag(ObjTemplate.WEARABLE_SHIELD))
                        {
                            ch.SendText("&+y(worn as shield)      &n");
                        }
                        else
                        {
                            ch.SendText(StringConversion.EquipmentLocationDisplay[(int)location]);
                        }
                    }
                    ch.SendText(FormatObjectToCharacter(obj, ch, true));
                    ch.SendText("\r\n");
                }
            }

            // Keep in mind that players can spam looking at someone in order
            // to increase their skill in peek - this will need to be fixed.
            if ((victim != ch && !ch.IsNPC()
                && ((((PC)ch).SkillAptitude.ContainsKey("peek") && MUDMath.NumberPercent() < ((PC)ch).SkillAptitude["peek"])
                || ch.Level >= Limits.LEVEL_AVATAR)) || ch.Riding == victim || ch.Rider == victim)
            {
                ch.SendText("\r\n&nYou peek at the inventory:\r\n");
                ch.PracticeSkill("peek");
                ShowListToCharacter(victim.Carrying, ch, true, true);
            }

            return;
        }