Example #1
0
        public void AddNewRoom(int originalRoom, Exit.Direction direction)
        {
            btnNew_Click(null, null);
            RoomTemplate newRoom = _area.Rooms[(_area.Rooms.Count - 1)];
            RoomTemplate oldRoom = null;

            for (int i = 0; i < _area.Rooms.Count; i++)
            {
                if (_area.Rooms[i].IndexNumber == originalRoom)
                {
                    oldRoom = _area.Rooms[i];
                    break;
                }
            }
            if (oldRoom != null)
            {
                if (oldRoom.ExitData[(int)direction] == null)
                {
                    oldRoom.ExitData[(int)direction] = new Exit();
                }
                oldRoom.ExitData[(int)direction].IndexNumber = newRoom.IndexNumber;
                if (newRoom.ExitData[(int)Exit.ReverseDirection(direction)] == null)
                {
                    newRoom.ExitData[(int)Exit.ReverseDirection(direction)] = new Exit();
                }
                newRoom.ExitData[(int)Exit.ReverseDirection(direction)].IndexNumber = oldRoom.IndexNumber;
            }
        }
Example #2
0
        /// <summary>
        /// Finds an exit based on a keyword.  Use FindDoor if you are looking for a door.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static Exit.Direction FindExit(CharData ch, string arg)
        {
            Exit exit;

            Exit.Direction door = Exit.DoorLookup(arg);
            if (door == Exit.Direction.invalid)
            {
                for (int doornum = 0; doornum < Limits.MAX_DIRECTION; doornum++)
                {
                    if ((exit = ch.InRoom.ExitData[doornum]) && exit.HasFlag(Exit.ExitFlag.is_door) &&
                        !(ch.Level < Limits.LEVEL_AVATAR && exit.ExitFlags != 0 &&
                          (exit.HasFlag(Exit.ExitFlag.secret) || exit.HasFlag(Exit.ExitFlag.blocked))) &&
                        exit.Keyword.Length != 0 && ("door".Equals(arg, StringComparison.CurrentCultureIgnoreCase) ||
                                                     MUDString.NameContainedIn(arg, exit.Keyword)))
                    {
                        return((Exit.Direction)doornum);
                    }
                }
                SocketConnection.Act("I see no $T here.", ch, null, arg, SocketConnection.MessageTarget.character);
                return(Exit.Direction.invalid);
            }

            if (!(exit = ch.InRoom.ExitData[(int)door]))
            {
                SocketConnection.Act("I see no door $T here.", ch, null, arg, SocketConnection.MessageTarget.character);
                return(Exit.Direction.invalid);
            }

            return(door);
        }
Example #3
0
        /// <summary>
        /// Finds a door based on a keyword or direction.  Use FindExit if you only need to get an exit,
        /// no door required.  This should _not_ tell the character anything; it is an internal function.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static Exit.Direction FindDoor(CharData ch, string arg)
        {
            Exit exit;

            Exit.Direction door = Exit.DoorLookup(arg);
            if (door == Exit.Direction.invalid)
            {
                for (int doornum = 0; doornum < Limits.MAX_DIRECTION; doornum++)
                {
                    if ((exit = ch.InRoom.ExitData[doornum]) && exit.HasFlag(Exit.ExitFlag.is_door) &&
                        !(ch.Level < Limits.LEVEL_AVATAR && exit.ExitFlags != 0 &&
                          (exit.HasFlag(Exit.ExitFlag.secret) || exit.HasFlag(Exit.ExitFlag.blocked))) &&
                        exit.Keyword.Length != 0 && ("door".Equals(arg, StringComparison.CurrentCultureIgnoreCase) ||
                                                     MUDString.NameContainedIn(arg, exit.Keyword)))
                    {
                        return((Exit.Direction)doornum);
                    }
                }
                return(Exit.Direction.invalid);
            }

            exit = ch.InRoom.GetExit(door);
            if (!exit)
            {
                return(Exit.Direction.invalid);
            }

            if (!exit.HasFlag(Exit.ExitFlag.is_door))
            {
                return(Exit.Direction.invalid);
            }

            return(door);
        }
