Пример #1
0
        /// <summary>
        /// Resets a single area.
        /// </summary>
        public static void ResetArea(Area area)
        {
            if (area == null)
            {
                return;
            }
            Room room;
            int  indexNumber;

            area.DefenderSquads         = 0;
            area.NumDefendersDispatched = 0;
            for (indexNumber = area.LowRoomIndexNumber; indexNumber <= area.HighRoomIndexNumber; indexNumber++)
            {
                if (indexNumber == 0)
                {
                    continue;
                }
                room = Room.GetRoom(indexNumber);
                if (room && room.Area == area)
                {
                    room.ResetRoom(area.TimesReset);
                }
            }
            area.AgeInSeconds = MUDMath.NumberRange(-Event.AREA_RESET_VARIABILITY, Event.AREA_RESET_VARIABILITY);
            area.TimesReset++;
            return;
        }
Пример #2
0
 /// <summary>
 /// Provides an override to get the character's current repop point, or the default repop
 /// point if they don't have a current home set.
 /// </summary>
 /// <returns></returns>
 public override Room GetRepopPoint()
 {
     if (CurrentHome != 0)
     {
         return(Room.GetRoom(CurrentHome));
     }
     return(base.GetRepopPoint());
 }
Пример #3
0
        /// <summary>
        /// Returns a random room on one of the maps.
        /// Argument: 0 = any map
        ///           1 = Surface map 1
        ///           2 = Surface map 2
        ///           3 = Underdark map 1
        ///           4 = Underdark map 2
        ///           5 = Underdark map 3
        /// </summary>
        /// <param name="map"></param>
        /// <returns></returns>
        public static Room GetRandomMapRoom(Area map)
        {
            if (Room.Count < 1)
            {
                throw new IndexOutOfRangeException("No rooms loaded, cannot get a random map room.");
            }

            if (map == null)
            {
                List <Area> zones = new List <Area>();
                foreach (Area area in Database.AreaList)
                {
                    if (area.HasFlag(Area.AREA_WORLDMAP) && area.Rooms.Count > 0)
                    {
                        zones.Add(area);
                    }
                }
                if (zones.Count < 1)
                {
                    throw new IndexOutOfRangeException("GetRandomMapRoom(): No zones found with AREA_WORLDMAP flag set.");
                }
                int val = MUDMath.NumberRange(0, (zones.Count - 1));
                map = zones[val];
            }

            int max = map.Rooms.Count;

            if (max < 1)
            {
                throw new IndexOutOfRangeException("GetRandomMapRoom(): No rooms found in target zone.");
            }

            int  target = MUDMath.NumberRange(0, (map.Rooms.Count - 1));
            Room room   = Room.GetRoom(target);

            if (!room ||
                room.WorldmapTerrainType == 92 ||
                room.WorldmapTerrainType == 101 ||
                room.WorldmapTerrainType == 102 ||
                room.WorldmapTerrainType == 116 ||
                room.WorldmapTerrainType == 130 ||
                room.WorldmapTerrainType == 131 ||
                room.WorldmapTerrainType == 132 ||
                room.WorldmapTerrainType == 136 ||
                room.WorldmapTerrainType == 137 ||
                room.HasFlag(RoomTemplate.ROOM_PRIVATE) ||
                room.HasFlag(RoomTemplate.ROOM_SOLITARY) ||
                room.HasFlag(RoomTemplate.ROOM_NO_TELEPORT) ||
                room.TerrainType == TerrainType.underground_impassable)
            {
                room = GetRandomMapRoom(map);
            }
            return(room);
        }
Пример #4
0
 /// <summary>
 /// Find a door based on its name.
 /// </summary>
 /// <param name="ch"></param>
 /// <param name="argument"></param>
 /// <returns></returns>
 public static Room FindRoom(CharData ch, string argument)
 {
     Exit.Direction dir = FindExit(ch, argument);
     if (dir == Exit.Direction.invalid)
     {
         SocketConnection.Act("I see no door $T here.", ch, null, argument, SocketConnection.MessageTarget.character);
         return(null);
     }
     if (ch.InRoom.ExitData[(int)dir])
     {
         Room room = Room.GetRoom(ch.InRoom.ExitData[(int)dir].IndexNumber);
         return(room);
     }
     return(null);
 }
Пример #5
0
        /// <summary>
        /// Random room generation function.
        /// </summary>
        /// <returns></returns>
        public static Room GetRandomRoom()
        {
            Room room;

            for ( ; ;)
            {
                room = Room.GetRoom(MUDMath.NumberRange(0, 65535));
                if (room)
                {
                    if (!room.HasFlag(RoomTemplate.ROOM_PRIVATE) && !room.HasFlag(RoomTemplate.ROOM_SOLITARY))
                    {
                        break;
                    }
                }
            }

            return(room);
        }
