示例#1
0
        static bool SpecInferno(System.Object obj, System.Object owner, bool hit)
        {
            CharData keeper = (CharData)owner;

            /* check to make sure the object has an owner and he's in the room */

            if (!keeper || !keeper.InRoom)
            {
                return(false);
            }

            if (MUDMath.NumberPercent() < 10)
            {
                SocketConnection.Act("&+LA faint hum can be heard from&n $p&n &+Lcarried by&n $n&n.",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.room);
                SocketConnection.Act("&+LA faint hum can be heard from&n $p&n &+Lyou are carrying.&n",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.character);
                return(true);
            }

            /* check to see if the weapon is in combat */
            if (!keeper.Fighting || !hit)
            {
                return(false);
            }


            if (keeper.Fighting && keeper.InRoom && MUDMath.NumberPercent() < 10 &&
                keeper.Fighting.Hitpoints >= -9)
            {
                SocketConnection.Act("&+r$n&+r's $p&+r glows brightly and emits a storm of fire!&n",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.room);
                SocketConnection.Act("Your $p&+r glows brightly and emits a storm of fire!&n",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.character);
                int dam = MUDMath.Dice(10, 10) + 150;
                foreach (CharData victim in keeper.InRoom.People)
                {
                    if (victim.IsSameGroup(keeper) ||
                        victim == keeper || victim.Hitpoints < -9)
                    {
                        continue;
                    }
                    if (victim.FlightLevel != keeper.FlightLevel)
                    {
                        continue;
                    }
                    if (Magic.SpellSavingThrow(((Object)obj).Level, victim, AttackType.DamageType.fire))
                    {
                        Combat.InflictSpellDamage(keeper, victim, dam / 2, "inferno", AttackType.DamageType.fire);
                    }
                    else
                    {
                        Combat.InflictSpellDamage(keeper, victim, dam, "inferno", AttackType.DamageType.fire);
                    }
                }
            }

            return(false);
        }
示例#2
0
        /// <summary>
        /// Sets the level of an undead creature based on info from the character,
        /// the corpse, and the type of undead being raised.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="corpseLevel"></param>
        /// <param name="petType"></param>
        /// <returns></returns>
        public static int FuzzyLevel(CharData ch, int corpseLevel, int petType)
        {
            int temp = corpseLevel;

            if ((corpseLevel > Table[petType].MaxLevel) && (corpseLevel <= ch.Level))
            {
                return(Table[petType].MaxLevel);
            }
            if ((corpseLevel >= ch.Level) &&
                (ch.Level <= Table[petType].MaxLevel))
            {
                temp = (ch.Level + ((MUDMath.Dice(1, ((corpseLevel + 1) - ch.Level))) - 1));
                return(Math.Min(temp, Table[petType].MaxLevel));
            }
            if (ch.Level >= corpseLevel)
            {
                return(Math.Min(ch.Level, Table[petType].MaxLevel));
            }
            return(temp);
        }
示例#3
0
        /// <summary>
        /// Song of quagmire (move drain).
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="spell"></param>
        /// <param name="level"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static bool SongQuagmire(CharData ch, Spell spell, int level, Target target)
        {
            foreach (CharData victim in ch.InRoom.People)
            {
                if (victim.CurrentMoves < 0)
                {
                    continue;
                }

                victim.CurrentMoves -= MUDMath.Dice(2, (level / 2)) + 5;

                if (victim.CurrentMoves < 0)
                {
                    victim.CurrentMoves = 0;
                }

                victim.SendText("Your feet feel mired to the ground.\r\n");
            }
            return(true);
        }
示例#4
0
        /// <summary>
        /// Song of healing.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="spell"></param>
        /// <param name="level"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static bool SongHealing(CharData ch, Spell spell, int level, Target target)
        {
            foreach (CharData victim in ch.InRoom.People)
            {
                if (!ch.IsSameGroup(victim))
                {
                    continue;
                }

                int heal = MUDMath.Dice(4, (level / 3)) + 1;

                if (victim.Hitpoints < victim.GetMaxHit())
                {
                    victim.Hitpoints = Math.Min(victim.Hitpoints + heal, victim.GetMaxHit());
                }
                victim.UpdatePosition();

                victim.SendText("&+WYour wounds begin to heal.&n\r\n");
            }
            return(true);
        }