Example #4
0
 /// <summary>
 /// Utility function that gets a room's exit for a particular direction.
 /// </summary>
 /// <param name="door"></param>
 /// <returns></returns>
 public Exit GetExit(Exit.Direction door)
 {
     // Exit direction could have been stored somewhere as an invalid value,
     // i.e. as a bad integer on a wall value. Check for it.
     if (!Enum.IsDefined(typeof(Exit.Direction), door))
     {
         return(null);
     }
     return(ExitData[(int)door]);
 }
Example #5
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);
 }
Example #6
0
 /// <summary>
 /// Updates the data in the window.  We pass in a room and a direction
 /// because we may or may not change the data depending on whether we
 /// click OK or Cancel.
 /// </summary>
 /// <param name="room"></param>
 /// <param name="direction"></param>
 public void UpdateWindowContents(RoomTemplate room, Exit.Direction direction)
 {
     _room = room;
     _direction = direction;
     Exit exit = _room.ExitData[(int)direction];
     if (exit != null)
     {
         lblEditStatus.Text = "Editing " + direction.ToString() + " exit in room " + room.IndexNumber.ToString() + ".";
         txtDescription.Text = exit.Description;
         txtFlags.Text = exit.ExitFlags.ToString();
         txtKeyIndexNumber.Text = exit.Key.ToString();
         txtKeyword.Text = exit.Keyword;
         txtIndexNumber.Text = exit.IndexNumber.ToString();
     }
     else
     {
         lblEditStatus.Text = "Creating new " + direction.ToString() + " exit in room " + room.IndexNumber.ToString() + ".";
     }
 }
Example #7
0
        /// <summary>
        /// Updates the data in the window.  We pass in a room and a direction
        /// because we may or may not change the data depending on whether we
        /// click OK or Cancel.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="direction"></param>
        public void UpdateWindowContents(RoomTemplate room, Exit.Direction direction)
        {
            _room      = room;
            _direction = direction;
            Exit exit = _room.ExitData[(int)direction];

            if (exit != null)
            {
                lblEditStatus.Text     = "Editing " + direction.ToString() + " exit in room " + room.IndexNumber.ToString() + ".";
                txtDescription.Text    = exit.Description;
                txtFlags.Text          = exit.ExitFlags.ToString();
                txtKeyIndexNumber.Text = exit.Key.ToString();
                txtKeyword.Text        = exit.Keyword;
                txtIndexNumber.Text    = exit.IndexNumber.ToString();
            }
            else
            {
                lblEditStatus.Text = "Creating new " + direction.ToString() + " exit in room " + room.IndexNumber.ToString() + ".";
            }
        }
Example #8
0
 private void ShowExitDlg(Exit.Direction direction)
 {
     if (roomList.SelectedIndex != -1)
     {
         EditExit exitdlg = new EditExit(_parent, _area);
         exitdlg.UpdateWindowContents(_area.Rooms[roomList.SelectedIndex], direction);
         DialogResult result = exitdlg.ShowDialog();
         if (result == DialogResult.OK)
         {
             Exit exitData = exitdlg.GetExitData();
             _area.Rooms[roomList.SelectedIndex].ExitData[(int)direction] = exitData;
             UpdateExitButtons(_area.Rooms[roomList.SelectedIndex]);
             this._parent.UpdateRoomMap();
         }
     }
     else
     {
         MessageBox.Show("You can't edit exits without first selecting or creating a room.");
     }
 }
Example #9
0
        public static Exit.Direction GolemGuardDirection(CharData ch)
        {
            // TODO: Verify that this works correctly since it was rewritten.

            int index = ch.Name.IndexOf("guild_");

            if (index == -1)
            {
                return(Exit.Direction.invalid);
            }
            string tmp = ch.Name.Substring(index + 6);

            index = tmp.IndexOf("_");
            if (index == -1)
            {
                return(Exit.Direction.invalid);
            }
            tmp = tmp.Substring(0, index);
            Exit.Direction dir = FindExit(ch, tmp);
            return(dir);
        }