Пример #6
0
        public static void ReturnToLoad(CharData ch)
        {
            if (!ch || !ch.InRoom)
            {
                return;
            }
            if (ch.InRoom.Area != Room.GetRoom(ch.LoadRoomIndexNumber).Area)
            {
                return;
            }

            Exit.Direction dir = FindPath(ch.InRoom.IndexNumber, ch.LoadRoomIndexNumber, ch, -40000, true);

            if (dir == Exit.Direction.invalid)
            {
                return;
            }

            if (ch.InRoom.ExitData[(int)dir].HasFlag(Exit.ExitFlag.closed) &&
                !ch.IsAffected(Affect.AFFECT_PASS_DOOR) && !ch.HasInnate(Race.RACE_PASSDOOR))
            {
                CommandType.Interpret(ch, "unlock " + dir.ToString());
                CommandType.Interpret(ch, "open " + dir.ToString());
                return;
            }

            ch.Move(dir);

            if (!ch.InRoom)
            {
                string text = "Return_to_load: no ch._inRoom!  Mob #" + ch.MobileTemplate.IndexNumber + ", _name: " +
                              ch.Name + ".  Placing mob in limbo (mob.AddToRoom()).";
                Log.Error(text, 0);
                ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO")));
                ImmortalChat.SendImmortalChat(ch, ImmortalChat.IMMTALK_SPAM, 0, text);
                return;
            }
            return;
        }
Пример #7
0
        // Dispatches a guard to hunt down the player that has committed a crime and
        // has the guard capture them.
        static void DispatchGuard(CharData ch)
        {
            CharData mob = Database.CreateMobile(Database.GetMobTemplate(ch.InRoom.Area.DefenderTemplateNumber));

            mob.AddToRoom(Room.GetRoom(ch.InRoom.Area.BarracksRoom));
            if (!mob.HasActionBit(MobTemplate.ACT_MEMORY))
            {
                mob.SetActionBit(MobTemplate.ACT_MEMORY);
            }
            if (!mob.HasActionBit(MobTemplate.ACT_HUNTER))
            {
                if (mob.HasActionBit(MobTemplate.ACT_SENTINEL))
                {
                    mob.RemoveActionBit(MobTemplate.ACT_SENTINEL);
                }
            }
            mob.SetAffectBit(Affect.AFFECT_JUSTICE_TRACKER);
            mob.MobileTemplate.AddSpecFun("spec_justice_guard");
            Combat.StartGrudge(mob, ch, false);

            return;
        }
