示例#1
0
        /// <summary>
        /// Demote: Decrease the rank of a guild member.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Demote(CharData ch, string[] str)
        {
            if( ch == null ) return;

            SocketConnection victimSocket;
            int count;
            bool loggedIn = false;

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

            if (!ch.IsGuild() || ((PC)ch).GuildRank != Guild.Rank.leader)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            CharData victim = null;
            foreach (CharData worldChar in Database.CharList)
            {
                if (worldChar.IsNPC())
                {
                    continue;
                }
                if (MUDString.NameContainedIn(str[0], worldChar.Name))
                {
                    victim = worldChar;
                    loggedIn = true;
                    break;
                }
            }

            if (victim == null)
            {
                if (!(CharData.LoadPlayer((victimSocket = new SocketConnection()), str[0])))
                {
                    ch.SendText("Who's that?!\r\n");
                    return;
                }
                victim = victimSocket.Original ? victimSocket.Original : victimSocket.Character;
                loggedIn = false;
            }

            if (victim.IsNPC())
            {
                ch.SendText("NPCs are not guildable!\r\n");
                return;
            }

            if (!ch.IsSameGuild(victim))
            {
                SocketConnection.Act("$N&n isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character);
                return;
            }

            switch (((PC)victim).GuildRank)
            {
                default:
                    ch.SendText("You can't demote this person.\r\n");
                    return;
                case Guild.Rank.normal:
                    ch.SendText("You can't demote them any further.\r\n");
                    return;
                case Guild.Rank.senior:
                case Guild.Rank.officer:
                case Guild.Rank.deputy:
                    break;
                case Guild.Rank.leader:
                    if (str.Length > 1 && MUDString.StringsNotEqual(str[1], "confirm"))
                    {
                        ch.SendText("Try 'demote leadername confirm' to demote a leader.\r\n");
                        return;
                    }
                    break;
            }

            ((PC)victim).GuildRank--;
            Guild.Rank newrank = ((PC)victim).GuildRank;

            SetTitle(victim, guild.RankNames[(int)((PC)victim).GuildRank]);

            string text = String.Format("Log {0}: demoting {1} to {2}",
                                       ch.Name,
                                       victim.Name,
                                       ((PC)ch).GuildMembership.Name);
            Database.LogGuild(text);

            text = String.Format(
                      "The grand Overlord {0} says:\r\n\r\n" +
                      "'I hereby demote you {1} to {2}!!!'\r\n" +
                      "You should make more efforts to improve!",
                      ch.Name, victim.Name, newrank);

            if (loggedIn)
            {
                victim.SendText(text);
            }

            SocketConnection.Act("You have demoted $N to $t.",
                 ch, newrank.ToString(), victim, SocketConnection.MessageTarget.character);

            for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count)
            {
                if (!MUDString.StringsNotEqual(guild.Members[count].Name, victim.Name))
                {
                    guild.Members[count].Rank = ((PC)victim).GuildRank;
                }
            }

            CharData.SavePlayer(victim);
            guild.Save();

            /* Close rented chars pfile. */
            if (!loggedIn)
            {
                victimSocket = null;
            }
            return;
        }