Example #10
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;
        }
Example #11
0
        private void btnNewRoom_Click(object sender, EventArgs e)
        {
            int currentRoom = _room.IndexNumber;
            int roomNumber  = _parent.AddNewRoomFromExit();

            this.txtIndexNumber.Text = roomNumber.ToString();
            // Create reverse-direction exit by default.
            Exit.Direction dir = Exit.ReverseDirection(_direction);
            for (int i = 0; i < _area.Rooms.Count; i++)
            {
                if (_area.Rooms[i].IndexNumber == roomNumber)
                {
                    if (_area.Rooms[i].ExitData != null && _area.Rooms[i].ExitData[(int)dir] == null)
                    {
                        Exit exit = new Exit();
                        exit.IndexNumber = currentRoom;
                        _area.Rooms[i].ExitData[(int)dir] = exit;
                    }
                    return;
                }
            }
        }
Example #12
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());
            }
        }
Example #13
0
        public void LoadContent(List <Tuple <int, int, int> > wallProperties, List <Tuple <int, int> > spikePositions, Vector2 startingPosition, Vector2 endingPosition, Tuple <int, int> worldPosition, Exit.Direction dir)
        {
            NUM_CELLS_WIDTH  = (int)Math.Ceiling((double)game.GraphicsDevice.Viewport.Width / (double)CELL_SIZE);
            NUM_CELLS_HEIGHT = (int)Math.Ceiling((double)game.GraphicsDevice.Viewport.Height / (double)CELL_SIZE);
            cells            = new Cell[NUM_CELLS_WIDTH, NUM_CELLS_HEIGHT];

            var cracked_wall_texture = game.Content.Load <Texture2D>("cracked_wall");
            var normal_wall_texture  = game.Content.Load <Texture2D>("wall");
            var spike_texture        = game.Content.Load <Texture2D>("spike");
            var exposedSFX           = game.Content.Load <SoundEffect>("spikeSFX");

            //Change upper to load textures once & pass to initializers

            for (int i = 0; i < wallProperties.Count(); i++)
            {
                Texture2D wall_texture;
                bool      isBombable = false;
                switch (wallProperties[i].Item3)
                {
                case 0:
                    wall_texture = normal_wall_texture;
                    break;

                case 1:
                    wall_texture = cracked_wall_texture;
                    isBombable   = true;
                    break;

                default:
                    wall_texture = normal_wall_texture;
                    break;
                }
                Wall wall = new Wall(game, wall_texture);
                wall.Initialize(new Vector2(wallProperties[i].Item1 * 50,
                                            wallProperties[i].Item2 * 50),
                                isBombable);
                walls.Add(wall);
                collidables.Add(wall);
            }
            for (int i = 0; i < spikePositions.Count(); i++)
            {
                Spike spike = new Spike(game, spike_texture, exposedSFX);
                spike.Initialize(new Vector2(spikePositions[i].Item1 * 50,
                                             spikePositions[i].Item2 * 50));
                spikes.Add(spike);
                collidables.Add(spike);
            }
            this.startingPosition = startingPosition;
            this.endingPosition   = endingPosition;

            for (int j = 0; j < NUM_CELLS_HEIGHT; j++)
            {
                for (int i = 0; i < NUM_CELLS_WIDTH; i++)
                {
                    cells[i, j] = new Cell(this, new BoundingRectangle(i * CELL_SIZE, j * CELL_SIZE, CELL_SIZE, CELL_SIZE));
                }
            }
            Exit exit = new Exit(game);

            exit.Bounds.X      = (int)(endingPosition.X + 49);
            exit.Bounds.Y      = (int)endingPosition.Y;
            exit.Bounds.Height = 50;
            exit.Bounds.Width  = 50;
            exit.direction     = dir;
            exits.Add(exit);
            collidables.Add(exit);
            this.worldPosition = worldPosition;
        }
Example #14
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;
        }