Пример #8
0
        /// <summary>
        /// Tracking code.
        /// </summary>
        /// <param name="ch"></param>
        public static void HuntVictim(CharData ch)
        {
            if (!ch || !ch.Hunting || !ch.IsAffected(Affect.AFFECT_TRACK))
            {
                return;
            }

            if (ch.CurrentPosition != Position.standing)
            {
                if (ch.IsAffected(Affect.AFFECT_TRACK))
                {
                    ch.SendText("You abort your tracking effort.\r\n");
                    ch.RemoveAffect(Affect.AFFECT_TRACK);
                    Combat.StopHunting(ch);
                }
                return;
            }

            CharData tmp = null;

            try
            {
                /*
                 * Make sure the victim still exists.
                 */
                bool found = false;
                foreach (CharData it in Database.CharList)
                {
                    ch = it;
                    if (ch.Hunting != null && ch.Hunting.Who == tmp)
                    {
                        found = true;
                    }
                }

                if (!found || !CharData.CanSee(ch, ch.Hunting.Who))
                {
                    if (!ch.IsAffected(Affect.AFFECT_TRACK))
                    {
                        CommandType.Interpret(ch, "say Damn!  My prey is gone!");
                    }
                    else
                    {
                        ch.SendText("The trail seems to disappear.\r\n");
                        ch.RemoveAffect(Affect.AFFECT_TRACK);
                    }
                    Combat.StopHunting(ch);
                    return;
                }

                if (ch.InRoom == ch.Hunting.Who.InRoom)
                {
                    if (ch.Fighting)
                    {
                        return;
                    }
                    FoundPrey(ch, ch.Hunting.Who);
                    return;
                }

                ch.WaitState(Skill.SkillList["track"].Delay);
                Exit.Direction dir = FindPath(ch.InRoom.IndexNumber, ch.Hunting.Who.InRoom.IndexNumber, ch, -40000, true);

                if (dir == Exit.Direction.invalid)
                {
                    if (!ch.IsAffected(Affect.AFFECT_TRACK))
                    {
                        SocketConnection.Act("$n&n says 'Damn! Lost $M!'", ch, null, ch.Hunting.Who, SocketConnection.MessageTarget.room);
                    }
                    else
                    {
                        ch.SendText("You lose the trail.\r\n");
                        ch.RemoveAffect(Affect.AFFECT_TRACK);
                        Combat.StopHunting(ch);
                    }
                    return;
                }

                /*
                 * Give a random direction if the mob misses the die roll.
                 */
                if (MUDMath.NumberPercent() > 75)   /* @ 25% */
                {
                    do
                    {
                        dir = Database.RandomDoor();
                    }while (!(ch.InRoom.ExitData[(int)dir]) || !(ch.InRoom.ExitData[(int)dir].TargetRoom));
                }

                if (ch.InRoom.ExitData[(int)dir].HasFlag(Exit.ExitFlag.closed))
                {
                    CommandType.Interpret(ch, "open " + dir.ToString());
                    return;
                }
                ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, String.Format("{0}&n leaves room {1} to the {2}.",
                                                                                                   ch.ShortDescription, ch.InRoom.IndexNumber, dir.ToString()));
                if (ch.IsAffected(Affect.AFFECT_TRACK))
                {
                    SocketConnection.Act(String.Format("You sense $N&n's trail {0} from here...", dir.ToString()),
                                         ch, null, ch.Hunting.Who, SocketConnection.MessageTarget.character);
                }
                ch.Move(dir);
                if (ch.IsAffected(Affect.AFFECT_TRACK))
                {
                    SocketConnection.Act("$n&n peers around looking for tracks.", ch, null, null, SocketConnection.MessageTarget.room);
                }

                if (!ch.Hunting)
                {
                    if (!ch.InRoom)
                    {
                        string text = String.Empty;
                        text = String.Format("Hunt_victim: no ch.in_room!  Mob #{0}, _name: {1}.  Placing mob in limbo (ch.AddToRoom()).",
                                             ch.MobileTemplate.IndexNumber, ch.Name);
                        Log.Error(text, 0);
                        ch.AddToRoom(Room.GetRoom(StaticRooms.GetRoomNumber("ROOM_NUMBER_LIMBO")));
                        text = String.Format("{0}&n has gone to limbo while hunting {1}.", ch.ShortDescription, ch.Hunting.Name);
                        ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, text);
                        return;
                    }
                    CommandType.Interpret(ch, "say Damn!  Lost my prey!");
                    return;
                }
                if (ch.InRoom == ch.Hunting.Who.InRoom)
                {
                    FoundPrey(ch, ch.Hunting.Who);
                }
                return;
            }
            catch (Exception ex)
            {
                Log.Error("Exception in HuntVictim: " + ex.ToString());
            }
        }
