Beispiel #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;
     }
 }
Beispiel #2
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() + ".";
     }
 }
Beispiel #3
0
 public Exit GetExitData()
 {
     if (_delete)
     {
         return null;
     }
     Exit exit = new Exit();
     exit.Description = txtDescription.Text;
     int val;
     Int32.TryParse(txtFlags.Text, out val);
     exit.ExitFlags = (Exit.ExitFlag)val;
     int key;
     Int32.TryParse(txtKeyIndexNumber.Text, out key);
     exit.Key = key;
     exit.Keyword = txtKeyword.Text;
     int indexNumber;
     Int32.TryParse(txtIndexNumber.Text, out indexNumber);
     exit.IndexNumber = indexNumber;
     return exit;
 }
Beispiel #4
0
        /*
        void room_iterate( RoomIndex *rb[], void ( *func ) ( ), void *cdata )
        {
        register int i;

        for ( i = 0; i < WORLD_SIZE; i++ )
        {
        RoomIndex *temp;

        temp = room_find( rb, i );
        if ( temp )
        ( *func ) ( i, temp, cdata );
        }
        }
        */
        /*
        void hash_iterate( HASH_HEADER *ht, void ( *func ) (  ), void *cdata )
        {
        int i;

        for ( i = 0; i < ht.Klistlen; i++ )
        {
        void          *temp;
        register int   Key;

        Key = ht.Keylist[i];
        temp = hash_find( ht, Key );
        ( *func )( Key, temp, cdata );
        if ( ht.Keylist[i] != Key )    // They must have deleted this room
        i--;        // Hit this slot again.
        }
        }
        */
        /// <summary>
        /// Checks whether an exit is valid.
        /// </summary>
        /// <param name="exit"></param>
        /// <returns></returns>
        static int ExitOk( Exit exit )
        {
            if( ( !exit ) || !( exit.TargetRoom ) )
            {
                return 0;
            }

            return 1;
        }
Beispiel #5
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;
        }
Beispiel #6
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;
         }
     }
 }
Beispiel #7
0
 /// <summary>
 /// Generates a zone file.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void generateZoneToolStripMenuItem_Click(object sender, EventArgs e)
 {
     SaveFileDialog dialog = new SaveFileDialog();
     dialog.Filter = "xml files (*.xml)|*.xml";
     if (dialog.ShowDialog() == DialogResult.OK)
     {
         int vnum = Int32.Parse(txtStartVnum.Text);
         Area area = new Area();
         area.AreaFlags[Area.AREA_WORLDMAP.Group] = Area.AREA_WORLDMAP.Vector;
         area.Width = _bitmap.Width;
         area.Height = _bitmap.Height;
         area.Author = txtAuthor.Text;
         area.Builders = txtAuthor.Text;
         area.Name = txtZoneName.Text;
         for (int y = 0; y < _bitmap.Height; y++)
         {
             for (int x = 0; x < _bitmap.Width; x++)
             {
                 Color col = _bitmap.GetPixel(x, y);
                 MiniRoomTemplate temp = GetTemplate(col);
                 RoomTemplate room = new RoomTemplate();
                 room.Title = temp.Title;
                 room.Description = temp.Description;
                 room.TerrainType = temp.Terrain;
                 room.IndexNumber = vnum + x + (y * _bitmap.Width);
                 // Only add exits and add the room to the zone if the room is not impassable.
                 //
                 // TODO: Don't create exits that point to impassable rooms.
                 Color pixel;
                 MiniRoomTemplate target;
                 if (room.TerrainType != TerrainType.underground_impassable || (x == 0 && y == 0))
                 {
                     if (x > 0)
                     {
                         pixel = _bitmap.GetPixel(x-1, y);
                         target = GetTemplate(pixel);
                         if (target.Terrain != TerrainType.underground_impassable)
                         {
                             Exit exit = new Exit();
                             exit.IndexNumber = vnum + x + (y * _bitmap.Width) - 1;
                             room.ExitData[(int)Exit.Direction.west] = exit;
                         }
                     }
                     if (x < (_bitmap.Width - 1))
                     {
                         pixel = _bitmap.GetPixel(x+1, y);
                         target = GetTemplate(pixel);
                         if (target.Terrain != TerrainType.underground_impassable)
                         {
                             Exit exit = new Exit();
                             exit.IndexNumber = vnum + x + (y * _bitmap.Width) + 1;
                             room.ExitData[(int)Exit.Direction.east] = exit;
                         }
                     }
                     if (y > 0)
                     {
                         pixel = _bitmap.GetPixel(x, y-1);
                         target = GetTemplate(pixel);
                         if (target.Terrain != TerrainType.underground_impassable)
                         {
                             Exit exit = new Exit();
                             exit.IndexNumber = vnum + x + ((y - 1) * _bitmap.Width);
                             room.ExitData[(int)Exit.Direction.north] = exit;
                         }
                     }
                     if( y < (_bitmap.Height - 1 ))
                     {
                         pixel = _bitmap.GetPixel(x, y+1);
                         target = GetTemplate(pixel);
                         if (target.Terrain != TerrainType.underground_impassable)
                         {
                             Exit exit = new Exit();
                             exit.IndexNumber = vnum + x + ((y + 1) * _bitmap.Width);
                             room.ExitData[(int)Exit.Direction.south] = exit;
                         }
                     }
                     area.Rooms.Add(room);
                 }
             }
         }
         area.Save(dialog.FileName);
     }
 }