示例#2
0
        /// <summary>
        /// Exile a player from a guild.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Exile(CharData ch, string[] str)
        {
            if( ch == null ) return;

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

            if (!ch.IsGuild()
                    || ((PC)ch).GuildRank != Guild.Rank.leader)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

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

            if (victim.IsNPC() || victim == ch || victim.Level > ch.Level)
                return;

            if (!ch.IsSameGuild(victim))
            {
                SocketConnection.Act("$N isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character);
                return;
            }

            string text = String.Format("Log {0}: exiling {1} from {2}", ch.Name, victim.Name, ((PC)ch).GuildMembership.Name);
            Database.LogGuild(text);

            // This function handles resetting member data
            victim.RemoveFromGuild();
            ((PC)victim).GuildRank = Guild.Rank.exiled;

            text = String.Format(
                      "The grand Overlord of {0} {1} says:\r\n\r\n" +
                      "'Then so be done, you {2} shall be exiled from {3}!'\r\n" +
                      "You hear a thundering sound...\r\n\r\n" +
                      "A booming voice says: 'You have been exiled. Only the gods can allow you\r\n" +
                      "to join another clan, order or guild!'\r\n",
                      guild.WhoName,
                      guild.Overlord,
                      victim.Name,
                      guild.WhoName);

            victim.SendText(text);

            SocketConnection.Act("You have exiled $N&n from $t!", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character);
            CharData.SavePlayer(victim);
            guild.Save();
            return;
        }
示例#3
0
        public static void Socname(CharData ch, string[] str)
        {
            if( ch == null ) return;

            string arg = String.Empty;
            Guild.Rank rank;

            if (!ch.IsGuild() || ((PC)ch).GuildRank < Guild.Rank.leader)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            if (arg.Length == 0)
            {
                ch.SendText("Reset the title on which rank?\r\n");
                return;
            }

            Guild guils = ((PC)ch).GuildMembership;

            try
            {
                rank = (Guild.Rank)Enum.Parse(typeof(Guild.Rank), arg, false);
            }
            catch (Exception)
            {
                ch.SendText("That's not a valid rank.\r\n");
                return;
            }

            if (str.Length == 0)
            {
                ch.SendText("Set the rank title to what?\r\n");
                return;
            }

            guils.RankNames[(int)rank] = str[0];

            ch.SendText("Done.\r\n");

            guils.Save();

            return;
        }
示例#4
0
        public static void Channels(CharData ch, string[] str)
        {
            if( ch == null ) return;

            if (str.Length == 0 || String.IsNullOrEmpty(str[0]))
            {
                if (!ch.IsNPC() && ch.HasActionBit(PC.PLAYER_SILENCE))
                {
                    ch.SendText("&nYou are silenced, cur.\r\n");
                    return;
                }

                ch.SendText("Channels:");

                ch.SendText(ch.IsListening(TalkChannel.shout)
                              ? " +SHOUT"
                              : " -shout");

                ch.SendText(ch.IsListening(TalkChannel.yell)
                              ? " +YELL"
                              : " -yell");

                if (ch.IsGuild())
                {
                    ch.SendText(ch.IsListening(TalkChannel.guild)
                                  ? " +guild"
                                  : " -guild");
                }

                if (ch.IsHero())
                {
                    ch.SendText(ch.IsListening(TalkChannel.immortal)
                                  ? " +IMMTALK"
                                  : " -immtalk");
                }

                ch.SendText(".\r\n");
            }
            else
            {
                TalkChannel bit;
                bool fClear;

                if (str[0][0] == '+')
                    fClear = true;
                else if (str[0][0] == '-')
                    fClear = false;
                else
                {
                    ch.SendText("&nChannels -channel or +channel?\r\n");
                    return;
                }

                string tmparg = String.Format("{0}", str[0]);
                if (!MUDString.StringsNotEqual(tmparg + 1, "immtalk"))
                    bit = TalkChannel.immortal;
                else if (!MUDString.StringsNotEqual(tmparg + 1, "guild"))
                    bit = TalkChannel.guild;
                else if (!MUDString.StringsNotEqual(tmparg + 1, "shout"))
                    bit = TalkChannel.shout;
                else if (!MUDString.StringsNotEqual(tmparg + 1, "yell"))
                    bit = TalkChannel.yell;
                else
                {
                    ch.SendText("&nSet or clear which channel?\r\n");
                    return;
                }

                if (fClear)
                    ch.SetListening(bit, true);
                else
                    ch.SetListening(bit, false);

                ch.SendText("&nOk.\r\n");
            }

            return;
        }
示例#5
0
        public static void Ostracize(CharData ch, string[] str)
        {
            if( ch == null ) return;

            string arg = String.Empty;

            if (!ch.IsGuild() || ((PC)ch).GuildRank < Guild.Rank.deputy)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            if (arg.Length == 0)
            {
                ch.SendText("Who do you want to ostracize?\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            if (MUDString.NameContainedIn(arg, guild.Ostracized))
            {
                ch.SendText("They've already been ostracized.\r\n");
                return;
            }

            string buf = String.Format("{0} {1}", guild.Ostracized, arg);

            if (!MUDString.StringsNotEqual(arg, "clear"))
            {
                buf = String.Empty;
            }

            guild.Ostracized = buf;

            ch.SendText("Done.\r\n");

            guild.Save();

            return;
        }
示例#6
0
        /// <summary>
        /// Promote target to another rank in the guild.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Promote(CharData ch, string[] str)
        {
            if( ch == null ) return;

            SocketConnection victimSocket;
            int count;
            bool loggedIn = false;

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

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

            if (!ch.IsGuild() || ((PC)ch).GuildRank != Guild.Rank.leader)
            {
                ch.SendText("You don't have the power to do this.  Only a leader may promote someone.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            CharData victim = null;
            foreach (CharData worldChar in Database.CharList)
            {
                if (worldChar.IsNPC())
                {
                    continue;
                }
                if (MUDString.NameContainedIn(str[0], worldChar.Name))
                {
                    victim = worldChar;
                    loggedIn = true;
                    break;
                }
            }

            if (victim == null)
            {
                if (!(CharData.LoadPlayer((victimSocket = new SocketConnection()), str[0])))
                {
                    ch.SendText("Who's that?!\r\n");
                    return;
                }
                victim = victimSocket.Original ? victimSocket.Original : victimSocket.Character;
                loggedIn = false;
            }

            if (victim.IsNPC() || victim == ch)
            {
                return;
            }

            if (!ch.IsSameGuild(victim))
            {
                SocketConnection.Act("$N&n isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character);
                return;
            }

            // This is technically where we would give them their guild badges.
            switch (((PC)victim).GuildRank)
            {
                default:
                    return;
                case Guild.Rank.normal:
                case Guild.Rank.officer:
                case Guild.Rank.senior:
                case Guild.Rank.deputy:
                    break;
                case Guild.Rank.leader:
                    ch.SendText("You may not promote that person any further.\r\n");
                    return;
            }

            ((PC)victim).GuildRank++;
            Guild.Rank newrank = ((PC)victim).GuildRank;

            SetTitle(victim, guild.RankNames[(int)((PC)victim).GuildRank]);

            string text = String.Format("Log {0}: promoting {1} to {2} in guild {3}",
                                       ch.Name, victim.Name, newrank, ((PC)ch).GuildMembership.Name);
            Database.LogGuild(text);

            text = String.Format(
                      "The grand Overlord {0} says:\r\n\r\nI hereby promote you {1} to {2}!'\r\n",
                      ch.Name, victim.Name, newrank);

            if (loggedIn)
            {
                victim.SendText(text);
            }

            SocketConnection.Act("You have promoted $N&n to $t.",
                 ch, newrank.ToString(), victim, SocketConnection.MessageTarget.character);

            for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count)
            {
                if (!MUDString.StringsNotEqual(guild.Members[count].Name, victim.Name))
                {
                    guild.Members[count].Rank = ((PC)victim).GuildRank;
                }
            }

            CharData.SavePlayer(victim);
            guild.Save();

            /* Close rented chars pfile. */
            if (!loggedIn)
            {
                victimSocket = null;
            }

            return;
        }
示例#7
0
        /// <summary>
        /// Kick a character out of a guild.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void KickOut(CharData ch, string[] str)
        {
            if( ch == null ) return;

            SocketConnection victimSocket;
            bool loggedIn = false;

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

            if (!ch.IsGuild() || ((PC)ch).GuildRank < Guild.Rank.officer)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            CharData victim = null;
            foreach (CharData worldChar in Database.CharList)
            {
                if (worldChar.IsNPC())
                {
                    continue;
                }
                if (MUDString.NameContainedIn(str[0], worldChar.Name))
                {
                    victim = worldChar;
                    loggedIn = true;
                    break;
                }
            }

            if (victim == null)
            {
                if (!(CharData.LoadPlayer((victimSocket = new SocketConnection()), str[0])))
                {
                    ch.SendText("Who's that?!\r\n");
                    return;
                }
                victim = victimSocket.Original ? victimSocket.Original : victimSocket.Character;
                loggedIn = false;
            }

            if (victim.IsNPC())
            {
                return;
            }

            if (victim == ch)
            {
                ch.SendText("Try &+rsociety secede&n!\r\n");
                return;
            }

            if (!ch.IsSameGuild(victim))
            {
                SocketConnection.Act("$N&n isn't even from $t.", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character);
                return;
            }

            if (((PC)ch).GuildRank <= ((PC)victim).GuildRank)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            string text = String.Format("Log {0}: kicking {1} from {2}", ch.Name, victim.Name, ((PC)ch).GuildMembership.Name);
            Database.LogGuild(text);

            // this _function _resets member data
            victim.RemoveFromGuild();
            ((PC)victim).GuildRank = Guild.Rank.normal;

            if (loggedIn)
            {
                victim.SendText("&+RYou have been booted from your guild!&n\r\n");
            }

            ch.SendText("You have kicked them out of the guild.\r\n");

            CharData.SavePlayer(victim);
            guild.Save();

            /* Close rented chars pfile. */
            if (!loggedIn)
            {
                victimSocket = null;
            }

            return;
        }
示例#8
0
文件: Look.cs 项目: ramseur/ModernMUD
        /// <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;
        }
示例#9
0
        public static void Hometown(CharData ch, string[] str)
        {
            if( ch == null ) return;

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

            if (!ch.IsGuild() && !ch.IsImmortal())
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            if (ch.IsNPC())
                return;

            if (!ch.InRoom.HasFlag(RoomTemplate.ROOM_GUILDROOM))
            {
                ch.SendText("You can't set your hometown here!\r\n");
                return;
            }

            if (ch.CurrentPosition == Position.fighting || ch.Fighting)
            {
                ch.SendText("No way! You are fighting.\r\n");
                return;
            }

            if (ch.CurrentPosition < Position.stunned)
            {
                ch.SendText("You're not &+RD&n&+rE&+RA&n&+rD&n yet.\r\n");
                return;
            }

            string logBuf = String.Format("{0} is resetting their hometown to {1}.", ch.Name, ch.InRoom.IndexNumber);
            Log.Trace(logBuf);

            ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_LOGINS, ch.GetTrust(), logBuf);

            // I can't see any reason why ch would not have an .in_room, but that
            // may just be shortsighted of me - Xangis
            if (!ch.InRoom)
            {
                Log.Error("Commandhometown: ch not in a room!", 0);
                return;
            }

            // Put them in the correct body
            if (ch.Socket && ch.Socket.Original)
            {
                CommandType.Interpret(ch, "return");
            }

            ch.SendText("You Reset your hometown.\r\n");
            ((PC)ch).CurrentHome = ch.InRoom.IndexNumber;

            CharData.SavePlayer(ch);

            return;
        }
示例#10
0
        public static void Initiate(CharData ch, string[] str)
        {
            if( ch == null ) return;

            Object ring;
            bool found = false;
            int count;

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

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

            if (victim.IsNPC())
            {
                ch.SendText("Very funny trying to enroll an NPC.\r\n");
                return;
            }

            if (!ch.IsGuild() || ((PC)ch).GuildRank < Guild.Rank.officer)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            if (victim == ch)
            {
                return;
            }

            if (guild.Applicant != victim)
            {
                ch.SendText("They have not applied for membership to your guild.\r\n");
                return;
            }

            if (victim.IsGuild())
            {
                ch.SendText("They are already in another guild.\r\n");
                return;
            }

            if (guild.NumMembers >= 30)
            {
                ch.SendText("Your guild is full.\r\n");
                return;
            }

            for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count)
            {
                if (guild.Members[count].Filled == false)
                {
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                ch.SendText("There are no more openings in your organization.\r\n");
                return;
            }

            /*
            if( ((PC)victim).rank == Rank.exiled )
            {
            ch.SendText( "They are an exile and may not be guilded.\r\n" );
            victim.SendText( "You are an exile and cannot be accepted into a guild.\r\n" );
            return;
            }
            */

            if (victim.Level < 25)
            {
                if (guild.TypeOfGuild == Guild.GuildType.clan && ch.Level >= 15)
                {
                }
                else if (guild.TypeOfGuild == Guild.GuildType.guild && ch.Level >= 20)
                {
                }
                else
                {
                    SocketConnection.Act("$N&n is too low level to be initiated.", ch, null, victim, SocketConnection.MessageTarget.character);
                    SocketConnection.Act("You are too weak to  be initiated to $t!", ch, guild.WhoName, victim, SocketConnection.MessageTarget.victim);
                    return;
                }
            }

            if (guild.TypeOfGuild == Guild.GuildType.guild && guild.ClassRestriction != victim.CharacterClass)
                ch.SendText("You may only initiate those of your class into a guild.\r\n");

            ((PC)victim).GuildMembership = guild;
            ((PC)victim).GuildRank = Guild.Rank.normal;
            guild.NumMembers++;

            SetTitle(victim, guild.RankNames[(int)((PC)victim).GuildRank]);

            guild.Members[count].Name = victim.Name;
            guild.Members[count].Rank = ((PC)victim).GuildRank;
            guild.Members[count].JoinTime = Database.SystemData.CurrentTime;
            guild.Members[count].Filled = true;

            // Reset so others can apply
            guild.Applicant = null;

            if (Database.GetObjTemplate(guild.GuildRingIndexNumber))
            {
                ring = Database.CreateObject(Database.GetObjTemplate(guild.GuildRingIndexNumber), victim.Level);

                if (ring)
                {
                    ring.ObjToChar(victim);
                }
            }

            string buf = String.Format("Log {0}: initiated {1} to {2}", ch.Name, victim.Name, guild.Name);
            Database.LogGuild(buf);

            buf = String.Format("'I {0} {1}, hereby declare you {2} a member of {3}!'\r\n" +
                      "Forever remember our motto: \"{4}\"\r\n",
                      ((PC)ch).GuildRank,
                      ch.Name,
                      victim.Name,
                      guild.WhoName,
                      guild.Motto);

            victim.SendText(buf);

            SocketConnection.Act("$N&n has been initiated to $t!", ch, guild.WhoName, victim, SocketConnection.MessageTarget.room);
            SocketConnection.Act("You have initiated $N&n to $t!", ch, guild.WhoName, victim, SocketConnection.MessageTarget.character);
            CharData.SavePlayer(victim);
            guild.Save();

            return;
        }
示例#11
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;
        }
示例#12
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;
        }
示例#13
0
 /// <summary>
 /// Checks whether two characters are in the same guild.
 /// </summary>
 /// <param name="ch"></param>
 /// <returns></returns>
 public bool IsSameGuild( CharData ch )
 {
     if (IsGuild() && ch.IsGuild())
     {
         return ((PC)this).GuildMembership == ((PC)ch).GuildMembership;
     }
     return false;
 }
示例#14
0
        public static void Fine(CharData ch, string[] str)
        {
            if( ch == null ) return;

            string arg = String.Empty;
            int amount;
            int count;

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

            if (!ch.IsGuild() || ((PC)ch).GuildRank < Guild.Rank.deputy)
            {
                ch.SendText("You don't have the power to do this.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            Int32.TryParse(str[0], out amount);

            if (amount <= 0)
            {
                ch.SendText("Fine them how much?\r\n");
                return;
            }

            if (!MUDString.StringsNotEqual(arg, "all"))
            {
                for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count)
                {
                    if (guild.Members[count].Filled == true &&
                            guild.Members[count].Rank < ((PC)ch).GuildRank)
                    {
                        guild.Members[count].Fine += amount;
                    }
                }
            }
            else
            {
                bool found = false;
                for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count)
                {
                    if (MUDString.StringsNotEqual(guild.Members[count].Name, arg))
                        continue;
                    if (guild.Members[count].Filled == true &&
                            guild.Members[count].Rank < ((PC)ch).GuildRank)
                    {
                        guild.Members[count].Fine += amount;
                        found = true;
                    }
                }
                if (!found)
                {
                    ch.SendText("You were not able to fine them.\r\n");
                    return;
                }
            }

            ch.SendText("Done.\r\n");

            guild.Save();

            return;
        }
示例#15
0
        /// <summary>
        /// Terminate your guild membership.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void Leave(CharData ch, string[] str)
        {
            if( ch == null ) return;
            if (!ch.IsGuild())
            {
                ch.SendText("You aren't a guildmember.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            if (((PC)ch).GuildRank == Guild.Rank.leader)
            {
                ch.SendText("Huh? An Overlord shouldn't leave his guild! Get demoted first!\r\n");
                return;
            }

            ch.RemoveFromGuild();
            ((PC)ch).GuildRank = Guild.Rank.normal;

            SocketConnection.Act("You have left guild $t.", ch, guild.WhoName, ch, SocketConnection.MessageTarget.character);
            CharData.SavePlayer(ch);
            guild.Save();

            return;
        }
示例#16
0
        /// <summary>
        /// Shows details about a guild.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="str"></param>
        public static void GuildInfo(CharData ch, string[] str)
        {
            if( ch == null ) return;

            int count;
            int members = 0;

            if (!ch.IsGuild())
            {
                ch.SendText("You aren't a guildmember.\r\n");
                return;
            }

            Guild guild = ((PC)ch).GuildMembership;

            string buf1 = String.Empty;

            string text = String.Format("{0}\r\n", guild.Name);
            buf1 += text;

            text = String.Format("Motto: \"{0}\"\r\n", guild.Motto);
            buf1 += text;

            buf1 += "-----------------------------------------------------------------------------\r\n";

            text = String.Format("{0}\r\n", guild.Description);
            buf1 += text;

            text = String.Format("Leader:  {0}\r\n", guild.Overlord);
            buf1 += text;

            text = String.Format("Members:   {0}\r\nFrags: &+W{1}&n\r\n", guild.NumMembers, guild.Frags);
            buf1 += text;

            text = String.Format("Vault:     {0} &+Wplatinum&n, {1} &+Ygold&n, {2} silver, {3} &+ycopper&n\r\n",
                      guild.GuildBankAccount.Platinum, guild.GuildBankAccount.Gold, guild.GuildBankAccount.Silver,
                      guild.GuildBankAccount.Copper);
            buf1 += text;

            text = String.Format("Current Applicant: {0}\r\n", guild.Applicant ? guild.Applicant.Name : "(none)");
            buf1 += text;

            if (((PC)ch).GuildRank == Guild.Rank.leader)
            {
                text = String.Format("\r\n&+cRank Titles:&n\r\n  Exile: {0}\r\n  Parole: {1}\r\n  Normal: {2}\r\n  Senior: {3}\r\n" +
                          "  Officer: {4}\r\n  Deputy: {5}\r\n  Leader: {6}\r\n",
                          guild.RankNames[(int)Guild.Rank.exiled],
                          guild.RankNames[(int)Guild.Rank.parole],
                          guild.RankNames[(int)Guild.Rank.normal],
                          guild.RankNames[(int)Guild.Rank.senior],
                          guild.RankNames[(int)Guild.Rank.officer],
                          guild.RankNames[(int)Guild.Rank.deputy],
                          guild.RankNames[(int)Guild.Rank.leader]);
                buf1 += text;
            }

            text = String.Format("\r\nMember            Rank  Fine:\r\n");
            buf1 += text;

            for (count = 0; count < Limits.MAX_GUILD_MEMBERS; ++count)
            {
                if (guild.Members[count].Filled)
                {
                    members++;
                    text = String.Format("{0}) &+r{1}&n{2} {3} {4}&+yc&n\r\n",
                              members,
                              (ch.GetCharWorld(guild.Members[count].Name) ? 'o' : ' '),
                              MUDString.PadStr(guild.Members[count].Name, 15),
                              guild.RankNames[(int)guild.Members[count].Rank],
                              MUDString.PadInt(guild.Members[count].Fine, 8));
                    buf1 += text;
                }
            }

            if (guild.Ostracized.Length > 0)
            {
                text = String.Format("Ostracized: {0}\r\n", guild.Ostracized);
                buf1 += text;
            }

            ch.SendText(buf1);
            return;
        }
示例#17
0
文件: Look.cs 项目: ramseur/ModernMUD
        /// <summary>
        /// Show a character to another character. This is the abbreviated version used in "look room"
        /// </summary>
        /// <param name="victim"></param>
        /// <param name="ch"></param>
        public static void ShowCharacterToCharacterAbbreviated(CharData victim, CharData ch)
        {
            string text = String.Empty;

            if (!victim || !ch)
            {
                Log.Error("ShowCharacterToCharacter0(): null ch or victim.", 0);
                return;
            }

            if (victim.Rider && victim.Rider.InRoom == ch.InRoom)
            {
                return;
            }

            // If invis, show char invis symbol first.
            if (victim.IsAffected(Affect.AFFECT_INVISIBLE))
            {
                text += "&+L*&n ";
            }

            // Show the player's description.
            if (((!ch.IsNPC() && victim.CurrentPosition == Position.standing)
                    || (victim.IsNPC() && victim.MobileTemplate != null
                        && victim.CurrentPosition == victim.MobileTemplate.DefaultPosition))
                    && (!String.IsNullOrEmpty(victim.FullDescription)) && !victim.Riding)
            {
                // Added long description does not have \r\n removed.  We may want to.
                text += victim.Description + "&n";
            }
            else
            {
                // Show the player's name.
                text += victim.ShowNameTo(ch, true) + "&n";

                // Show the player's title.
                // Show the player's race, only if PC, and on the same side of the racewar or a god.
                if (!victim.IsNPC() && ((PC)victim).Title.Length > 0)
                {
                    if (MUDString.StringsNotEqual(((PC)victim).Title, " &n") && (ch.IsNPC()))
                    {
                        text += ((PC)victim).Title;
                    }
                    if (victim.IsGuild() && (ch.IsNPC()))
                    {
                        text += " " + ((PC)victim).GuildMembership.WhoName;
                    }

                    if (!ch.IsRacewar(victim) || victim.IsImmortal() || ch.IsImmortal())
                    {
                        text += " (" + Race.RaceList[victim.GetRace()].ColorName + ")";
                    }
                }

                // Show the player's condition.
                text += " is ";
                if (victim.CurrentPosition == Position.standing && victim.CanFly())
                {
                    text += "flying";
                }
                else
                {
                    text += Position.PositionString(victim.CurrentPosition);
                }
                text += " here";
                if (victim.Fighting != null)
                {
                    text += "&n fighting ";
                    if (victim.Fighting == ch)
                    {
                        text += "&nyou!";
                    }
                    else if (victim.InRoom == victim.Fighting.InRoom)
                    {
                        text += victim.Fighting.ShowNameTo(ch, false);
                    }
                    else
                    {
                        text += "&nsomeone who left??";
                    }
                }

                if (victim.Riding && victim.Riding.InRoom == victim.InRoom)
                {
                    text += "&n, mounted on " + victim.Riding.ShowNameTo(ch, false);
                }
                text += "&n.";
            }

            if (victim.IsAffected(Affect.AFFECT_CASTING))
            {
                text += "&n&+y (casting)&n";
            }

            if (victim.IsAffected(Affect.AFFECT_MINOR_PARA))
            {
                text += "&n (&+Yparalyzed)&n";
            }
            if (!victim.IsNPC() && victim.HasActionBit(PC.PLAYER_WIZINVIS)
                    && victim.GetTrust() <= ch.GetTrust())
            {
                text += " &n&+g*&n";
            }
            if (victim.IsAffected(Affect.AFFECT_HIDE) && (ch.IsAffected(Affect.AFFECT_DETECT_HIDDEN) ||
                      ch.HasInnate(Race.RACE_DETECT_HIDDEN)))
            {
                text += " &n(&+LHiding&n)";
            }
            if (victim.IsAffected(Affect.AFFECT_CHARM) && ch.HasActionBit(PC.PLAYER_GODMODE))
            {
                text += " &n(&n&+mCharmed&n)";
            }
            if ((victim.IsAffected(Affect.AFFECT_PASS_DOOR) || victim.HasInnate(Race.RACE_PASSDOOR))
                    && ch.HasActionBit(PC.PLAYER_GODMODE))
            {
                text += " &n(&+WTranslucent&n)";
            }
            if ((victim.GetRace() == Race.RACE_UNDEAD || victim.GetRace() == Race.RACE_VAMPIRE)
                    && (ch.IsAffected( Affect.AFFECT_DETECT_UNDEAD) || ch.HasActionBit(PC.PLAYER_GODMODE)))
            {
                text += " &n(&+WPale&n)";
            }
            if (victim.IsAffected(Affect.AFFECT_FAERIE_FIRE))
            {
                text += " &n(&n&+mFa&+Me&n&+mr&+Mie&+L Aura&n)";
            }
            if (victim.IsEvil() && (ch.IsAffected(Affect.AFFECT_DETECT_EVIL)
                         || ch.HasInnate(Race.RACE_DETECT_ALIGN)
                         || ch.IsClass(CharClass.Names.paladin)
                         || ch.IsClass(CharClass.Names.antipaladin)))
            {
                text += " &n(&+rBlood&+L Aura&n)";
            }
            if (victim.IsGood() && (ch.IsAffected(Affect.AFFECT_DETECT_GOOD)
                         || ch.HasInnate(Race.RACE_DETECT_ALIGN)
                         || ch.IsClass(CharClass.Names.paladin)
                         || ch.IsClass(CharClass.Names.antipaladin)))
            {
                text += " &n(&+CLight&+L Aura&n)";
            }
            if (victim.IsAffected(Affect.AFFECT_SANCTUARY))
            {
                text += " &n(&+WWhite&+L Aura&n)";
            }
            if (!victim.IsNPC() && victim.HasActionBit(PC.PLAYER_AFK))
            {
                text += " &n&+b(&+RAFK&n&+b)&n";
            }
            if (!victim.IsNPC() && victim.HasActionBit(PC.PLAYER_BOTTING))
            {
                text += " &n&+b(&+YBot&n&+b)&n";
            }
            text += "\r\n";
            ch.SendText(text);
            return;
        }