Пример #9
0
        /// <summary>
        /// Tracking mob has found the person its after. Attack or react accordingly.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="victim"></param>
        public static void FoundPrey(CharData ch, CharData victim)
        {
            string victname = String.Empty;
            string text     = String.Empty;
            string lbuf     = String.Empty;

            if (!victim)
            {
                Log.Error("FoundPrey: null victim", 0);
                return;
            }

            if (!victim.InRoom)
            {
                Log.Error("FoundPrey: null victim._inRoom", 0);
                return;
            }
            ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_HUNTING, 0, string.Format("{0}&n has found {1}.", ch.ShortDescription, victim.Name));

            if (ch.IsAffected(Affect.AFFECT_TRACK))
            {
                ch.RemoveAffect(Affect.AFFECT_TRACK);
                Combat.StopHunting(ch);
                return;
            }
            if (ch.IsAffected(Affect.AFFECT_JUSTICE_TRACKER))
            {
                /* Give Justice the ability to ground flying culprits */
                if (victim.FlightLevel != 0)
                {
                    SocketConnection.Act("$n&n forces you to land!", ch, null, victim, SocketConnection.MessageTarget.victim);
                    SocketConnection.Act("$n&n forces $N&n to land!", ch, null, victim, SocketConnection.MessageTarget.room_vict);
                    victim.FlightLevel = 0;
                }

                SocketConnection.Act("$n&n says, 'Stop, $N&n, you're under ARREST!'", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n says, 'Stop, $N&n, you're under ARREST!'", ch, null, victim, SocketConnection.MessageTarget.room);
                SocketConnection.Act("$n&n chains you up.", ch, null, victim, SocketConnection.MessageTarget.character);
                SocketConnection.Act("$n&n binds $N&n so $E can't move.", ch, null, victim, SocketConnection.MessageTarget.room);
                victim.SetAffectBit(Affect.AFFECT_BOUND);
                victim.RemoveFromRoom();

                if (ch.InRoom.Area.JailRoom != 0)
                {
                    victim.AddToRoom(Room.GetRoom(victim.InRoom.Area.JailRoom));
                }
                else
                {
                    victim.SendText("Justice is broken in this town - there is no jail and you're screwed.\r\n");
                }
                Combat.StopHunting(ch);
                return;
            }

            victname = victim.IsNPC() ? victim.ShortDescription : victim.Name;

            if (ch.FlightLevel != victim.FlightLevel)
            {
                if (ch.CanFly())
                {
                    if (ch.FlightLevel < victim.FlightLevel && ch.FlightLevel < CharData.FlyLevel.high)
                    {
                        Command.Fly(ch, new string[] { "up" });
                    }
                    else
                    {
                        Command.Fly(ch, new string[] { "down" });
                    }
                }
                else
                {
                    SocketConnection.Act("$n peers around looking for something.", ch, null, null, SocketConnection.MessageTarget.room);
                }
                return;
            }
            if (!CharData.CanSee(ch, victim))
            {
                if (MUDMath.NumberPercent() < 90)
                {
                    return;
                }
                switch (MUDMath.NumberBits(5))
                {
                case 0:
                    text = String.Format("You can't hide forever, {0}!", victname);
                    Command.Say(ch, new string[] { text });
                    break;

                case 1:
                    SocketConnection.Act("$n&n sniffs around the room.", ch, null, victim, SocketConnection.MessageTarget.room);
                    text = "I can smell your blood!";
                    Command.Say(ch, new string[] { text });
                    break;

                case 2:
                    text = String.Format("I'm going to tear {0} apart!", victname);
                    Command.Yell(ch, new string[] { text });
                    break;

                case 3:
                    Command.Say(ch, new string[] { "Just wait until I find you..." });
                    break;

                default:
                    SocketConnection.Act("$p peers about looking for something.", ch, null, null, SocketConnection.MessageTarget.room);
                    break;
                }
                return;
            }

            if (ch.InRoom.HasFlag(RoomTemplate.ROOM_SAFE) && ch.IsNPC())
            {
                text = String.Format("Hunting mob {0} found a safe room {1}.", ch.MobileTemplate.IndexNumber, ch.InRoom.IndexNumber);
                Log.Trace(text);
                return;
            }

            if (ch.CurrentPosition > Position.kneeling)
            {
                switch (MUDMath.NumberBits(5))
                {
                case 0:
                    text = String.Format("I will eat your heart, {0}!", victname);
                    Command.Say(ch, new string[] { text });
                    break;

                case 1:
                    text = String.Format("You want a piece of me, {0}?", victname);
                    Command.Say(ch, new string[] { text });
                    break;

                case 2:
                    text = String.Format("How does your flesh taste {0}, like chicken?", victname);
                    Command.Say(ch, new string[] { text });
                    break;

                case 3:
                    SocketConnection.Act("$n&n howls gleefully and lunges at $N&n!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                    SocketConnection.Act("$n&n howls gleefully and lunges at you!", ch, null, victim, SocketConnection.MessageTarget.victim);
                    break;

                case 4:
                    SocketConnection.Act("$n&n charges headlong into $N&n!", ch, null, victim, SocketConnection.MessageTarget.everyone_but_victim);
                    SocketConnection.Act("$n&n charges headlong into you!", ch, null, victim, SocketConnection.MessageTarget.victim);
                    break;

                default:
                    break;
                }
                Combat.StopHunting(ch);
                Combat.CheckAggressive(victim, ch);
                if (ch.Fighting)
                {
                    return;
                }

                // Backstab if able, otherwise just kill them.
                // Kill if they don't have the skill or if they don't have a stabber.
                if (!ch.HasSkill("backstab"))
                {
                    Combat.CombatRound(ch, victim, String.Empty);
                }
                else if (!Combat.Backstab(ch, victim))
                {
                    Combat.CombatRound(ch, victim, String.Empty);
                }
            }
            return;
        }
Пример #10
0
        public static Exit.Direction FindPath(int inRoomIndexNumber, int outRoomIndexNumber, CharData ch, int depth, bool inZone)
        {
            RoomTemplate herep;
            RoomTemplate startp;
            Exit         exitp;
            RoomQ        tmp_q;
            RoomQ        q_head;
            RoomQ        q_tail;
            HashHeader   x_room = null;
            bool         throughDoors;
            int          i;
            int          tmp_room;
            int          count = 0;

            // TODO: Re-enable this.
            return(Exit.Direction.invalid);

            if (depth < 0)
            {
                throughDoors = true;
                depth        = -depth;
            }
            else
            {
                throughDoors = false;
            }

            startp = Room.GetRoom(inRoomIndexNumber);

            InitHashTable(x_room, sizeof(int), 2048);
            //HashEnter(x_room, inRoomIndexNumber, null);

            /* initialize queue */
            q_head        = new RoomQ();
            q_tail        = q_head;
            q_tail.RoomNR = inRoomIndexNumber;
            q_tail.NextQ  = null;

            while (q_head != null)
            {
                herep = Room.GetRoom(q_head.RoomNR);
                /* for each room test all directions */
                if (herep.Area == startp.Area || inZone == false)
                {
                    /*
                     * only look in this zone...
                     * saves cpu time and makes world safer for players
                     */
                    for (i = 0; i < Limits.MAX_DIRECTION; i++)
                    {
                        exitp = herep.ExitData[i];
                        if (ExitOk(exitp) != 0 && (throughDoors ? GO_OK_SMARTER :
                                                   Macros.IsSet((int)Room.GetRoom(q_head.RoomNR).ExitData[i].ExitFlags, (int)Exit.ExitFlag.closed)))
                        {
                            /* next room */
                            tmp_room = herep.ExitData[i].TargetRoom.IndexNumber;
                            if (tmp_room != outRoomIndexNumber)
                            {
                                /*
                                 * shall we add room to queue ?
                                 * count determines total breadth and depth
                                 */
                                if (!hash_find(x_room, tmp_room) &&
                                    (count < depth))
                                /* && !IS_SET( RM_FLAGS(tmp_room), DEATH ) ) */
                                {
                                    ++count;
                                    /* mark room as visted and put on queue */

                                    tmp_q        = new RoomQ();
                                    tmp_q.RoomNR = tmp_room;
                                    tmp_q.NextQ  = null;
                                    q_tail.NextQ = tmp_q;
                                    q_tail       = tmp_q;

                                    /* Ancestor for first layer is the direction */

                                    /*HashEnter(x_room, tmp_room,
                                     *          ((long)hash_find(x_room, q_head.RoomNR) == -1)
                                     *          ? (Object)(i + 1)
                                     *          : hash_find(x_room, q_head.RoomNR));*/
                                }
                            }
                            else
                            {
                                /* have reached our goal so free queue */
                                tmp_room = q_head.RoomNR;
                                for (; q_head != null; q_head = tmp_q)
                                {
                                    tmp_q  = q_head.NextQ;
                                    q_head = null;
                                }
                                /* return direction if first layer */

                                /*if ((long)hash_find(x_room, tmp_room) == -1)
                                 * {
                                 *  if (x_room.Buckets)
                                 *  {
                                 *      // junk left over from a previous track
                                 *      DestroyHashTable(x_room, null);
                                 *  }
                                 *  return (i);*/
                                //}
                                //else
                                {
                                    /* else return the Ancestor */
                                    //long j;

                                    /*j = (long)hash_find(x_room, tmp_room);
                                     * if (x_room.Buckets)
                                     * {
                                     *  // junk left over from a previous track
                                     *  DestroyHashTable(x_room, null);
                                     * }
                                     * return (-1 + j);*/
                                }
                            }
                        }
                    }
                }

                /* free queue head and point to next entry */
                tmp_q  = q_head.NextQ;
                q_head = null;
                q_head = tmp_q;
            }

            /* couldn't find path */

            /*if (x_room.Buckets)
             * {
             *  // junk left over from a previous track
             *  DestroyHashTable(x_room, null);
             * }*/
            return(Exit.Direction.invalid);
        }
Пример #11
0
        /// <summary>
        /// Alert and dispatch the guards when an enemy has entered the area.
        /// </summary>
        /// <param name="ch"></param>
        static void StartInvasion(CharData ch)
        {
            SocketConnection socket;
            int      count;
            CharData mob;
            string   lbuf;

            // if there are no protector mobs, who cares if someone walks in.
            if (ch.InRoom.Area.DefenderTemplateNumber == 0 || ch.InRoom.Area.DefendersPerSquad == 0)
            {
                lbuf = String.Format("Start_invasion: no defender mobs");
                ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf);
                return;
            }

            // any town can only dispatch 5 batches of guards.
            if (ch.InRoom.Area.NumDefendersDispatched >= (ch.InRoom.Area.DefendersPerSquad * 5))
            {
                //    if( ch.in_room.area.dispatched >= (ch.in_room.area.defender_num *
                //        ch.in_room.area.squads )) {
                lbuf = String.Format("Start_invasion: dispatched all defender mobs, disregarding");
                ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf);
                //      return;
            }

            // warn of invasion
            foreach (SocketConnection it in Database.SocketList)
            {
                socket = it;
                if (socket.ConnectionStatus == SocketConnection.ConnectionState.playing &&
                    socket.Character.InRoom.Area == ch.InRoom.Area)
                {
                    socket.Character.SendText("&+RYou hear the guards sound the invasion alarm!\r\n");
                }
            }

            // create and dispatch defenders
            for (count = 0; count < ch.InRoom.Area.DefendersPerSquad; ++count)
            {
                if (ch.InRoom.Area.NumDefendersDispatched >= ch.InRoom.Area.DefendersPerSquad * 5)
                {
                    break;
                }
                mob = Database.CreateMobile(Database.GetMobTemplate(ch.InRoom.Area.DefenderTemplateNumber));
                mob.AddToRoom(Room.GetRoom(ch.InRoom.Area.BarracksRoom));
                if (!mob.HasActionBit(MobTemplate.ACT_MEMORY))
                {
                    mob.SetActionBit(MobTemplate.ACT_MEMORY);
                }
                if (!mob.HasActionBit(MobTemplate.ACT_HUNTER))
                {
                    mob.SetActionBit(MobTemplate.ACT_HUNTER);
                }
                if (mob.HasActionBit(MobTemplate.ACT_SENTINEL))
                {
                    mob.RemoveActionBit(MobTemplate.ACT_SENTINEL);
                }
                mob.MobileTemplate.AddSpecFun("spec_justice_guard");
                Combat.StartGrudge(mob, ch, false);
                ch.InRoom.Area.NumDefendersDispatched++;
            }
            ch.InRoom.Area.DefenderSquads++;

            return;
        }