示例#5
0
        /// <summary>
        /// Initialize a new PC with default values.
        /// </summary>
        public PC()
        {
            ++NumPc;
            Prompt         = "&+g<%hhp %mm %vmv>\r\n<&n%D %B&+g>&n ";
            Score          = 0.0;
            PageLength     = 25;
            IsSwitched     = false;
            Speaking       = 0;
            ActionFlags[0] = PLAYER_CAST_TICK.Vector | PLAYER_TELL.Vector | PLAYER_SHOUT.Vector |
                             PLAYER_PROMPT.Vector | PLAYER_COMBINE.Vector | PLAYER_MAP.Vector |
                             PLAYER_PAGER.Vector | PLAYER_AUTOWRAP.Vector | PLAYER_COLOR.Vector | PLAYER_VICIOUS.Vector;
            HitpointModifier = 0;
            GuildRank        = 0;
            Train            = 0;
            Frags            = 0;
            PlayerKills      = 0;
            PlayerDeaths     = 0;
            MobKills         = 0;
            MobDeaths        = 0;
            FirstaidTimer    = 0;
            CreationTime     = new DateTime(); // Creation time, actual.
            Created          = new ItemStatus();
            Destroyed        = new ItemStatus();
            Birthdate        = new DateTime(); // Creation time used for age calculations.  Unlike creation time, it can change.
            OriginalHome     = StaticRooms.GetRoomNumber("ROOM_NUMBER_START");
            CurrentHome      = StaticRooms.GetRoomNumber("ROOM_NUMBER_START");
            Height           = 60 + MUDMath.Dice(2, 10);
            Weight           = 15 + (Height * 2);
            RaceStrMod       = 0;
            RaceIntMod       = 0;
            RaceWisMod       = 0;
            RaceDexMod       = 0;
            RaceConMod       = 0;
            RaceAgiMod       = 0;
            RaceChaMod       = 0;
            RacePowMod       = 0;
            RaceLukMod       = 0;
            MaxStrMod        = 0;
            MaxIntMod        = 0;
            MaxWisMod        = 0;
            MaxDexMod        = 0;
            MaxConMod        = 0;
            MaxAgiMod        = 0;
            MaxChaMod        = 0;
            MaxPowMod        = 0;
            MaxLukMod        = 0;
            AggressiveLevel  = -1;
            Tradition        = 0;
            SkillPoints      = 0;
            Chi                 = 0;
            MaxChi              = 0;
            Stance              = String.Empty;
            LastRentLocation    = 0;
            LostHp              = 0;
            MonkRestriction     = 0;
            IsWieldingTwohanded = false;
            Editing             = SocketConnection.EditState.none;
            Security            = 0;
            int count;

            SpellAptitude = new SerializableDictionary <String, Int32>();
            SkillAptitude = new SerializableDictionary <String, Int32>();
            SongAptitude  = new SerializableDictionary <String, Int32>();
            MonkAptitude  = new SerializableDictionary <String, Int32>();

            LanguageAptitude = new int[Race.MAX_LANG];
            for (count = 0; count < Race.MAX_LANG; ++count)
            {
                LanguageAptitude[count] = 0;
            }
            TrophyData = new TrophyData[Limits.MAX_LEVEL];
            for (count = 0; count < Limits.MAX_LEVEL; ++count)
            {
                TrophyData[count] = new TrophyData();
                TrophyData[count].MobIndexNumber = 0;
                TrophyData[count].NumberKilled   = 0;
            }
            Thirst        = 48;
            Hunger        = 48;
            Drunk         = 0;
            Bank          = new Coins();
            Bank.Copper   = 0;
            Bank.Silver   = 0;
            Bank.Gold     = 0;
            Bank.Platinum = 0;
        }
示例#6
0
        /// <summary>
        /// Create an instance of a mobile from the provided template.
        /// </summary>
        /// <param name="mobTemplate"></param>
        /// <returns></returns>
        public static CharData CreateMobile(MobTemplate mobTemplate)
        {
            int count;

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

            CharData mob = new CharData();

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

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

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

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

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

            mob.Hitpoints = mob.GetMaxHit();

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

            // Insert in list.
            CharList.Add(mob);
            // Increment count of in-game instances of mob.
            mobTemplate.NumActive++;
            return(mob);
        }