Beispiel #8
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];
 }
Beispiel #9
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." );
     }
 }
Beispiel #10
0
        /// <summary>
        /// Movement function.  Handles all processing related to walking/flying/moving from one room to another.
        /// </summary>
        /// <param name="door"></param>
        public void Move( Exit.Direction door )
        {
            Exit exit;
            Room toRoom;
            Room target;
            Bitvector moved = PC.PLAYER_MOVED;
            string text;
            string text2;
            bool riding = false;
            bool disbelief = false;
            bool illusion = false;

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

            if( InRoom == null )
            {
                Log.Trace( "Null from room in CharData.Move" );
                SendText("There's nowhere for you to move from - you aren't anywhere!");
                return;
            }

            // Prevents infinite move loop in maze zone when group has 2 leaders
            if (HasActionBit(moved))
            {
                return;
            }

            if(IsAffected( Affect.AFFECT_MINOR_PARA ) || IsAffected( Affect.AFFECT_BOUND )
               || IsAffected( Affect.AFFECT_HOLD ) )
            {
                SendText( "You can't move!\r\n" );
                return;
            }

            if (Riding && (Riding.IsAffected(Affect.AFFECT_BOUND) || Riding.IsAffected(Affect.AFFECT_HOLD) ||
                Riding.IsAffected(Affect.AFFECT_MINOR_PARA)))
            {
                SendText( "Your ride can't move.\r\n" );
                return;
            }

            // More likely to go NSEW than any other dirs
            if( IsAffected( Affect.AFFECT_MISDIRECTION ) )
            {
                if (MUDMath.NumberRange(1, 2) == 1)
                {
                    door = (Exit.Direction)MUDMath.NumberRange(0, 3);
                }
                else
                {
                    door = Database.RandomDoor();
                }
            }

            Room inRoom = InRoom;

            RemoveAffect(Affect.AFFECT_HIDE);

            if( !( exit = inRoom.GetExit(door)) || !( toRoom = Room.GetRoom(exit.IndexNumber) )
                || ( toRoom.TerrainType == TerrainType.underground_impassable )
                || ( toRoom.WorldmapTerrainType == ExtendedTerrain.EXT_ZONEMARKER )
                || ( Level < Limits.LEVEL_AVATAR
                && ( exit.HasFlag( Exit.ExitFlag.secret ) || exit.HasFlag(Exit.ExitFlag.blocked))))
            {
                SendText( "Alas, you cannot go that way.\r\n" );
                return;
            }

            if( FlightLevel != 0 && !toRoom.IsFlyable() )
            {
                SendText( "Alas, you cannot fly there.\r\n" );
                return;
            }

            // For trapped objects in the room that trigger on certain actions
            foreach( Object obj in InRoom.Contents )
            {
                if( obj.Trap == null )
                    continue;
                if( obj.Trap.CheckTrigger( Trap.TriggerType.move ) )
                {
                    SetOffTrap( obj );
                    if (CurrentPosition == Position.dead)
                    {
                        return;
                    }
                }
                else if( door != Exit.Direction.invalid )
                {
                    if (obj.Trap.CheckTrigger(Movement.TrapDirectionFlag[(int)door]))
                    {
                        SetOffTrap( obj );
                        if (CurrentPosition == Position.dead)
                        {
                            return;
                        }
                    }
                }
            }

            // Being walled doesen't mean they can't go there, it just means that we
            // need to check for wall functions.
            if (!IsAffected(Affect.AFFECT_CLIMBING) && inRoom.ExitData[(int)door].HasFlag(Exit.ExitFlag.walled))
            {
                foreach( Object wall in InRoom.Contents )
                {
                    if( wall.ItemType != ObjTemplate.ObjectType.wall || wall.Values[ 0 ] != (int)door )
                        continue;
                    if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_WALL_ILLUSION )
                    {
                        illusion = true;
                        // Test for disbelief
                        int dchance = GetCurrInt() / 2 + Level - wall.Values[ 2 ];
                        if( Fighting )
                            dchance /= 2;
                        if( GetRace() == Race.RACE_OGRE || GetRace() == Race.RACE_CENTAUR )
                            dchance /= 4;
                        if( MUDMath.NumberPercent() < dchance )
                        {
                            // Disbelief
                            SocketConnection.Act( "You disbelieve $p&n!", this, wall, null, SocketConnection.MessageTarget.character );
                            disbelief = true;
                        }
                    }

                    if( wall.Values[ 1 ] == 0 && !disbelief )
                    {
                        if( !illusion || CanSeeObj( this, wall ) )
                        {
                            SocketConnection.Act("You bump into $p&n.", this, wall, null, SocketConnection.MessageTarget.character);
                            SocketConnection.Act("$n&n bumps into $p&n.", this, wall, null, SocketConnection.MessageTarget.room);
                            if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_WALL_ICE )
                            {
                                Combat.InflictSpellDamage(this, this, MUDMath.Dice(2, (wall.Values[2] / 2)), "wall of ice", AttackType.DamageType.cold);
                                if (CurrentPosition == Position.dead)
                                    return;
                            }
                            else if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_WALL_FORCE )
                            {
                                CurrentMoves -= MUDMath.Dice( 2, 15 );
                                SendText( "You feel drained of energy!\r\n" );
                                SendText( "The force of the wall knocks you down!\r\n" );
                                CurrentPosition = Position.sitting;
                                WaitState( MUDMath.Dice( 2, 9 ) );
                            }
                        } //end if !illusion
                        else
                        {
                            SendText( "Alas, you cannot go that way.\r\n" );
                        }
                        return;
                    }
                    if( disbelief )
                    {
                        SocketConnection.Act(StringConversion.WallDecayString(StaticObjects.OBJECT_NUMBER_WALL_ILLUSION), this, wall, null, SocketConnection.MessageTarget.all);
                        wall.RemoveFromWorld();
                        inRoom.ExitData[ (int)door ].RemoveFlag( Exit.ExitFlag.walled );
                    }
                    else if( !illusion )
                    {
                        SocketConnection.Act("You just walked through $p&n.", this, wall, null, SocketConnection.MessageTarget.character);
                        SocketConnection.Act("$n&n just walked through $p&n.", this, wall, null, SocketConnection.MessageTarget.room);
                        if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_WALL_FIRE )
                        {
                            Combat.InflictSpellDamage(this, this, MUDMath.Dice(wall.Values[2], 5), "wall of fire", AttackType.DamageType.fire);
                            if (CurrentPosition == Position.dead)
                                return;
                        }
                        else if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_WALL_SPARKS )
                        {
                            Combat.InflictSpellDamage(this, this, MUDMath.Dice(3, wall.Values[2]), "wall of sparks", AttackType.DamageType.fire);
                            if (CurrentPosition == Position.dead)
                                return;
                        }
                        else if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_LIGHTNING_CURTAIN )
                        {
                            Combat.InflictSpellDamage(this, this, MUDMath.Dice(wall.Values[2], 5), "lightning curtain", AttackType.DamageType.electricity);
                            if (CurrentPosition == Position.dead)
                                return;
                        }
                        if( wall.ObjIndexData.IndexNumber == StaticObjects.OBJECT_NUMBER_WALL_MIST )
                        {
                            if (!Magic.SpellSavingThrow(wall.Values[2], this, AttackType.DamageType.poison))
                            {
                                Affect af = new Affect(Affect.AffectType.spell, "poison", wall.Values[2], Affect.Apply.strength, (0 - 2), Affect.AFFECT_POISON);
                                CombineAffect(af);
                                SendText( "&+GYou don't feel very well.&n\r\n" );
                            }
                            Combat.InflictSpellDamage(this, this, MUDMath.Dice(4, wall.Values[2]), "wall of mist", AttackType.DamageType.poison);
                            if (CurrentPosition == Position.dead)
                                return;
                        }
                    }
                }
            }

            if( exit.HasFlag( Exit.ExitFlag.closed ) )
            {
                if( Riding )
                {
                    if( !Riding.IsAffected( Affect.AFFECT_PASS_DOOR )
                            && !HasInnate( Race.RACE_PASSDOOR )
                            && !Riding.IsImmortal() )
                    {
                        SocketConnection.Act("The $d is closed so your mount is unable to pass.", this, null, exit.Keyword, SocketConnection.MessageTarget.character);
                        return;
                    }

                    if( exit.HasFlag( Exit.ExitFlag.passproof )
                            && !Riding.IsImmortal() )
                    {
                        SocketConnection.Act( "Your mount is unable to pass through the $d.  Ouch!",
                             this, null, exit.Keyword, SocketConnection.MessageTarget.character);
                        return;
                    }
                }
                else
                {
                    if( !IsAffected( Affect.AFFECT_PASS_DOOR )
                            && !HasInnate( Race.RACE_PASSDOOR )
                            && !IsImmortal() )
                    {
                        SocketConnection.Act("The $d is closed.", this, null, exit.Keyword, SocketConnection.MessageTarget.character);
                        return;
                    }

                    if (exit.HasFlag(Exit.ExitFlag.passproof)
                            && !IsImmortal() )
                    {
                        SocketConnection.Act( "You are unable to pass through the $d.  Ouch!",
                             this, null, exit.Keyword, SocketConnection.MessageTarget.character);
                        return;
                    }
                }
            }

            if (Riding && Riding.CurrentPosition < Position.standing)
            {
                SendText( "Your ride doesn't want to move right now.\r\n" );
                return;
            }

            if( toRoom.IsPrivate() )
            {
                SendText( "That room is private right now.\r\n" );
                return;
            }

            // Race.RACE_SWIM means you're an aquatic race... and fish can't walk on land.
            if( Riding )
            {
                if( !toRoom.IsWater() && Riding.HasInnate( Race.RACE_SWIM ) )
                {
                    SendText( "Your mount flaps around but can't move!\r\n" );
                    return;
                }
            }
            else
            {
                if( !toRoom.IsWater() && HasInnate( Race.RACE_SWIM ) )
                {
                    SendText( "You flap around but you can't move!\r\n" );
                    return;
                }
            }

            // Allow all mobs to go wherever they want? Not allowing them to would really
            // screw up the track code, but that's probably all screwed up already anyhow.
            if( !IsNPC() )
            {

                if( ( InRoom.IsMidair() && InRoom.FallChance == 0 ) ||
                    ( toRoom.IsMidair() && toRoom.FallChance == 0 ) )
                {
                    if( InRoom.FallChance != 0 )
                    {
                        Event.CheckFall(InRoom, toRoom, this);
                    }
                    if( Riding )
                    {
                        if( !Riding.CanFly() && door != Exit.Direction.down )
                        {
                            SendText( "Your mount can't fly.\r\n" );
                            return;
                        }
                    }
                    else
                    {
                        // Changed to allow going down always in an air sector.
                        if( !CanFly() && door != Exit.Direction.down )
                        {
                            SendText( "You can't fly.\r\n" );
                            return;
                        }
                    }
                }

                // Water terrain code, check for boats and swimming.  Flyers don't need to swim
                if( ( ( Riding && !Riding.CanFly() ) || ( !Riding && !CanFly() ) )
                        && ( toRoom.IsWater() || inRoom.IsWater() ) )
                {
                    bool found = false;

                    if( Riding && !Riding.IsNPC() )
                    {
                        if( ( (PC)Riding ).SkillAptitude[ "swim" ] != 0 )
                        {
                            found = true;
                            Riding.PracticeSkill( "swim" );
                        }
                    }
                    else if( !IsNPC() )
                    {
                        if (((PC)this).SkillAptitude["swim"] != 0)
                        {
                            found = true;
                            PracticeSkill( "swim" );
                        }
                    }

                    // Check for a boat first, uses less effort than swimming.
                    foreach( Object obj in Carrying )
                    {
                        if( obj.ItemType == ObjTemplate.ObjectType.boat )
                        {
                            found = true;
                            break;
                        }
                    }

                    if( Riding != null && ( Riding.HasInnate( Race.RACE_WATERWALK )
                        || Riding.HasInnate( Race.RACE_SWIM ) ) )
                    {
                        found = true;
                    }

                    if( HasInnate( Race.RACE_WATERWALK ) || HasInnate( Race.RACE_SWIM ) )
                    {
                        found = true;
                    }

                    if( !found )
                    {
                        SendText( "You can't go there without a boat.\r\n" );
                        return;
                    }
                }

                if( Riding != null )
                {
                    if( ( inRoom.TerrainType == TerrainType.underwater_has_ground
                            || toRoom.TerrainType == TerrainType.underwater_has_ground )
                            && !Riding.HasInnate( Race.RACE_SWIM )
                            && ( !Riding.IsNPC() && ((PC)this).SkillAptitude["swim"] == 0))
                    {
                        SendText( "Your mount needs to be able to swim better to go there.\r\n" );
                        return;
                    }
                }
                else
                {
                    if( ( inRoom.TerrainType == TerrainType.underwater_has_ground
                            || toRoom.TerrainType == TerrainType.underwater_has_ground )
                            && !HasInnate( Race.RACE_SWIM ) && ((PC)this).SkillAptitude["swim"] == 0)
                    {
                        SendText( "You need to be able to swim better to go there.\r\n" );
                        PracticeSkill( "swim" );
                        return;
                    }
                    else if( (toRoom.TerrainType == TerrainType.ocean || inRoom.TerrainType == TerrainType.ocean ||
                        toRoom.TerrainType == TerrainType.underground_ocean || inRoom.TerrainType == TerrainType.underground_ocean ) &&
                        (!IsImmortal() || !HasActionBit(PC.PLAYER_GODMODE)))
                    {
                        SendText("The ocean is much too turbulent for your swimming ability.\r\n");
                        return;
                    }
                }

                int move;
                // Half of move loss comes from crossing the current terrain and half comes from crossing the destination terrain
                // since they're technically moving from midpoint to midpoint.
                if ((int)inRoom.TerrainType < RoomTemplate.TERRAIN_MAX && (int)toRoom.TerrainType < RoomTemplate.TERRAIN_MAX )
                {
                    move = ( Movement.MovementLoss[ inRoom.TerrainType ] + Movement.MovementLoss[ toRoom.TerrainType ] ) / 2;
                    int swimAbility = Level * 2 + 15;
                    if( !IsNPC() && HasSkill("swim"))
                    {
                        swimAbility = ((PC)this).SkillAptitude["swim"];
                    }
                    if (toRoom.IsWater())
                    {
                        // Movement loss can increase by up to 95% based on swim skill.
                        move += (move * ((Limits.MAX_SKILL_ADEPT - swimAbility)) / 100);
                    }
                    if (InRoom.IsWater())
                    {
                        // Movement loss can increase by up to 95% based on swim skill.
                        move += (move * ((Limits.MAX_SKILL_ADEPT - swimAbility)) / 100);
                    }
                }
                else
                {
                    move = 4;
                }

                // Flying persons lose constant minimum movement.
                if (CanFly() || IsAffected(Affect.AFFECT_LEVITATE))
                {
                    move = 1;
                }

                if ((Riding))
                {
                    if (this != Riding.Rider)
                    {
                        Log.Error(String.Format( "{0} riding {1}, who is not mounted!", Name, Riding.Name ) );
                    }
                    else
                    {
                        riding = true;
                    }
                }

                if( ( CurrentMoves < move ) && ( !IsImmortal() ) )
                {
                    SendText( "You are too tired to move another step.\r\n" );
                    if( ( Rider ) && riding )
                    {
                        Rider.SendText( "Your mount is too tired to carry you there.\r\n" );
                    }
                    return;
                }

                WaitState( 1 );
                CurrentMoves -= move;

                if( ( Rider ) && riding )
                {
                }
            }

            if (!CheckSneak() && !HasActionBit(PC.PLAYER_WIZINVIS) && !IsAffected( Affect.AFFECT_IS_FLEEING ) )
            {
                if( ( ( inRoom.TerrainType == TerrainType.swimmable_water )
                    || ( inRoom.TerrainType == TerrainType.underwater_has_ground ) )
                    && ( ( toRoom.TerrainType == TerrainType.swimmable_water )
                    || ( toRoom.TerrainType == TerrainType.underwater_has_ground ) ) )
                {
                    SocketConnection.Act("$n&n swims $T.", this, null, door.ToString(), SocketConnection.MessageTarget.room);
                }
                else
                {
                    foreach( CharData watchCh in InRoom.People )
                    {
                        if (watchCh == this || watchCh.FlightLevel != FlightLevel)
                            continue;
                        Visibility visibility = Look.HowSee(watchCh, this);
                        switch( visibility )
                        {
                            case Visibility.visible:
                                if( !Riding )
                                {
                                    text2 = String.Format( "{0}&n {1} {2}.\r\n", ShowNameTo( watchCh, true ),
                                            ( FlightLevel != 0 ) ? "flies" :
                                            Race.RaceList[ GetRace() ].WalkMessage, door.ToString() );
                                    watchCh.SendText( text2 );
                                }
                                else
                                {
                                    text2 = String.Format( "{0}&n rides {1}&n {2}.\r\n", ShowNameTo( watchCh, true ),
                                            Riding.ShowNameTo(watchCh, false), door.ToString() );
                                    watchCh.SendText( text2 );
                                }
                                break;
                            case Visibility.sense_infravision:
                                text2 = String.Format( "&+LA &n&+rred shape &+Lleaves {0} in the &+Wd&n&+war&+Lkness.\r\n&n",
                                          door.ToString());
                                watchCh.SendText( text2 );
                                break;
                            case Visibility.invisible:
                                if( Riding )
                                {
                                    if (Look.HowSee(watchCh, Riding) == Visibility.visible)
                                    {
                                        text2 = String.Format( "{0}&n {1} {2}.\r\n",
                                                  Riding.ShowNameTo(watchCh, true),
                                                  ( FlightLevel != 0 ) ? "flies" :
                                      Race.RaceList[ GetRace() ].WalkMessage,
                                                  door.ToString() );
                                        watchCh.SendText( text2 );
                                    }
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
            }

            // Check for guild golems
            if( inRoom.HasFlag( RoomTemplate.ROOM_GUILDROOM ) )
            {
                int chId = 0;
                Guild.Rank chRank = 0;
                // Find a golem
                foreach( CharData roomCharacter in InRoom.People )
                {
                    if( !roomCharacter.IsNPC() && !MUDString.NameContainedIn( "_guildgolem_", roomCharacter.Name ) )
                        continue;
                    int id = Guild.GolemGuildID( roomCharacter );
                    Exit.Direction dir = Movement.GolemGuardDirection( roomCharacter );
                    if( id > 0 && dir > Exit.Direction.invalid )
                    {
                        // We have a golem guarding an exit
                        if (!IsNPC() && ((PC)this).GuildMembership != null)
                        {
                            chId = ((PC)this).GuildMembership.ID;
                            chRank = ((PC)this).GuildRank;
                        }
                        if (dir == door && (id != chId || chRank < Guild.Rank.parole) && CurrentPosition > Position.reclining)
                        {
                            SocketConnection.Act("$N&n roughly shoves you to the floor as you attempt to pass.", this, null, roomCharacter, SocketConnection.MessageTarget.character);
                            SocketConnection.Act("$N&n shoves $n&n to the floor.", this, null, roomCharacter, SocketConnection.MessageTarget.room);
                            CurrentPosition = Position.reclining;
                            return;
                        }
                        if (dir == door && ((PC)this).GuildRank >= Guild.Rank.officer)
                        {
                            SocketConnection.Act("$N&n salutes smartly as you pass.", this, null, roomCharacter, SocketConnection.MessageTarget.character);
                            SocketConnection.Act("$N&n salutes at $n&n.", this, null, roomCharacter, SocketConnection.MessageTarget.room);
                        }
                        else if( dir == door )
                        {
                            SocketConnection.Act("$N&n nods as you pass.", this, null, roomCharacter, SocketConnection.MessageTarget.character);
                            SocketConnection.Act("$N&n nods at $n&n.", this, null, roomCharacter, SocketConnection.MessageTarget.room);
                        }
                    } //end if
                } ///end for
            } // end guild golems

            RemoveFromRoom();
            AddToRoom( toRoom );

            if( IsAffected( Affect.AFFECT_IS_FLEEING ) )
            {
                text = String.Format( "move_char: {0} has fled to room {1}.", Name, InRoom.IndexNumber );
                ImmortalChat.SendImmortalChat( null, ImmortalChat.IMMTALK_SPAM, 0, text );
            }

            if( !CheckSneak() )
            {
                if( Riding )
                {
                    text = String.Format( "$n&n enters from {0}, riding $N&n.", Exit.ReverseDirectionName[ (int)door ] );
                    SocketConnection.Act(text, this, null, Riding, SocketConnection.MessageTarget.room);
                }
                else if( !Rider )
                {
                    // Changed: Don't show invis people entering room.
                    foreach( CharData watchCh in InRoom.People )
                    {
                        Visibility sight;
                        if ((sight = Look.HowSee(watchCh, this)) != 0 && watchCh != this
                                && watchCh.FlightLevel == FlightLevel )
                        {
                            // If visible to char (& not char), show msg.
                            if( sight == Visibility.visible )
                            {
                                // If they can see the person enter clearly..
                                text2 = String.Format( "{0}&n {1} in from {2}.\r\n", ShowNameTo( watchCh, true ),
                                        ( FlightLevel != 0 ) ? "flies" : Race.RaceList[ GetRace() ].WalkMessage,
                                        Exit.ReverseDirectionName[(int)door]);
                                watchCh.SendText( text2 );
                            }
                            else if( sight == Visibility.sense_infravision )
                            {
                                // Otherwise, show a vague message..
                                text2 = String.Format( "&+LA &n&+rred shape &+Lenters from {0}.\r\n&n",
                                          Exit.ReverseDirectionName[(int)door]);
                                watchCh.SendText( text2 );
                            }
                        }
                    }
                }
            }

            /* Because of the addition of the deleted flag, we can do this  */
            if( !IsImmortal() && GetRace() == Race.RACE_VAMPIRE
                    && toRoom.TerrainType == TerrainType.underwater_has_ground )
            {
                SendText( "Arrgh!  Large body of water!\r\n" );
                SocketConnection.Act("$n&n thrashes underwater!", this, null, null, SocketConnection.MessageTarget.room);
                Combat.InflictDamage(this, this, 20, String.Empty, ObjTemplate.WearLocation.none, AttackType.DamageType.drowning);
            }
            else if( !IsImmortal()
                      && ( toRoom.TerrainType == TerrainType.underwater_has_ground
                           && !IsAffected( Affect.AFFECT_BREATHE_UNDERWATER )
                           && !HasInnate( Race.RACE_WATERBREATH ) ) )
            {
                SendText( "You can't breathe!\r\n" );
                SocketConnection.Act("$n&n sputters and chokes!", this, null, null, SocketConnection.MessageTarget.room);
                Combat.InflictDamage(this, this, 2, String.Empty, ObjTemplate.WearLocation.none, AttackType.DamageType.drowning);
            }

            //* Why have mobiles see the room?
            if( Socket != null )
            {
                CommandType.Interpret(this, "look auto");
            }

            SetActionBit(moved );

            // Handle following.
            for( int i = InRoom.People.Count -1; i >= 0; i--)
            {
                CharData followChar = InRoom.People[i];
                if (followChar.Master == this && followChar.CurrentPosition == Position.standing && followChar.Wait == 0
                        && followChar.FlightLevel == FlightLevel && CanSee(followChar, this))
                {
                    SocketConnection.Act("You follow $N&n.", followChar, null, this, SocketConnection.MessageTarget.character);
                    followChar.Move(door);
                }
                else if (followChar == Rider)
                {
                    followChar.Move(door);
                }
            }

            RemoveActionBit(moved);

            // Okay, now that they're in to room, check to see if they've just invaded a
            // hometown
            Crime.CheckInvader(this);

            // Check to see if a person falls out of this room
            if( InRoom.ExitData[ 5 ] && ( target = Room.GetRoom(InRoom.ExitData[ 5 ].IndexNumber) ) )
            {
                if( InRoom.TerrainType == TerrainType.air ||
                        InRoom.TerrainType == TerrainType.plane_of_air ||
                        InRoom.TerrainType == TerrainType.underground_no_ground ||
                        InRoom.FallChance != 0 )
                    Event.CheckFall(InRoom, target, this);
            }

            //    prog_entry_trigger( ch );
            //    prog_greet_trigger( ch );
            return;
        }