/// <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); }
/// <summary> /// Shows text for affects on a room. /// </summary> /// <param name="ch"></param> /// <param name="room"></param> public static void ShowRoomAffects(CharData ch, Room room) { if (room.HasFlag(RoomTemplate.ROOM_EARTHEN_STARSHELL)) { ch.SendText("&+yEarth moves about this room.&n\r\n"); } if (room.HasFlag(RoomTemplate.ROOM_FIERY_STARSHELL)) { ch.SendText("&+rFire burns in the air here.&n\r\n"); } if (room.HasFlag(RoomTemplate.ROOM_AIRY_STARSHELL)) { ch.SendText("&+cAir blows around viciously here.&n\r\n"); } if (room.HasFlag(RoomTemplate.ROOM_WATERY_STARSHELL)) { ch.SendText("&+bWater floats about in this room.&n\r\n"); } if (room.HasFlag(RoomTemplate.ROOM_HYPNOTIC_PATTERN)) { ch.SendText("&+mA &+bbe&+mau&+bt&+mifu&+bl pa&+mtter&+bn floa&+mts her&+be..&n\r\n"); } if (room.HasFlag(RoomTemplate.ROOM_MAGICDARK)) { ch.SendText("It is unnaturally &+Ldark&n here.\r\n"); } if (room.HasFlag(RoomTemplate.ROOM_MAGICLIGHT)) { ch.SendText("It is unnaturally &+Wbright&n here.\r\n"); } }
/// <summary> /// Display the room flags as a string. /// </summary> /// <param name="room"></param> /// <returns></returns> public static string RoomString(Room room) { string text = String.Empty; foreach (BitvectorFlagType bvf in BitvectorFlagType.RoomFlags) { if (room.HasFlag(bvf.BitvectorData)) { text += " "; text += bvf.Name; } } return((!String.IsNullOrEmpty(text)) ? text.Substring(1) : "none"); }
/// <summary> /// Resets a room, reloading according to resets. /// </summary> /// <param name="notInitial"></param> /// <returns></returns> public bool ResetRoom(int notInitial) { Exit exit = null; CharData mobile; CharData lastMob = null; int level = 0; bool last = true; // Added for debugging. string text = String.Empty; foreach (Reset reset in Area.Resets) { if (!reset.IsRoomReset(this)) { continue; } Object obj; Object lastObj; MobTemplate mobIndex; ObjTemplate objTemplate; Room room; switch (reset.Command) { default: Log.Error("RoomIndex.Reset(): bad command %c.", reset.Command); break; case 'M': mobIndex = Database.GetMobTemplate(reset.Arg1); if (!mobIndex) { Log.Error("RoomIndex.Reset(): 'M': bad mob index number {0} for arg1.", reset.Arg1); continue; } room = GetRoom(reset.Arg3); if (!room) { Log.Error("RoomIndex.Reset(): 'R': bad room index number {0} for arg3.", reset.Arg3); continue; } if ((mobIndex.HasSpecFun("spec_cast_ghost")) && (Database.SystemData.WeatherData.Sunlight > SunType.night) && (Database.SystemData.WeatherData.Sunlight < SunType.moonrise)) { last = false; continue; } level = Macros.Range(0, mobIndex.Level - 2, Limits.LEVEL_HERO); if (mobIndex.NumActive >= reset.Arg2) { last = false; break; } mobile = Database.CreateMobile(mobIndex); // Check for pet shop. Room prevRoom = GetRoom(room.IndexNumber - 1); if (prevRoom && prevRoom.HasFlag(ROOM_PET_SHOP)) { mobile.SetActionBit(MobTemplate.ACT_PET); } if (room.IsDark()) { mobile.SetAffectBit(Affect.AFFECT_INFRAVISION); } mobile.AddToRoom(room); mobile.LoadRoomIndexNumber = room.IndexNumber; // This code makes mounts make their mounters mount them. if (reset.Arg0 == -1 && lastMob) { // If set to be mounted. String[] keywords = mobile.Name.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Command.Mount(lastMob, keywords); } lastMob = mobile; level = Macros.Range(0, mobile.Level - 2, Limits.LEVEL_HERO); last = true; break; case 'F': mobIndex = Database.GetMobTemplate(reset.Arg1); if (!mobIndex) { Log.Error("RoomIndex.Reset(): 'F': bad mob index number {0} for arg1.", reset.Arg1); continue; } room = GetRoom(reset.Arg3); if (!room) { Log.Error("RoomIndex.Reset(): 'F': bad room index number {0} for arg3.", reset.Arg3); continue; } if (mobIndex.HasSpecFun("spec_cast_ghost") && (Database.SystemData.WeatherData.Sunlight > SunType.night) && (Database.SystemData.WeatherData.Sunlight < SunType.moonrise)) { last = false; continue; } level = Macros.Range(0, mobIndex.Level - 2, Limits.LEVEL_HERO); if (mobIndex.NumActive >= reset.Arg2) { last = false; break; } mobile = Database.CreateMobile(mobIndex); Room prev = GetRoom(room.IndexNumber - 1); if (prev && prev.HasFlag(ROOM_PET_SHOP)) { mobile.SetActionBit(MobTemplate.ACT_PET); } if (room.IsDark()) { mobile.SetAffectBit(Affect.AFFECT_INFRAVISION); } // Set following bit. Can't have a message sent because // there is no valid room number (causes a segmentation fault) CharData.AddFollowerWithoutMessage(mobile, lastMob); lastMob = mobile; mobile.AddToRoom(room); mobile.LoadRoomIndexNumber = room.IndexNumber; level = Macros.Range(0, mobile.Level - 2, Limits.LEVEL_HERO); last = true; break; case 'O': if (notInitial != 0) { last = false; continue; } objTemplate = Database.GetObjTemplate(reset.Arg1); if (!objTemplate) { Log.Error("RoomIndex.Reset(): 'O': bad obj index number {0} for arg1.", reset.Arg1); continue; } room = GetRoom(reset.Arg3); if (!room) { Log.Error("RoomIndex.Reset(): 'O': bad room index number {0} for arg3.", reset.Arg3); continue; } if (Area.NumPlayers > 0 || room._contents.Count != 0 && (Object.CountObjectInList(objTemplate, room._contents) > 0)) { last = false; break; } // check if is unique/arti if (Database.IsArtifact(objTemplate.IndexNumber)) { text += "RoomIndex.Reset(): Artifact found: " + objTemplate.Name + " (" + objTemplate.IndexNumber + ")"; Log.Trace(text); } //end if artiact obj = Database.CreateObject(objTemplate, MUDMath.FuzzyNumber(level)); if (obj != null) { obj.Cost = 0; obj.AddToRoom(this); last = true; } else { Log.Error("RoomIndex.Reset(): Unable to Database.CreateObject {0}", reset.Arg3); } break; case 'P': if (notInitial != 0) { last = false; continue; } objTemplate = Database.GetObjTemplate(reset.Arg1); if (!objTemplate) { Log.Error("RoomIndex.Reset(): 'P': bad obj index number {0} for arg3.", reset.Arg1); continue; } ObjTemplate targetObjTemplate = Database.GetObjTemplate(reset.Arg3); if (!targetObjTemplate) { Log.Error("RoomIndex.Reset(): 'P': bad obj index number {0} for arg3.", reset.Arg3); continue; } if (Area.NumPlayers > 0 || !(lastObj = Object.GetFirstObjectOfTemplateType(targetObjTemplate)) || lastObj.Contains.Count != 0 && (Object.CountObjectInList(objTemplate, lastObj.Contains) > 0)) { last = false; break; } // check if is unique/arti if (Database.IsArtifact(objTemplate.IndexNumber)) { text += "RoomIndex.Reset(): Artifact found: " + objTemplate.Name + " (" + objTemplate.IndexNumber + ")"; Log.Trace(text); } //end if artifact obj = Database.CreateObject(objTemplate, MUDMath.FuzzyNumber(lastObj.Level)); lastObj.AddToObject(obj); last = true; // Ensure that the container gets Reset. if ((lastObj.ItemType == ObjTemplate.ObjectType.container) || (lastObj.ItemType == ObjTemplate.ObjectType.drink_container)) { lastObj.Values[1] = lastObj.ObjIndexData.Values[1]; } break; case 'G': case 'E': if (notInitial != 0) { last = false; continue; } objTemplate = Database.GetObjTemplate(reset.Arg1); if (!objTemplate) { Log.Error("RoomIndex.Reset(): 'E' or 'G': bad obj index number {0} for arg1.", reset.Arg1); continue; } if (!last) { break; } if (!lastMob) { Log.Error("RoomIndex.Reset(): 'E' or 'G': null mob for index number {0} for arg1.", reset.Arg1); last = false; break; } // check if is unique/arti if (Database.IsArtifact(objTemplate.IndexNumber)) { text += "RoomIndex.Reset(): Artifact found: " + objTemplate.Name + " (" + objTemplate.IndexNumber + ")"; Log.Trace(text); } //end if artifact if (lastMob.MobileTemplate.ShopData) /* Shop-keeper? */ { int olevel; switch (objTemplate.ItemType) { default: olevel = 0; break; case ObjTemplate.ObjectType.pill: olevel = MUDMath.NumberRange(0, 10); break; case ObjTemplate.ObjectType.potion: olevel = MUDMath.NumberRange(0, 10); break; case ObjTemplate.ObjectType.scroll: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.wand: olevel = MUDMath.NumberRange(10, 20); break; case ObjTemplate.ObjectType.staff: olevel = MUDMath.NumberRange(15, 25); break; case ObjTemplate.ObjectType.armor: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.other: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.clothing: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.weapon: if (reset.Command == 'G') { olevel = MUDMath.NumberRange(5, 15); } else { olevel = MUDMath.FuzzyNumber(level); } break; } obj = Database.CreateObject(objTemplate, olevel); if (reset.Command == 'G') { obj.AddFlag(ObjTemplate.ITEM_INVENTORY); } } else { obj = Database.CreateObject(objTemplate, MUDMath.FuzzyNumber(level)); } obj.ObjToChar(lastMob); if (reset.Command == 'E') { lastMob.EquipObject(ref obj, (ObjTemplate.WearLocation)reset.Arg3); } last = true; break; case 'D': if (reset.Arg2 < 0 || reset.Arg2 >= Limits.MAX_DIRECTION || !(exit = ExitData[reset.Arg2]) || !exit.HasFlag(Exit.ExitFlag.is_door)) { Log.Error("RoomIndex.Reset(): 'D': exit {0} not door for arg2.", reset.Arg2); } switch (reset.Arg3) { default: Log.Error("RoomIndex.Reset(): 'D': bad 'locks': {0} for arg3.", reset.Arg3); break; case 0: break; case 1: exit.AddFlag(Exit.ExitFlag.closed); break; case 2: exit.AddFlag(Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; case 4: exit.AddFlag(Exit.ExitFlag.secret); break; case 5: exit.AddFlag(Exit.ExitFlag.secret | Exit.ExitFlag.closed); break; case 6: exit.AddFlag(Exit.ExitFlag.secret | Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; case 8: exit.AddFlag(Exit.ExitFlag.blocked); break; case 9: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.closed); break; case 10: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; case 12: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.secret); break; case 13: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.secret | Exit.ExitFlag.closed); break; case 14: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.secret | Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; } break; case 'R': Log.Trace("Unsupported randomize room exits call. Please implement this."); break; } } return(true); }
/// <summary> /// Scanning function. /// </summary> /// <param name="ch"></param> /// <param name="room"></param> /// <param name="text"></param> /// <param name="distance"></param> /// <param name="dir"></param> /// <returns></returns> public static int ScanRoom( CharData ch, Room room, ref string text, int distance, int dir ) { int numberFound = 0; string distanceMsg; if( dir < 0 || dir >= Limits.MAX_DIRECTION ) { Log.Error( "ScanRoom: direction {0} out of bounds!", dir ); ch.SendText( "Bug while scanning, direction out of bounds!\r\n" ); return 0; } // Not going to find anything in a room that is unscannable - Xangis if (room.HasFlag(RoomTemplate.ROOM_NO_SCAN)) { return 0; } switch( distance ) { case 1: distanceMsg = String.Format( "&n who is close by to the " ); break; case 2: distanceMsg = String.Format( "&n who is not far off to the " ); break; case 3: distanceMsg = String.Format( "&n who is a brief walk away to the " ); break; default: distanceMsg = String.Format( "&n who is an unknown distance to the " ); break; } foreach( CharData target in room.People ) { if( ch.FlightLevel == target.FlightLevel ) { Visibility visibility = Look.HowSee(ch, target); switch( visibility ) { case Visibility.sense_hidden: case Visibility.invisible: case Visibility.too_dark: default: break; case Visibility.visible: text += ( target.ShowNameTo( ch, true )); text += distanceMsg; text += dir.ToString(); text += ".&n\r\n"; numberFound++; break; case Visibility.sense_infravision: text += "&+rYou sense a being within the darkness"; text += distanceMsg; text += dir.ToString(); text += ".&n\r\n"; numberFound++; break; } } } return numberFound; }
/// <summary> /// Display the room flags as a string. /// </summary> /// <param name="room"></param> /// <returns></returns> public static string RoomString(Room room) { string text = String.Empty; foreach(BitvectorFlagType bvf in BitvectorFlagType.RoomFlags) { if (room.HasFlag(bvf.BitvectorData)) { text += " "; text += bvf.Name; } } return (!String.IsNullOrEmpty(text)) ? text.Substring(1) : "none"; }
/// <summary> /// Shows text for affects on a room. /// </summary> /// <param name="ch"></param> /// <param name="room"></param> public static void ShowRoomAffects(CharData ch, Room room) { if (room.HasFlag(RoomTemplate.ROOM_EARTHEN_STARSHELL)) ch.SendText("&+yEarth moves about this room.&n\r\n"); if (room.HasFlag(RoomTemplate.ROOM_FIERY_STARSHELL)) ch.SendText("&+rFire burns in the air here.&n\r\n"); if (room.HasFlag(RoomTemplate.ROOM_AIRY_STARSHELL)) ch.SendText("&+cAir blows around viciously here.&n\r\n"); if (room.HasFlag(RoomTemplate.ROOM_WATERY_STARSHELL)) ch.SendText("&+bWater floats about in this room.&n\r\n"); if (room.HasFlag(RoomTemplate.ROOM_HYPNOTIC_PATTERN)) ch.SendText("&+mA &+bbe&+mau&+bt&+mifu&+bl pa&+mtter&+bn floa&+mts her&+be..&n\r\n"); if (room.HasFlag(RoomTemplate.ROOM_MAGICDARK)) ch.SendText("It is unnaturally &+Ldark&n here.\r\n"); if (room.HasFlag(RoomTemplate.ROOM_MAGICLIGHT)) ch.SendText("It is unnaturally &+Wbright&n here.\r\n"); }
/// <summary> /// Scanning function. /// </summary> /// <param name="ch"></param> /// <param name="room"></param> /// <param name="text"></param> /// <param name="distance"></param> /// <param name="dir"></param> /// <returns></returns> public static int ScanRoom(CharData ch, Room room, ref string text, int distance, int dir) { int numberFound = 0; string distanceMsg; if (dir < 0 || dir >= Limits.MAX_DIRECTION) { Log.Error("ScanRoom: direction {0} out of bounds!", dir); ch.SendText("Bug while scanning, direction out of bounds!\r\n"); return(0); } // Not going to find anything in a room that is unscannable - Xangis if (room.HasFlag(RoomTemplate.ROOM_NO_SCAN)) { return(0); } switch (distance) { case 1: distanceMsg = String.Format("&n who is close by to the "); break; case 2: distanceMsg = String.Format("&n who is not far off to the "); break; case 3: distanceMsg = String.Format("&n who is a brief walk away to the "); break; default: distanceMsg = String.Format("&n who is an unknown distance to the "); break; } foreach (CharData target in room.People) { if (ch.FlightLevel == target.FlightLevel) { Visibility visibility = Look.HowSee(ch, target); switch (visibility) { case Visibility.sense_hidden: case Visibility.invisible: case Visibility.too_dark: default: break; case Visibility.visible: text += (target.ShowNameTo(ch, true)); text += distanceMsg; text += dir.ToString(); text += ".&n\r\n"; numberFound++; break; case Visibility.sense_infravision: text += "&+rYou sense a being within the darkness"; text += distanceMsg; text += dir.ToString(); text += ".&n\r\n"; numberFound++; break; } } } return(numberFound); }