示例#7
0
        static bool SpecHammer(System.Object obj, System.Object owner, bool hit)
        {
            CharData keeper = (CharData)owner;
            bool     retval = false;

            if (!keeper)
            {
                return(false);
            }

            //Hum
            if ((!keeper.Fighting && MUDMath.NumberPercent() < 10) ||
                (keeper.Fighting && MUDMath.NumberPercent() < 2))
            {
                SocketConnection.Act("&+LA faint hum can be heard from&n $p&n &+Lcarried by&n $n&n.",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.room);
                SocketConnection.Act("&+LA faint hum can be heard from&n $p&n &+Lyou are carrying.&n",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.character);
                if (!keeper.IsAffected(Affect.AFFECT_STONESKIN) && MUDMath.NumberPercent() < 30)
                {
                    Spell spl = Spell.SpellList["stoneskin"];
                    if (spl != null)
                    {
                        spl.Invoke(keeper, 60, keeper);
                    }
                }
                retval = true;
            }

            if (!keeper.Fighting)
            {
                return(retval);
            }

            // it fires off 1 in 12 times
            if (MUDMath.NumberPercent() > 8)
            {
                return(false);
            }

            // if not wielded as primary, do nothing
            if (Object.GetEquipmentOnCharacter(keeper, ObjTemplate.WearLocation.hand_one) != obj)
            {
                return(false);
            }

            // grumbar's hammer needs to be grounded to work
            if (keeper.FlightLevel != 0)
            {
                return(false);
            }

            // need to have some earthly elements around
            //    if ( keeper.in_room.sector == RoomIndex.TerrainType.plane_of_air ||
            //         keeper.in_room.sector == RoomIndex.TerrainType.plane_of_water ||
            //         keeper.in_room.sector == RoomIndex.TerrainType.plane_of_fire )
            //        return false;

            CharData vict = keeper.Fighting;

            switch (MUDMath.NumberRange(1, 3))
            {
            case 1:
                //throw a wall
                int dir = MUDMath.NumberRange(0, Limits.MAX_DIRECTION - 1);
                if (keeper.InRoom.ExitData[dir])
                {
                    Spell spl = Spell.SpellList["wall of stone"];
                    if (spl != null)
                    {
                        spl.Invoke(keeper, 50, dir.ToString());
                    }
                }
                retval = true;
                break;

            case 2:
                // earthen rain
                if (!keeper.IsOutside())
                {
                    retval = false;
                    break;
                }
                SocketConnection.Act("Your $p crushes $N in a rain of &+yearth&N and &+Lstone&N!", keeper,
                                     (Object)obj, vict, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n's $p crushes you under a rain of &+yearth&N and &+Lstone&N!", keeper,
                                     (Object)obj, vict, SocketConnection.MessageTarget.victim);
                SocketConnection.Act("$n's $p crushes $N under a rain of &+yearth&N and &+Lstone&N!.", keeper,
                                     (Object)obj, vict, SocketConnection.MessageTarget.everyone_but_victim);
                // same damage as earthen rain at level 50
                int dam = MUDMath.Dice(150, 3) + 100;
                Combat.InflictSpellDamage(keeper, vict, dam, "earthen rain", AttackType.DamageType.crushing);
                retval = true;
                break;

            case 3:
                // cause an earthquake
                SocketConnection.Act("Your $p causes the ground to rise up!",
                                     keeper, (Object)obj, vict, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n's $p blasts the ground with a &+yshockwave&N!",
                                     keeper, (Object)obj, null, SocketConnection.MessageTarget.room);
                foreach (CharData targetChar in keeper.InRoom.People)
                {
                    if ((targetChar == keeper) || targetChar.IsImmortal())
                    {
                        continue;
                    }
                    if (keeper.IsSameGroup(targetChar))
                    {
                        continue;
                    }
                    if (targetChar.IsAffected(Affect.AFFECT_FLYING))
                    {
                        continue;
                    }
                    if (keeper.IsNPC() && targetChar.IsNPC() && !vict.IsSameGroup(targetChar))
                    {
                        continue;
                    }
                    if (Magic.SpellSavingThrow(60, targetChar, AttackType.DamageType.earth))
                    {
                        SocketConnection.Act("You wobble precipitously, but keep your feet.",
                                             keeper, null, targetChar, SocketConnection.MessageTarget.victim);
                        SocketConnection.Act("$n&n stumbles slightly but keeps $s balance.", targetChar, null, null, SocketConnection.MessageTarget.room);
                    }
                    else
                    {
                        SocketConnection.Act("You are knocked to the ground!",
                                             keeper, null, targetChar, SocketConnection.MessageTarget.victim);
                        SocketConnection.Act("$n&n is knocked to the ground!", targetChar, null, null, SocketConnection.MessageTarget.room);
                        targetChar.CurrentPosition = Position.kneeling;
                        targetChar.WaitState(Event.TICK_COMBAT);
                    }
                }     // end for
                retval = true;
                break;

            default:
                break;
            } //end switch
            return(retval);
        }