Пример #12
0
        /// <summary>
        /// Loads the entire MUD database including all classes, races, areas, helps, sytem data, etc.
        /// </summary>
        public void LoadDatabase()
        {
            DatabaseIsBooting = true;

            Log.Trace(DateTime.Now.ToShortDateString() + " BOOT: -------------------------[ Boot Log ]-------------------------");

            Log.Trace("Validating that player directories exist.");
            for (Char letter = 'a'; letter <= 'z'; letter++)
            {
                String directory = FileLocation.PlayerDirectory + letter;
                if (!Directory.Exists(directory))
                {
                    Log.Trace("Creating directory: " + directory + ".");
                    Directory.CreateDirectory(directory);
                }
            }
            Log.Trace("Player directories validated.");

            Log.Trace("Loading Database.SystemData.");
            Sysdata.Load();
            SystemData.CurrentTime  = DateTime.Now;
            SystemData.GameBootTime = SystemData.CurrentTime;

            // Set time and weather.
            Log.Trace("Setting time and weather.");
            SystemData.SetWeather();

            Log.Trace("Loading static rooms.");
            StaticRooms.Load();
            Log.Trace("Loaded " + StaticRooms.Count + " static rooms.");

            Log.Trace("Loading spells.");
            Spell.LoadSpells();
            Log.Trace("Loaded " + Spell.SpellList.Count + " spells.");

            Log.Trace("Loading skills.");
            Skill.LoadSkills();
            Log.Trace("Loaded " + Skill.SkillList.Count + " skills.");

            Log.Trace("Loading races.");
            Race.LoadRaces();
            Log.Trace("Loaded " + Race.Count + " races.");

            Log.Trace("Initializing skill Levels.");
            {
                int cclass;

                foreach (KeyValuePair <String, Skill> kvp in Skill.SkillList)
                {
                    for (cclass = 0; cclass < CharClass.ClassList.Length; cclass++)
                    {
                        kvp.Value.ClassAvailability[cclass] = Limits.LEVEL_LESSER_GOD;
                    }
                }
                foreach (KeyValuePair <String, Spell> kvp in Spell.SpellList)
                {
                    for (cclass = 0; cclass < CharClass.ClassList.Length; cclass++)
                    {
                        kvp.Value.SpellCircle[cclass] = Limits.MAX_CIRCLE + 3;
                    }
                }
            }

            Log.Trace("Loading classes.");
            CharClass.LoadClasses(true);
            Log.Trace("Loaded " + CharClass.Count + " classes.");

            Log.Trace("Assigning spell circles.");
            AssignSpellCircles();
            Log.Trace("Assigned spell circles.");

            Log.Trace("Loading socials.");
            SocialList = Socials.Load();
            Log.Trace("Loaded " + Social.Count + " socials.");

            Log.Trace("Loading bans.");
            LoadBans();
            Log.Trace("Loaded " + BanList.Count + " bans.");

            Log.Trace("Loading help entries.");
            HelpList = Help.Load(FileLocation.SystemDirectory + FileLocation.HelpFile);
            Log.Trace("Loaded " + Help.Count + " help entries.");

            Log.Trace("Loading screens.");
            Screen.Load(FileLocation.SystemDirectory + FileLocation.ScreenFile, FileLocation.BlankSystemFileDirectory + FileLocation.ScreenFile);
            Log.Trace("Loaded " + Screen.Count + " screens.");

            // Chatbots have to be loaded before mobs.
            Log.Trace("Loading chatbots.");
            ChatterBot.Load();
            Log.Trace("Loaded " + ChatterBot.Count + " chatbots.");

            // Read in all the area files.
            Log.Trace("Reading in area files...");
            LoadAreaFiles();
            Log.Trace("Loaded " + Area.Count + " areas.");

            string buf = String.Format("Loaded {0} mobs, {1} objects, {2} rooms, {3} shops, {4} helps, {5} resets, and {6} quests.",
                                       MobTemplate.Count, ObjTemplate.Count, Room.Count, Shop.Count, Help.Count, Reset.Count, QuestData.Count);

            Log.Trace(buf);

            Log.Trace("Loading guilds.");
            Guild.LoadGuilds();
            Log.Trace("Loaded " + Guild.Count + " guilds.");

            Log.Trace("Loading corpses.");
            CorpseList = CorpseData.Load();
            Log.Trace("Loaded " + CorpseData.Count + " corpses.");

            Log.Trace("Loading crimes.");
            Crime.Load();
            Log.Trace("Loaded " + Crime.Count + " crimes.");

            Log.Trace("Loading fraglist.");
            FraglistData.Fraglist.Load();

            Log.Trace("Loading issues.");
            Issue.Load();
            Log.Trace("Loaded " + Issue.Count + " issues.");

            Log.Trace("Loading bounties.");
            Bounty.Load();
            Log.Trace("Loaded " + Bounty.Count + " bounties.");

            Log.Trace("Initializing movement parameters.");
            Movement.Initialize();
            Log.Trace("Movement parameters initialized.");

            // Only compile spells that have attached code.  Otherwise use default handlers.
            Log.Trace("Compiling spells.");
            int good = 0;
            int bad  = 0;

            foreach (KeyValuePair <String, Spell> kvp in Spell.SpellList)
            {
                if (!String.IsNullOrEmpty(kvp.Value.Code))
                {
                    if (!SpellFunction.CompileSpell(kvp.Value))
                    {
                        ++bad;
                    }
                    else
                    {
                        ++good;
                    }
                }
            }
            Log.Trace("Done compiling spells. " + good + " were successful, " + bad + " failed.");

            // Links up exits and makes rooms runtime-ready so we can access them.
            Log.Trace("Linking exits.");
            LinkExits();

            // This has to be after LinkExits().
            Log.Trace("Loading zone connections.");
            ZoneConnectionList = ZoneConnection.Load();
            // Link zones together based on file.
            foreach (ZoneConnection connection in ZoneConnectionList)
            {
                RoomTemplate   room1     = Room.GetRoom(connection.FirstRoomNumber);
                RoomTemplate   room2     = Room.GetRoom(connection.SecondRoomNumber);
                Exit.Direction direction = connection.FirstToSecondDirection;
                if (room1 != null && room2 != null && direction != Exit.Direction.invalid)
                {
                    Exit exit = new Exit();
                    exit.TargetRoom  = room2;
                    exit.IndexNumber = connection.SecondRoomNumber;
                    room1.ExitData[(int)direction] = exit;
                    exit             = new Exit();
                    exit.TargetRoom  = room1;
                    exit.IndexNumber = connection.FirstRoomNumber;
                    room2.ExitData[(int)Exit.ReverseDirection(direction)] = exit;
                    Log.Trace("Connected " + room1.Area.Name + " to " + room2.Area.Name + " at " + room1.IndexNumber);
                }
                else
                {
                    Log.Error("Unable to connect room " + connection.FirstRoomNumber + " to " + connection.SecondRoomNumber + " in direction " + connection.FirstToSecondDirection);
                }
            }
            Log.Trace("Loaded " + ZoneConnectionList.Count + " zone connections.");


            DatabaseIsBooting = false;
            Log.Trace("Resetting areas.");
            AreaUpdate();

            Log.Trace("Creating events.");
            Event.CreateEvent(Event.EventType.save_corpses, Event.TICK_SAVE_CORPSES, null, null, null);
            Event.CreateEvent(Event.EventType.save_sysdata, Event.TICK_SAVE_SYSDATA, null, null, null);
            Event.CreateEvent(Event.EventType.violence_update, Event.TICK_COMBAT_UPDATE, null, null, null);
            Event.CreateEvent(Event.EventType.area_update, Event.TICK_AREA, null, null, null);
            Event.CreateEvent(Event.EventType.room_update, Event.TICK_ROOM, null, null, null);
            Event.CreateEvent(Event.EventType.object_special, Event.TICK_OBJECT, null, null, null);
            Event.CreateEvent(Event.EventType.mobile_update, Event.TICK_MOBILE, null, null, null);
            Event.CreateEvent(Event.EventType.weather_update, Event.TICK_WEATHER, null, null, null);
            Event.CreateEvent(Event.EventType.char_update, Event.TICK_CHAR_UPDATE, null, null, null);
            Event.CreateEvent(Event.EventType.object_update, Event.TICK_OBJ_UPDATE, null, null, null);
            Event.CreateEvent(Event.EventType.aggression_update, Event.TICK_AGGRESS, null, null, null);
            Event.CreateEvent(Event.EventType.memorize_update, Event.TICK_MEMORIZE, null, null, null);
            Event.CreateEvent(Event.EventType.hit_gain, Event.TICK_HITGAIN, null, null, null);
            Event.CreateEvent(Event.EventType.mana_gain, Event.TICK_MANAGAIN, null, null, null);
            Event.CreateEvent(Event.EventType.move_gain, Event.TICK_MOVEGAIN, null, null, null);
            Event.CreateEvent(Event.EventType.heartbeat, Event.TICK_WEATHER, null, null, null);

            return;
        }