示例#8
0
        /// <summary>
        /// Updates the weather and game hour.  Also updates things that depend on the game hour.
        ///
        /// Weather depends on the time of year.
        /// </summary>
        public void UpdateWeather()
        {
            string text = String.Empty;

            UpdatePlayerCount();

            switch (++GameHour)
            {
            case 4:
                WeatherData.Sunlight = SunType.moonset;
                if (WeatherData.MoonPhase != MoonPhase.new_moon)
                {
                    text = "&+cThe &+Cmoon&n&+c slowly &+Lvanishes&n&+c from the horizon.&n\r\n";
                }
                break;

            case 6:
                WeatherData.Sunlight = SunType.sunrise;
                text = "&+cThe first &+Clights&n&+c of &+md&+Maw&n&+mn &n&+cilluminate the&+C sky&n.\r\n";
                WeatherData.Temperature += MUDMath.FuzzyNumber(10);
                break;

            case 7:
                WeatherData.Sunlight = SunType.daytime;
                text = "&+MA new day has begun as the &+Ysun&+M rises&n.&n\r\n";
                if (GameMonth <= 4 || GameMonth >= 15)
                {
                    WeatherData.Temperature = MUDMath.FuzzyNumber(20);
                }
                else
                {
                    WeatherData.Temperature = MUDMath.FuzzyNumber(50);
                }
                break;

            case 12:
                text = "&+cThe &+Ysun&n &+cnow hangs at high noon&n.\r\n";
                WeatherData.Temperature += MUDMath.FuzzyNumber(20);
                break;

            case 19:
                WeatherData.Sunlight = SunType.sunset;
                text = "&+mThe &+Ysun&n&+m slowly slips off the &+Mhorizon&n.\r\n";
                WeatherData.Temperature -= MUDMath.FuzzyNumber(20);
                break;

            case 20:
                WeatherData.Sunlight = SunType.night;
                text = "&+LThe night begins as darkness settles across the lands&n.\r\n";
                WeatherData.Temperature -= MUDMath.FuzzyNumber(10);
                break;

            case Limits.HOURS_PER_DAY:
                WeatherData.Sunlight     = SunType.moonrise;
                WeatherData.Temperature -= MUDMath.FuzzyNumber(10);
                GameHour = 0;
                GameDay++;

                // Moon stuff
                WeatherData.Moonday++;

                if (WeatherData.Moonday >= LUNAR_CYCLE_DAYS)
                {
                    WeatherData.MoonPhase = MoonPhase.new_moon;
                    WeatherData.Moonday   = 0;
                }
                else
                {
                    if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS / 8))
                    {
                        WeatherData.MoonPhase = MoonPhase.new_moon;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS / 4))
                    {
                        WeatherData.MoonPhase = MoonPhase.quarter;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS * 3 / 8))
                    {
                        WeatherData.MoonPhase = MoonPhase.half;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS / 2))
                    {
                        WeatherData.MoonPhase = MoonPhase.three_quarter;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS * 5 / 8))
                    {
                        WeatherData.MoonPhase = MoonPhase.full;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS * 3 / 4))
                    {
                        WeatherData.MoonPhase = MoonPhase.three_quarter;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS * 7 / 8))
                    {
                        WeatherData.MoonPhase = MoonPhase.half;
                    }
                    else if (WeatherData.Moonday < (LUNAR_CYCLE_DAYS))
                    {
                        WeatherData.MoonPhase = MoonPhase.quarter;
                    }
                }

                switch (WeatherData.MoonPhase)
                {
                default:
                    break;

                case MoonPhase.new_moon:
                    text += "&+LThe night sky is overshadowed by an uncommon darkness.&n\r\n";
                    break;

                case MoonPhase.full:
                    text += "&n&+LThe &+Cmoon&n&+L rises full, casting a &n&+wsi&+Wlv&n&+wer &n&+cglow&+L across the entire sky.&n\r\n";
                    break;

                case MoonPhase.three_quarter:
                    text += "&n&+LThe &+Cmoon&n&+L ascends, a small &n&+csliver&+L absent against the night sky.&n\r\n";
                    break;

                case MoonPhase.half:
                    text += "&n&+LA giant half-circle, the &+Cmoon&n&+L rises against the blanket of night.&n\r\n";
                    break;

                case MoonPhase.quarter:
                    text += "&n&+LThe &+Cmoon&n&+L rises, a &n&+wsi&+Wlv&n&+wer &+csliver&n&+L against the dark firmament.&n\r\n";
                    break;
                }
                break;
            }

            if (GameDay >= Limits.DAYS_PER_MONTH)
            {
                GameDay = 0;
                GameMonth++;
            }

            if (GameMonth >= Limits.MONTHS_PER_YEAR)
            {
                GameMonth = 0;
                GameYear++;
            }

            // Weather change.
            WeatherData.WindDirection += MUDMath.NumberRange(0, 2) - 1;

            int diff = 0;

            if (GameMonth >= 9 && GameMonth <= 16)
            {
                diff = WeatherData.BarometricPressure > 985 ? -2 : 2;
            }
            else
            {
                diff = WeatherData.BarometricPressure > 1015 ? -2 : 2;
            }

            WeatherData.Change += diff * MUDMath.Dice(1, 4) + MUDMath.Dice(2, 6) - MUDMath.Dice(2, 6);
            WeatherData.Change  = Math.Max(WeatherData.Change, -12);
            WeatherData.Change  = Math.Min(WeatherData.Change, 12);

            WeatherData.BarometricPressure += WeatherData.Change;
            WeatherData.BarometricPressure  = Math.Max(WeatherData.BarometricPressure, 960);
            WeatherData.BarometricPressure  = Math.Min(WeatherData.BarometricPressure, 1040);

            switch (WeatherData.Sky)
            {
            default:
                Log.Error("WeatherUpdate: bad sky {0}.", WeatherData.Sky);
                WeatherData.Sky = SkyType.clear;
                break;

            case SkyType.clear:
                if (WeatherData.BarometricPressure < 990 || (WeatherData.BarometricPressure < 1010 && MUDMath.NumberBits(2) == 0))
                {
                    if (GameMonth <= 3 || GameMonth >= 11)
                    {
                        text += "&+wA few &+Wf&n&+wl&+Wa&n&+wk&+We&n&+ws of &+Ws&n&+wn&+Wo&n&+ww&+w are falling&n.\r\n";
                        WeatherData.Temperature -= 10;
                    }
                    else
                    {
                        text += "&+LStorm clouds &n&+mthunder&+L in the distance&n.\r\n";
                    }
                    WeatherData.Sky        = SkyType.cloudy;
                    WeatherData.WindSpeed += 10;
                }
                break;

            case SkyType.cloudy:
                if (WeatherData.BarometricPressure < 970 || (WeatherData.BarometricPressure < 990 && MUDMath.NumberBits(2) == 0))
                {
                    if (GameMonth <= 3 || GameMonth >= 11)
                    {
                        text += "&+wThe &+Wharsh s&n&+wn&+Wo&n&+ww-&+Lstorm&n&+w makes visibility difficult&n.\r\n";
                        WeatherData.Temperature -= 10;
                    }
                    else
                    {
                        text += "&+cSmall drops of &+Crain&n&+w m&+Wis&n&+wt the air&n.\r\n";
                    }
                    WeatherData.Sky        = SkyType.rain;
                    WeatherData.WindSpeed += 10;
                }

                if (WeatherData.BarometricPressure > 1030 && MUDMath.NumberBits(2) == 0)
                {
                    if (GameMonth <= 3 || GameMonth >= 11)
                    {
                        text += "&+wThe &+Wsnow&n&+w-&+Lstorm&n&+w seems to settle&n.\r\n";
                        WeatherData.Temperature += 10;
                    }
                    else
                    {
                        text += "&+cThe &+Cclouds&n&+c disappear from the skyline&n.\r\n";
                    }
                    WeatherData.Sky        = SkyType.clear;
                    WeatherData.WindSpeed -= 10;
                }
                break;

            case SkyType.rain:
                if (WeatherData.BarometricPressure < 970 && MUDMath.NumberBits(2) == 0)
                {
                    if (GameMonth <= 3 || GameMonth >= 11)
                    {
                        text += "&+wThe &+Wsnow-&+cstorm&n&+w has evolved into a full &+Cblizzard&n.\r\n";
                        WeatherData.Temperature -= 30;
                    }
                    else
                    {
                        text += "&+WLightning flashes across the sky&n.\r\n";
                    }
                    WeatherData.Sky        = SkyType.thunderstorm;
                    WeatherData.WindSpeed += 10;
                }

                if (WeatherData.BarometricPressure > 1030 || (WeatherData.BarometricPressure > 1010 && MUDMath.NumberBits(2) == 0))
                {
                    if (GameMonth <= 3 || GameMonth >= 11)
                    {
                        text += "&+wThe &+Ws&n&+wn&+Wo&n&+ww seems to be letting up&n.\r\n";
                        WeatherData.Temperature += 30;
                    }
                    else
                    {
                        text += "&+cThe &+Crain&n&+c slows to a drizzle then quits&n.\r\n";
                    }
                    WeatherData.Sky        = SkyType.cloudy;
                    WeatherData.WindSpeed -= 10;
                }
                break;

            case SkyType.thunderstorm:
                if (WeatherData.BarometricPressure > 1010 || (WeatherData.BarometricPressure > 990 && MUDMath.NumberBits(2) == 0))
                {
                    if (GameMonth <= 3 || GameMonth >= 11)
                    {
                        text += "&+wThe &+Wblizzard&n&+w subsides&n.\r\n";
                        WeatherData.Temperature += 10;
                    }
                    else
                    {
                        text += "&n&+wThe &+Lthunder &N&+wand &+Clightning&n&+w has stopped&N.\r\n";
                    }
                    WeatherData.Sky        = SkyType.rain;
                    WeatherData.WindSpeed -= 10;
                    break;
                }
                break;
            }

            if (text.Length > 0)
            {
                foreach (SocketConnection socket in Database.SocketList)
                {
                    if (socket.ConnectionStatus == SocketConnection.ConnectionState.playing &&
                        socket.Character.IsOutside() && !socket.Character.IsUnderground() &&
                        socket.Character.IsAwake() && !socket.Character.InRoom.HasFlag(RoomTemplate.ROOM_NO_PRECIP))
                    {
                        socket.Character.SendText(text);
                    }
                }
            }

            foreach (SocketConnection playerSocket in Database.SocketList)
            {
                if ((playerSocket.ConnectionStatus == SocketConnection.ConnectionState.playing) &&
                    !playerSocket.Character.IsNPC())
                {
                    if (((PC)playerSocket.Character).FirstaidTimer > 0)
                    {
                        ((PC)playerSocket.Character).FirstaidTimer -= 1;
                    }
                }
            }

            return;
        }
示例#9
0
        /// <summary>
        /// Generic spell processing function.  Handles basic spells based on values set in the spell file.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="level"></param>
        /// <param name="target"></param>
        public void GenericSpellFunction(CharData ch, int level, Target target)
        {
            switch (ValidTargets)
            {
            case TargetType.singleCharacterOffensive:
            {
                CharData opponent = (CharData)target;

                if (level > LevelCap)
                {
                    level = LevelCap;
                }

                int damage = MUDMath.Dice(level, DamageDicePerLevel) + BaseDamage;

                bool saved   = Magic.SpellSavingThrow(level, opponent, DamageInflicted);
                bool affects = true;

                if (saved)
                {
                    switch (SavingThrowEffect)
                    {
                    case SavingThrowResult.negates:
                        damage  = 0;
                        affects = false;
                        ch.SendText("Nothing happens.\r\n");
                        return;

                    case SavingThrowResult.halfDamage:
                        damage /= 2;
                        affects = true;
                        break;

                    case SavingThrowResult.halfDamageNoAffects:
                        damage /= 2;
                        affects = true;
                        break;

                    case SavingThrowResult.fullDamageNoAffects:
                        affects = false;
                        break;

                    case SavingThrowResult.none:
                        affects = true;
                        break;
                    }
                }

                if (damage > 0)
                {
                    Combat.InflictSpellDamage(ch, opponent, damage, this, DamageInflicted);
                }

                if (affects)
                {
                    // Apply "negates" to character.
                    for (int n = 0; n < Negates.Length; n++)
                    {
                        opponent.RemoveAffect(new Bitvector(n, Negates[n]));
                    }
                    Affect af = new Affect();
                    af.Level      = ch.Level;
                    af.BitVectors = Provides;
                    af.Value      = Name;
                    af.Type       = Affect.AffectType.spell;
                    for (int p = 0; p < Provides.Length; p++)
                    {
                        if (Provides[p] != 0)
                        {
                            if (!ch.IsAffected(new Bitvector(p, Provides[p])))
                            {
                                opponent.AddAffect(af);
                                if (!String.IsNullOrEmpty(MessageCompleted))
                                {
                                    SocketConnection.Act(MessageCompleted, ch, null, null, SocketConnection.MessageTarget.character);
                                }
                                else
                                {
                                    ch.SendText("Ok.\r\n");
                                }
                                if (!String.IsNullOrEmpty(MessageCompletedToTarget))
                                {
                                    SocketConnection.Act(MessageCompletedToTarget, ch, opponent, null, SocketConnection.MessageTarget.victim);
                                }
                                if (!String.IsNullOrEmpty(MessageCompletedToRoom))
                                {
                                    SocketConnection.Act(this.MessageCompletedToRoom, ch, opponent, null, SocketConnection.MessageTarget.room);
                                }
                            }
                            else
                            {
                                switch (StackingType)
                                {
                                case StackType.addDuration:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell addDuration stacking types are not yet supported.");

                                case StackType.addModifier:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell addModifier stacking types are not yet supported.");

                                case StackType.addModifierAddDuration:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell addModifierAddDuration stacking types are not yet supported.");

                                case StackType.addModifierMaxDuration:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell addModifierMaxDuration stacking types are not yet supported.");

                                case StackType.alwaysReplace:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell alwaysReplace stacking types are not yet supported.");

                                case StackType.noRefresh:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    break;

                                case StackType.replaceDuration:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell replaceDuration stacking types are not yet supported.");

                                case StackType.takeMaxDuration:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell takeMaxDuration stacking types are not yet supported.");

                                case StackType.takeMaxModifier:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell takeMaxModifier stacking types are not yet supported.");

                                case StackType.takeMaxModifierAndDuration:
                                    ch.SendText("Your spell has no effect.\r\n");
                                    throw new NotSupportedException("Spell takeMaxModifierAndDuration stacking types are not yet supported.");
                                }
                            }
                        }
                    }
                }

                return;
            }

            case TargetType.singleCharacterDefensive:
            case TargetType.self:
            {
                CharData victim;
                if (ValidTargets == TargetType.self)
                {
                    victim = ch;
                }
                else
                {
                    victim = (CharData)target;
                    if (victim == null)
                    {
                        victim = ch;
                    }
                }

                for (int n = 0; n < Negates.Length; n++)
                {
                    victim.RemoveAffect(new Bitvector(n, Negates[n]));
                }

                Affect af = new Affect();
                af.Level      = ch.Level;
                af.BitVectors = Provides;
                af.Value      = Name;
                af.Type       = Affect.AffectType.spell;
                switch (this.Duration)
                {
                case SpellDurationType.oneHourPerlevel:
                    af.Duration = level;
                    break;

                case SpellDurationType.quarterHourPerLevel:
                    af.Duration = level / 4;
                    break;

                case SpellDurationType.halfHourPerLevel:
                    af.Duration = level / 2;
                    break;

                case SpellDurationType.oneDay:
                    af.Duration = 24;
                    break;

                case SpellDurationType.threeHoursPerLevel:
                    af.Duration = level * 3;
                    break;

                case SpellDurationType.twoHoursPerLevel:
                    af.Duration = level * 2;
                    break;

                case SpellDurationType.fourHoursPerLevel:
                    af.Duration = level * 4;
                    break;

                case SpellDurationType.oneHour:
                    af.Duration = 1;
                    break;

                case SpellDurationType.permanent:
                    af.Duration = -1;
                    break;

                case SpellDurationType.sixHours:
                    af.Duration = 6;
                    break;

                case SpellDurationType.threeHours:
                    af.Duration = 3;
                    break;

                case SpellDurationType.twoHours:
                    af.Duration = 2;
                    break;

                default:
                    throw new NotSupportedException("Spells with duration type " + Duration + " are not implemented yet.");
                }
                foreach (AffectApplyType apply in Modifies)
                {
                    af.AddModifier(apply.Location, apply.Amount);
                }

                for (int p = 0; p < Provides.Length; p++)
                {
                    if (Provides[p] != 0)
                    {
                        if (!ch.IsAffected(new Bitvector(p, Provides[p])))
                        {
                            victim.AddAffect(af);
                            if (!String.IsNullOrEmpty(MessageCompleted))
                            {
                                SocketConnection.Act(MessageCompleted, ch, null, null, SocketConnection.MessageTarget.character);
                            }
                            else
                            {
                                ch.SendText("Ok.\r\n");
                            }
                            if (!String.IsNullOrEmpty(MessageCompletedToTarget))
                            {
                                SocketConnection.Act(MessageCompletedToTarget, ch, victim, null, SocketConnection.MessageTarget.victim);
                            }
                            if (!String.IsNullOrEmpty(MessageCompletedToRoom))
                            {
                                SocketConnection.Act(MessageCompletedToRoom, ch, victim, null, SocketConnection.MessageTarget.room);
                            }
                        }
                        else
                        {
                            switch (StackingType)
                            {
                            case StackType.addDuration:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell addDuration stacking types are not yet supported.");

                            case StackType.addModifier:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell addModifier stacking types are not yet supported.");

                            case StackType.addModifierAddDuration:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell addModifierAddDuration stacking types are not yet supported.");

                            case StackType.addModifierMaxDuration:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell addModifierMaxDuration stacking types are not yet supported.");

                            case StackType.alwaysReplace:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell alwaysReplace stacking types are not yet supported.");

                            case StackType.noRefresh:
                                ch.SendText("Your spell has no effect.\r\n");
                                break;

                            case StackType.replaceDuration:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell replaceDuration stacking types are not yet supported.");

                            case StackType.takeMaxDuration:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell takeMaxDuration stacking types are not yet supported.");

                            case StackType.takeMaxModifier:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell takeMaxModifier stacking types are not yet supported.");

                            case StackType.takeMaxModifierAndDuration:
                                ch.SendText("Your spell has no effect.\r\n");
                                throw new NotSupportedException("Spell takeMaxModifierAndDuration stacking types are not yet supported.");
                            }
                        }
                    }
                }
            }
            break;

            case TargetType.multipleCharacterOffensive:
            {
            }
            break;

            case TargetType.objectCorpse:
            {
            }
            break;

            case TargetType.objectInInventory:
            {
            }
            break;

            case TargetType.objectInRoom:
            {
            }
            break;

            case TargetType.objectOrCharacter:
            {
            }
            break;

            case TargetType.ritual:
            {
            }
            break;

            case TargetType.singleCharacterRanged:
            {
                CharData opponent = (CharData)target;

                if (level > LevelCap)
                {
                    level = LevelCap;
                }

                int damage = MUDMath.Dice(level, DamageDicePerLevel) + BaseDamage;

                bool saved   = Magic.SpellSavingThrow(level, opponent, DamageInflicted);
                bool affects = true;

                if (saved)
                {
                    switch (SavingThrowEffect)
                    {
                    case SavingThrowResult.negates:
                        damage  = 0;
                        affects = false;
                        break;

                    case SavingThrowResult.halfDamage:
                        damage /= 2;
                        affects = true;
                        break;

                    case SavingThrowResult.halfDamageNoAffects:
                        damage /= 2;
                        affects = false;
                        break;

                    case SavingThrowResult.fullDamageNoAffects:
                        affects = false;
                        break;

                    case SavingThrowResult.none:
                        affects = true;
                        break;
                    }
                }

                if (damage > 0)
                {
                    Combat.InflictSpellDamage(ch, opponent, damage, this, DamageInflicted);
                }

                if (affects)
                {
                    // TODO: Apply "provides" to character.
                    // TODO: Apply "negates" to character.
                }

                return;
            }

            case TargetType.singleCharacterWorld:
            {
            }
            break;

            case TargetType.trap:
            {
            }
            break;

            case TargetType.none:
            {
                Log.Error("Magic spell '" + Name + "' is flagged as TargetType.none.  This should never happen.  Fix it.");
            }
            break;
            }
        }