Пример #13
0
        /// <summary>
        /// Links all room exits to the the appropriate _targetType room data.  Reports any problems with
        /// nonexistant rooms or one-way exits.  This must be done once and only once after all rooms are
        /// loaded.
        /// </summary>
        static void LinkExits()
        {
            Exit exit;
            Exit reverseExit;
            Room toRoom;
            int  door;

            // First we have to convert into runtime rooms.
            foreach (Area area in AreaList)
            {
                for (int i = 0; i < area.Rooms.Count; i++)
                {
                    area.Rooms[i] = new Room(area.Rooms[i]);
                }
            }

            foreach (Area area in AreaList)
            {
                foreach (Room room in area.Rooms)
                {
                    // Set exit data.
                    for (door = 0; door < Limits.MAX_DIRECTION; door++)
                    {
                        exit = room.ExitData[door];
                        if (exit != null)
                        {
                            if (exit.IndexNumber <= 0)
                            {
                                exit.TargetRoom = null;
                            }
                            else
                            {
                                exit.TargetRoom = Room.GetRoom(exit.IndexNumber);
                                if (exit.TargetRoom == null)
                                {
                                    string buf = String.Format("Room {0} in zone {1} has an exit in direction {2} to room {3}.  Room {3} was not found.",
                                                               room.IndexNumber, SocketConnection.RemoveANSICodes(room.Area.Name),
                                                               door.ToString(), exit.IndexNumber);
                                    Log.Error(buf);
                                    // NOTE: We do not delete the exit data here because most non-linkable exits are due to
                                    // attached zones not loading.  If we delete the exit data, that means that the zone link
                                    // will be irrevocably lost if we re-save the zone.  However, if we leave the exit data
                                    // intact, when the missing zone is re-loaded in a future boot the exit should self-heal.
                                }
                            }
                        }
                    }
                }
            }

            foreach (Area area in AreaList)
            {
                foreach (RoomTemplate room in area.Rooms)
                {
                    for (door = 0; door < Limits.MAX_DIRECTION; door++)
                    {
                        if ((exit = room.ExitData[door]) && (toRoom = Room.GetRoom(exit.IndexNumber)) &&
                            (reverseExit = toRoom.GetExit(Exit.ReverseDirection((Exit.Direction)door))) &&
                            reverseExit.TargetRoom != room)
                        {
                            String buf = String.Format("Database.LinkExits(): Mismatched Exit - Room {0} Exit {1} to Room {2} in zone {3}: Target room's {4} Exit points to Room {5}.",
                                                       room.IndexNumber, door.ToString(), toRoom.IndexNumber,
                                                       SocketConnection.RemoveANSICodes(room.Area.Name), Exit.ReverseDirection((Exit.Direction)door).ToString(),
                                                       (!reverseExit.TargetRoom) ? 0 : reverseExit.TargetRoom.IndexNumber);
                            Log.Info(buf);
                        }
                    }
                }
            }
            return;
        }