示例#10
0
        /// <summary>
        /// Summoning an elemental.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="spell"></param>
        /// <param name="level"></param>
        /// <param name="indexNumber"></param>
        public static void SummonElem(CharData ch, Spell spell, int level, int indexNumber)
        {
            int numpets = 0;

            foreach (CharData petChar in Database.CharList)
            {
                if (petChar != ch && petChar.Master == ch &&
                    petChar.IsNPC() && petChar.HasActionBit(MobTemplate.ACT_PET))
                {
                    numpets++;
                }
            }

            //just a WAG as far as number...check for some consistency with necro
            int maxpets = ch.Level / 20 + ch.GetCurrCha() / 35;

            if (ch.Level >= Limits.LEVEL_AVATAR)
            {
                string text = String.Format("You can summon at most {0} pets.\r\n", maxpets);
                ch.SendText(text);
            }
            if (numpets >= maxpets)
            {
                ch.SendText("You cannot handle any more pets!\r\n");
                return;
            }
            CharData elemental = Database.CreateMobile(Database.GetMobTemplate(indexNumber));

            elemental.AddToRoom(ch.InRoom);

            elemental.SetCoins(0, 0, 0, 0);
            elemental.Level        = 27 + MUDMath.Dice(2, 5);
            elemental.MaxHitpoints = 150 + MUDMath.Dice(16, level / 2);
            elemental.Hitpoints    = elemental.MaxHitpoints;
            elemental.ArmorPoints -= (ch.Level * 3 / 2);
            elemental.SetActionBit(MobTemplate.ACT_NOEXP);

            switch (indexNumber)
            {
            case StaticMobs.MOB_NUMBER_EARTH_PECH:
                SocketConnection.Act("$n&n rises from the ground before your eyes.", elemental,
                                     null, null, SocketConnection.MessageTarget.room);
                break;

            case StaticMobs.MOB_NUMBER_AIR_SLYPH:
                elemental.ArmorPoints = -130;
                elemental.PermAgility = 100;
                SocketConnection.Act("$n&n appears out of thin air.", elemental, null, null, SocketConnection.MessageTarget.room);
                break;

            case StaticMobs.MOB_NUMBER_FIRE_SERPENT:
                SocketConnection.Act("$n&n bursts into existence in a roaring ball of flame.",
                                     elemental, null, null, SocketConnection.MessageTarget.room);
                break;

            case StaticMobs.MOB_NUMBER_WATER_NEREID:
                SocketConnection.Act("$n&n coalesces into existence.", elemental, null, null, SocketConnection.MessageTarget.room);
                elemental.MaxHitpoints += 100;
                elemental.Hitpoints     = elemental.MaxHitpoints;
                break;

            default:
                Log.Error("SummonElem: bad indexNumber in switch: " + indexNumber);
                ch.SendText("You managed to summon a bad indexNumber! Shame on you.\r\n");
                break;
            }
            SocketConnection.Act("$N&n says 'Your wish is my command $n&n.'", ch, null, elemental, SocketConnection.MessageTarget.room);
            SocketConnection.Act("$N&n tells you 'Your wish is my command.'", ch, null, elemental, SocketConnection.MessageTarget.character);
            CharData.AddFollower(elemental, ch);
            elemental.Master = ch;
            Affect af = new Affect(Affect.AffectType.spell, spell.Name, level / 2 + MUDMath.Dice(4, level / 2), Affect.Apply.none, 0, Affect.AFFECT_CHARM);

            elemental.AddAffect(af);
            // Set the MobIndex.ACT_PET bit as well
            elemental.SetActionBit(MobTemplate.ACT_PET);
            elemental.FlightLevel = ch.FlightLevel;
            if (ch.Fighting)
            {
                Combat.SetFighting(elemental, ch.Fighting);
            }

            return;
        }